commit f281bc64b20c6b58de35fec059802256b0aa26aa Author: 做个有用的人 <819389547@qq.com> Date: Wed Jun 12 14:01:31 2024 +0800 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ca38718 --- /dev/null +++ b/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "{}" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright 2019-2020 Zheng Jie + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..484acf5 --- /dev/null +++ b/README.md @@ -0,0 +1,83 @@ +

EL-ADMIN 后台管理系统

+
+#### 项目简介 +一个基于 Spring Boot 2.1.0 、 Spring Boot Jpa、 JWT、Spring Security、Redis、Vue的前后端分离的后台管理系统 + +**开发文档:** [https://el-admin.vip](https://el-admin.vip) + +**体验地址:** [https://el-admin.xin](https://el-admin.xin) + +**账号密码:** `admin / 123456` + +#### 项目源码 + +| | 后端源码 | 前端源码 | +|--- |--- | --- | +| github | https://github.com/elunez/eladmin | https://github.com/elunez/eladmin-web | +| 码云 | https://gitee.com/elunez/eladmin | https://gitee.com/elunez/eladmin-web | + +#### 主要特性 +- 使用最新技术栈,社区资源丰富。 +- 高效率开发,代码生成器可一键生成前后端代码 +- 支持数据字典,可方便地对一些状态进行管理 +- 支持接口限流,避免恶意请求导致服务层压力过大 +- 支持接口级别的功能权限与数据权限,可自定义操作 +- 自定义权限注解与匿名接口注解,可快速对接口拦截与放行 +- 对一些常用地前端组件封装:表格数据请求、数据字典等 +- 前后端统一异常拦截处理,统一输出异常,避免繁琐的判断 +- 支持在线用户管理与服务器性能监控,支持限制单用户登录 +- 支持运维管理,可方便地对远程服务器的应用进行部署与管理 + +#### 系统功能 +- 用户管理:提供用户的相关配置,新增用户后,默认密码为123456 +- 角色管理:对权限与菜单进行分配,可根据部门设置角色的数据权限 +- 菜单管理:已实现菜单动态路由,后端可配置化,支持多级菜单 +- 部门管理:可配置系统组织架构,树形表格展示 +- 岗位管理:配置各个部门的职位 +- 字典管理:可维护常用一些固定的数据,如:状态,性别等 +- 系统日志:记录用户操作日志与异常日志,方便开发人员定位排错 +- SQL监控:采用druid 监控数据库访问性能,默认用户名admin,密码123456 +- 定时任务:整合Quartz做定时任务,加入任务日志,任务运行情况一目了然 +- 代码生成:高灵活度生成前后端代码,减少大量重复的工作任务 +- 邮件工具:配合富文本,发送html格式的邮件 +- 七牛云存储:可同步七牛云存储的数据到系统,无需登录七牛云直接操作云数据 +- 支付宝支付:整合了支付宝支付并且提供了测试账号,可自行测试 +- 服务监控:监控服务器的负载情况 +- 运维管理:一键部署你的应用 + +#### 项目结构 +项目采用按功能分模块的开发方式,结构如下 + +- `capiltal-common` 为系统的公共模块,各种工具类,公共配置存在该模块 + +- `capiltal-client` 为客户端api模块,也是最终需要打包部署的模块 + +- `capiltal-system` 为系统核心模块也是项目入口模块,也是最终需要打包部署的模块 + +- `capiltal-logging` 为系统的日志模块,其他模块如果需要记录日志需要引入该模块 + +- `capiltal-tools` 为第三方工具模块,包含:图床、邮件、云存储、本地存储、支付宝 + +- `capiltal-generator` 为系统的代码生成模块,代码生成的模板在 system 模块中 + +#### 详细结构 + +``` +- capiltal-common 公共模块 + - annotation 为系统自定义注解 + - aspect 自定义注解的切面 + - base 提供了Entity、DTO基类和mapstruct的通用mapper + - config 自定义权限实现、redis配置、swagger配置、Rsa配置等 + - dao MybatiesPlus Dao + - mapper mybatiesPlus Mapper + - exception 项目统一异常的处理 + - utils 系统通用工具类 +- capiltal-system 系统核心模块(系统启动入口) + - config 配置跨域与静态资源,与数据权限 + - thread 线程池相关 + - modules 系统相关模块(登录授权、系统监控、定时任务、运维管理等) +- capiltal-logging 系统日志模块 +- capiltal-tools 系统第三方工具模块 +- capiltal-generator 系统代码生成模块 +``` + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..313c8bc --- /dev/null +++ b/pom.xml @@ -0,0 +1,321 @@ + + + 4.0.0 + + me.zhengjie + wjcy + pom + 1.0 + + + wjcy-common + wjcy-logging + wjcy-system + wjcy-tools + wjcy-generator + + + EL-ADMIN 后台管理 + http://auauz.net + + + org.springframework.boot + spring-boot-starter-parent + 2.2.10.RELEASE + + + + UTF-8 + UTF-8 + 1.8 + 1.16 + 1.2.70 + 1.1.24 + 2.5.0 + 1.3.1.Final + 2.1.1 + 2.15.0 + 2.0.7 + + + + + + org.springframework.boot + spring-boot-starter-logging + + + * + * + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.springframework.boot + spring-boot-starter-security + + + + + org.springframework.boot + spring-boot-starter-cache + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + org.apache.commons + commons-pool2 + ${commons-pool2.version} + + + org.apache.commons + commons-lang3 + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + org.bgee.log4jdbc-log4j2 + log4jdbc-log4j2-jdbc4.1 + ${log4jdbc.version} + + + + + com.github.xiaoymin + knife4j-spring-boot-starter + ${knife4j.version} + + + + + mysql + mysql-connector-java + runtime + + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + org.lionsoul + ip2region + 1.7.2 + + + + + org.projectlombok + lombok + true + + + + + + + com.alibaba + fastjson + ${fastjson.version} + + + + + org.mapstruct + mapstruct + ${mapstruct.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + provided + + + javax.inject + javax.inject + 1 + + + + + com.github.whvcse + easy-captcha + 1.6.2 + + + + + nl.basjes.parse.useragent + yauaa + 5.23 + + + + + com.baomidou + mybatis-plus-boot-starter + 3.3.2 + + + com.h2database + h2 + runtime + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + + + org.apache.poi + poi + 4.0.1 + + + + + org.apache.poi + poi-ooxml + 4.0.1 + + + + net.sourceforge.jexcelapi + jxl + 2.6.10 + + + + org.redisson + redisson + 3.5.7 + + + + + org.apache.rocketmq + rocketmq-client + 4.4.0 + + + + + com.google.guava + guava + 24.1-jre + + + com.madgag.spongycastle + core + 1.58.0.0 + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + org.springframework.cloud + spring-cloud-starter-openfeign + 2.2.5.RELEASE + + + com.netflix.feign + feign-jackson + 8.18.0 + + + + org.telegram + telegrambots + 5.5.0 + + + + + + + + src/main/java + + **/*.xml + + true + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + + + public + aliyun nexus + http://maven.aliyun.com/nexus/content/groups/public/ + + true + + + + + + + public + aliyun nexus + http://maven.aliyun.com/nexus/content/groups/public/ + + true + + + false + + + + \ No newline at end of file diff --git a/wjcy-common/pom.xml b/wjcy-common/pom.xml new file mode 100644 index 0000000..12e75a5 --- /dev/null +++ b/wjcy-common/pom.xml @@ -0,0 +1,37 @@ + + + + wjcy + me.zhengjie + 1.0 + + 4.0.0 + + 5.3.4 + + + wjcy-common + 公共模块 + + + + + cn.hutool + hutool-all + ${hutool.version} + + + + org.apache.httpcomponents + httpclient + 4.5.12 + + + org.jodd + jodd-core + 3.7.1 + + + diff --git a/wjcy-common/src/main/java/me/zhengjie/annotation/AnonymousAccess.java b/wjcy-common/src/main/java/me/zhengjie/annotation/AnonymousAccess.java new file mode 100644 index 0000000..b2c168f --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/annotation/AnonymousAccess.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.annotation; + +import java.lang.annotation.*; + +/** + * @author jacky + * 用于标记匿名访问方法 + */ +@Inherited +@Documented +@Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface AnonymousAccess { + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/annotation/CheckPwd.java b/wjcy-common/src/main/java/me/zhengjie/annotation/CheckPwd.java new file mode 100644 index 0000000..459425b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/annotation/CheckPwd.java @@ -0,0 +1,25 @@ +package me.zhengjie.annotation; + +import me.zhengjie.utils.CheckPwdValidator; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +/* + * + * @Description 密码校验 + * @Date 2022/3/21 + * @Author zeng + */ +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = CheckPwdValidator.class) +public @interface CheckPwd { + + String message() default "密码格式错误,必须包含大小写字母、数子、英文特殊符号,且长度在16~64之间!"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/annotation/DataPermission.java b/wjcy-common/src/main/java/me/zhengjie/annotation/DataPermission.java new file mode 100644 index 0000000..b73c1a2 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/annotation/DataPermission.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + *

+ * 用于判断是否过滤数据权限 + * 1、如果没有用到 @OneToOne 这种关联关系,只需要填写 fieldName [参考:DeptQueryCriteria.class] + * 2、如果用到了 @OneToOne ,fieldName 和 joinName 都需要填写,拿UserQueryCriteria.class举例: + * 应该是 @DataPermission(joinName = "dept", fieldName = "id") + *

+ * @author Zheng Jie + * @website https://el-admin.vip + * @date 2020-05-07 + **/ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface DataPermission { + + /** + * Entity 中的字段名称 + */ + String fieldName() default ""; + + /** + * Entity 中与部门关联的字段名称 + */ + String joinName() default ""; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/annotation/DateTime.java b/wjcy-common/src/main/java/me/zhengjie/annotation/DateTime.java new file mode 100644 index 0000000..385ddd9 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/annotation/DateTime.java @@ -0,0 +1,31 @@ +package me.zhengjie.annotation; + +import me.zhengjie.utils.DateTimeValidator; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +/** + *

+ * 日期格式效验 + *

+ * + * @Author xx + * @Date 2021/7/27 + **/ +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = DateTimeValidator.class) +public @interface DateTime { + + String message() default "日期格式错误"; + + String format() default "yyyy-MM-dd HH:mm:ss"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/annotation/FormSubmission.java b/wjcy-common/src/main/java/me/zhengjie/annotation/FormSubmission.java new file mode 100644 index 0000000..d3e7f2d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/annotation/FormSubmission.java @@ -0,0 +1,28 @@ +package me.zhengjie.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static me.zhengjie.config.constant.Constants.FORM_SUB_SECOND; + +/** + *

+ * 表单提交 + *

+ * + * @author: rch + * @date: 2022-08-30 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface FormSubmission { + + /** 是否开启防止表单重复提交验证 */ + boolean isOpen() default true; + /** 表单重复提交时间间隔,单位;秒 */ + long second() default FORM_SUB_SECOND; + + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/annotation/Limit.java b/wjcy-common/src/main/java/me/zhengjie/annotation/Limit.java new file mode 100644 index 0000000..58b41cf --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/annotation/Limit.java @@ -0,0 +1,49 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.annotation; + +import me.zhengjie.aspect.LimitType; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author jacky + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Limit { + + // 资源名称,用于描述接口功能 + String name() default ""; + + // 资源 key + String key() default ""; + + // key prefix + String prefix() default ""; + + // 时间的,单位秒 + int period(); + + // 限制访问次数 + int count(); + + // 限制类型 + LimitType limitType() default LimitType.CUSTOMER; + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/annotation/Query.java b/wjcy-common/src/main/java/me/zhengjie/annotation/Query.java new file mode 100644 index 0000000..e1758c9 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/annotation/Query.java @@ -0,0 +1,90 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author Zheng Jie + * @date 2019-6-4 13:52:30 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Query { + + // Dong ZhaoYang 2017/8/7 基本对象的属性名 + String propName() default ""; + // Dong ZhaoYang 2017/8/7 查询方式 + Type type() default Type.EQUAL; + + /** + * 连接查询的属性名,如User类中的dept + */ + String joinName() default ""; + + /** + * 默认左连接 + */ + Join join() default Join.LEFT; + + /** + * 多字段模糊搜索,仅支持String类型字段,多个用逗号隔开, 如@Query(blurry = "email,username") + */ + String blurry() default ""; + + enum Type { + // jie 2019/6/4 相等 + EQUAL + // Dong ZhaoYang 2017/8/7 大于等于 + , GREATER_THAN + // Dong ZhaoYang 2017/8/7 小于等于 + , LESS_THAN + // Dong ZhaoYang 2017/8/7 中模糊查询 + , INNER_LIKE + // Dong ZhaoYang 2017/8/7 左模糊查询 + , LEFT_LIKE + // Dong ZhaoYang 2017/8/7 右模糊查询 + , RIGHT_LIKE + // Dong ZhaoYang 2017/8/7 小于 + , LESS_THAN_NQ + // jie 2019/6/4 包含 + , IN + // 不包含 + , NOT_IN + // 不等于 + ,NOT_EQUAL + // between + ,BETWEEN + // 不为空 + ,NOT_NULL + // 为空 + ,IS_NULL + } + + /** + * @author Zheng Jie + * 适用于简单连接查询,复杂的请自定义该注解,或者使用sql查询 + */ + enum Join { + /** jie 2019-6-4 13:18:30 */ + LEFT, RIGHT, INNER + } + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousDeleteMapping.java b/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousDeleteMapping.java new file mode 100644 index 0000000..6a81c2e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousDeleteMapping.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.zhengjie.annotation.rest; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import me.zhengjie.annotation.AnonymousAccess; +import org.springframework.core.annotation.AliasFor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * Annotation for mapping HTTP {@code DELETE} requests onto specific handler + * methods. + * 支持匿名访问 DeleteMapping + * + * @author liaojinlong + * @see AnonymousGetMapping + * @see AnonymousPostMapping + * @see AnonymousPutMapping + * @see AnonymousPatchMapping + * @see RequestMapping + */ +@AnonymousAccess +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@RequestMapping(method = RequestMethod.DELETE) +public @interface AnonymousDeleteMapping { + + /** + * Alias for {@link RequestMapping#name}. + */ + @AliasFor(annotation = RequestMapping.class) + String name() default ""; + + /** + * Alias for {@link RequestMapping#value}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] value() default {}; + + /** + * Alias for {@link RequestMapping#path}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] path() default {}; + + /** + * Alias for {@link RequestMapping#params}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] params() default {}; + + /** + * Alias for {@link RequestMapping#headers}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] headers() default {}; + + /** + * Alias for {@link RequestMapping#consumes}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] consumes() default {}; + + /** + * Alias for {@link RequestMapping#produces}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] produces() default {}; + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousGetMapping.java b/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousGetMapping.java new file mode 100644 index 0000000..c260a71 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousGetMapping.java @@ -0,0 +1,90 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.zhengjie.annotation.rest; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import me.zhengjie.annotation.AnonymousAccess; +import org.springframework.core.annotation.AliasFor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * Annotation for mapping HTTP {@code GET} requests onto specific handler + * methods. + *

+ * 支持匿名访问 GetMapping + * + * @author liaojinlong + * @see RequestMapping + */ +@AnonymousAccess +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@RequestMapping(method = RequestMethod.GET) +public @interface AnonymousGetMapping { + + /** + * Alias for {@link RequestMapping#name}. + */ + @AliasFor(annotation = RequestMapping.class) + String name() default ""; + + /** + * Alias for {@link RequestMapping#value}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] value() default {}; + + /** + * Alias for {@link RequestMapping#path}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] path() default {}; + + /** + * Alias for {@link RequestMapping#params}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] params() default {}; + + /** + * Alias for {@link RequestMapping#headers}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] headers() default {}; + + /** + * Alias for {@link RequestMapping#consumes}. + * + * @since 4.3.5 + */ + @AliasFor(annotation = RequestMapping.class) + String[] consumes() default {}; + + /** + * Alias for {@link RequestMapping#produces}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] produces() default {}; + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousPatchMapping.java b/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousPatchMapping.java new file mode 100644 index 0000000..6686617 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousPatchMapping.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.zhengjie.annotation.rest; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import me.zhengjie.annotation.AnonymousAccess; +import org.springframework.core.annotation.AliasFor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * Annotation for mapping HTTP {@code PATCH} requests onto specific handler + * methods. + * * 支持匿名访问 PatchMapping + * + * @author liaojinlong + * @see AnonymousGetMapping + * @see AnonymousPostMapping + * @see AnonymousPutMapping + * @see AnonymousDeleteMapping + * @see RequestMapping + */ +@AnonymousAccess +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@RequestMapping(method = RequestMethod.PATCH) +public @interface AnonymousPatchMapping { + + /** + * Alias for {@link RequestMapping#name}. + */ + @AliasFor(annotation = RequestMapping.class) + String name() default ""; + + /** + * Alias for {@link RequestMapping#value}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] value() default {}; + + /** + * Alias for {@link RequestMapping#path}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] path() default {}; + + /** + * Alias for {@link RequestMapping#params}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] params() default {}; + + /** + * Alias for {@link RequestMapping#headers}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] headers() default {}; + + /** + * Alias for {@link RequestMapping#consumes}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] consumes() default {}; + + /** + * Alias for {@link RequestMapping#produces}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] produces() default {}; + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousPostMapping.java b/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousPostMapping.java new file mode 100644 index 0000000..8f1cdcd --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousPostMapping.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.zhengjie.annotation.rest; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import me.zhengjie.annotation.AnonymousAccess; +import org.springframework.core.annotation.AliasFor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * Annotation for mapping HTTP {@code POST} requests onto specific handler + * methods. + * 支持匿名访问 PostMapping + * + * @author liaojinlong + * @see AnonymousGetMapping + * @see AnonymousPostMapping + * @see AnonymousPutMapping + * @see AnonymousDeleteMapping + * @see RequestMapping + */ +@AnonymousAccess +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@RequestMapping(method = RequestMethod.POST) +public @interface AnonymousPostMapping { + + /** + * Alias for {@link RequestMapping#name}. + */ + @AliasFor(annotation = RequestMapping.class) + String name() default ""; + + /** + * Alias for {@link RequestMapping#value}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] value() default {}; + + /** + * Alias for {@link RequestMapping#path}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] path() default {}; + + /** + * Alias for {@link RequestMapping#params}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] params() default {}; + + /** + * Alias for {@link RequestMapping#headers}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] headers() default {}; + + /** + * Alias for {@link RequestMapping#consumes}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] consumes() default {}; + + /** + * Alias for {@link RequestMapping#produces}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] produces() default {}; + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousPutMapping.java b/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousPutMapping.java new file mode 100644 index 0000000..7c417da --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/annotation/rest/AnonymousPutMapping.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.zhengjie.annotation.rest; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import me.zhengjie.annotation.AnonymousAccess; +import org.springframework.core.annotation.AliasFor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * Annotation for mapping HTTP {@code PUT} requests onto specific handler + * methods. + * * 支持匿名访问 PutMapping + * + * @author liaojinlong + * @see AnonymousGetMapping + * @see AnonymousPostMapping + * @see AnonymousPutMapping + * @see AnonymousDeleteMapping + * @see RequestMapping + */ +@AnonymousAccess +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@RequestMapping(method = RequestMethod.PUT) +public @interface AnonymousPutMapping { + + /** + * Alias for {@link RequestMapping#name}. + */ + @AliasFor(annotation = RequestMapping.class) + String name() default ""; + + /** + * Alias for {@link RequestMapping#value}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] value() default {}; + + /** + * Alias for {@link RequestMapping#path}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] path() default {}; + + /** + * Alias for {@link RequestMapping#params}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] params() default {}; + + /** + * Alias for {@link RequestMapping#headers}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] headers() default {}; + + /** + * Alias for {@link RequestMapping#consumes}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] consumes() default {}; + + /** + * Alias for {@link RequestMapping#produces}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] produces() default {}; + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/aspect/LimitAspect.java b/wjcy-common/src/main/java/me/zhengjie/aspect/LimitAspect.java new file mode 100644 index 0000000..908e022 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/aspect/LimitAspect.java @@ -0,0 +1,99 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.aspect; + +import com.google.common.collect.ImmutableList; +import me.zhengjie.annotation.Limit; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.utils.RequestHolder; +import me.zhengjie.utils.StringUtils; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.script.DefaultRedisScript; +import org.springframework.data.redis.core.script.RedisScript; +import org.springframework.stereotype.Component; +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; + +/** + * @author / + */ +@Aspect +@Component +public class LimitAspect { + + private final RedisTemplate redisTemplate; + private static final Logger logger = LoggerFactory.getLogger(LimitAspect.class); + + public LimitAspect(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + @Pointcut("@annotation(me.zhengjie.annotation.Limit)") + public void pointcut() { + } + + @Around("pointcut()") + public Object around(ProceedingJoinPoint joinPoint) throws Throwable { + HttpServletRequest request = RequestHolder.getHttpServletRequest(); + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method signatureMethod = signature.getMethod(); + Limit limit = signatureMethod.getAnnotation(Limit.class); + LimitType limitType = limit.limitType(); + String key = limit.key(); + if (StringUtils.isEmpty(key)) { + if (limitType == LimitType.IP) { + key = StringUtils.getIp(request); + } else { + key = signatureMethod.getName(); + } + } + + ImmutableList keys = ImmutableList.of(StringUtils.join(limit.prefix(), "_", key, "_", request.getRequestURI().replaceAll("/","_"))); + + String luaScript = buildLuaScript(); + RedisScript redisScript = new DefaultRedisScript<>(luaScript, Number.class); + Number count = redisTemplate.execute(redisScript, keys, limit.count(), limit.period()); + if (null != count && count.intValue() <= limit.count()) { + logger.info("第{}次访问key为 {},描述为 [{}] 的接口", count, keys, limit.name()); + return joinPoint.proceed(); + } else { + throw new BadRequestException("访问次数受限制"); + } + } + + /** + * 限流脚本 + */ + private String buildLuaScript() { + return "local c" + + "\nc = redis.call('get',KEYS[1])" + + "\nif c and tonumber(c) > tonumber(ARGV[1]) then" + + "\nreturn c;" + + "\nend" + + "\nc = redis.call('incr',KEYS[1])" + + "\nif tonumber(c) == 1 then" + + "\nredis.call('expire',KEYS[1],ARGV[2])" + + "\nend" + + "\nreturn c;"; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/aspect/LimitType.java b/wjcy-common/src/main/java/me/zhengjie/aspect/LimitType.java new file mode 100644 index 0000000..bf3f09e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/aspect/LimitType.java @@ -0,0 +1,27 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.aspect; + +/** + * 限流枚举 + * @author / + */ +public enum LimitType { + // 默认 + CUSTOMER, + // by ip addr + IP +} diff --git a/wjcy-common/src/main/java/me/zhengjie/base/BaseDTO.java b/wjcy-common/src/main/java/me/zhengjie/base/BaseDTO.java new file mode 100644 index 0000000..e9e7cc2 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/base/BaseDTO.java @@ -0,0 +1,40 @@ +package me.zhengjie.base; + +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.builder.ToStringBuilder; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.sql.Timestamp; + +/** + * @author Zheng Jie + * @date 2019年10月24日20:48:53 + */ +@Getter +@Setter +public class BaseDTO implements Serializable { + + private String createBy; + + private String updateBy; + + private Timestamp createTime; + + private Timestamp updateTime; + + @Override + public String toString() { + ToStringBuilder builder = new ToStringBuilder(this); + Field[] fields = this.getClass().getDeclaredFields(); + try { + for (Field f : fields) { + f.setAccessible(true); + builder.append(f.getName(), f.get(this)).append("\n"); + } + } catch (Exception e) { + builder.append("toString builder encounter an error"); + } + return builder.toString(); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/base/BaseEntity.java b/wjcy-common/src/main/java/me/zhengjie/base/BaseEntity.java new file mode 100644 index 0000000..618e100 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/base/BaseEntity.java @@ -0,0 +1,85 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.base; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.annotations.UpdateTimestamp; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import javax.persistence.Column; +import javax.persistence.EntityListeners; +import javax.persistence.MappedSuperclass; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.sql.Timestamp; + +/** + * 通用字段, is_del 根据需求自行添加 + * @author Zheng Jie + * @Date 2019年10月24日20:46:32 + */ +@Getter +@Setter +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) +public class BaseEntity implements Serializable { + + @CreatedBy + @Column(name = "create_by", updatable = false) + @ApiModelProperty(value = "创建人", hidden = true) + private String createBy; + + @LastModifiedBy + @Column(name = "update_by") + @ApiModelProperty(value = "更新人", hidden = true) + private String updateBy; + + @CreationTimestamp + @Column(name = "create_time", updatable = false) + @ApiModelProperty(value = "创建时间", hidden = true) + private Timestamp createTime; + + @UpdateTimestamp + @Column(name = "update_time") + @ApiModelProperty(value = "更新时间", hidden = true) + private Timestamp updateTime; + + /* 分组校验 */ + public @interface Create {} + + /* 分组校验 */ + public @interface Update {} + + @Override + public String toString() { + ToStringBuilder builder = new ToStringBuilder(this); + Field[] fields = this.getClass().getDeclaredFields(); + try { + for (Field f : fields) { + f.setAccessible(true); + builder.append(f.getName(), f.get(this)).append("\n"); + } + } catch (Exception e) { + builder.append("toString builder encounter an error"); + } + return builder.toString(); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/base/BaseMapper.java b/wjcy-common/src/main/java/me/zhengjie/base/BaseMapper.java new file mode 100644 index 0000000..e8bb825 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/base/BaseMapper.java @@ -0,0 +1,53 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.base; + +import java.util.List; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +public interface BaseMapper { + + /** + * DTO转Entity + * @param dto / + * @return / + */ + E toEntity(D dto); + + /** + * Entity转DTO + * @param entity / + * @return / + */ + D toDto(E entity); + + /** + * DTO集合转Entity集合 + * @param dtoList / + * @return / + */ + List toEntity(List dtoList); + + /** + * Entity集合转DTO集合 + * @param entityList / + * @return / + */ + List toDto(List entityList); +} diff --git a/wjcy-common/src/main/java/me/zhengjie/config/AuditorConfig.java b/wjcy-common/src/main/java/me/zhengjie/config/AuditorConfig.java new file mode 100644 index 0000000..006ef6b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/AuditorConfig.java @@ -0,0 +1,45 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.config; + +import me.zhengjie.utils.SecurityUtils; +import org.springframework.data.domain.AuditorAware; +import org.springframework.stereotype.Component; +import java.util.Optional; + +/** + * @description : 设置审计 + * @author : Dong ZhaoYang + * @date : 2019/10/28 + */ +@Component("auditorAware") +public class AuditorConfig implements AuditorAware { + + /** + * 返回操作员标志信息 + * + * @return / + */ + @Override + public Optional getCurrentAuditor() { + try { + // 这里应根据实际业务情况获取具体信息 + return Optional.of(SecurityUtils.getCurrentUsername()); + }catch (Exception ignored){} + // 用户定时任务,或者无Token调用的情况 + return Optional.of("System"); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/config/BeanFactory.java b/wjcy-common/src/main/java/me/zhengjie/config/BeanFactory.java new file mode 100644 index 0000000..a293074 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/BeanFactory.java @@ -0,0 +1,105 @@ +package me.zhengjie.config; + + +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +/** + *

+ * bean 工厂, 通过spring容器获取容器中定义的bean + *

+ * + * @Author xx + * @Date 2021/7/22 + **/ +@Configuration +public class BeanFactory implements ApplicationContextAware +{ + /** + * Spring应用上下文环境 + */ + private static ApplicationContext context; + + /** + * 实现ApplicationContextAware接口的回调方法,设置上下文环境 + * + * @param applicationContext + */ + @Override + public void setApplicationContext(ApplicationContext applicationContext) + { + context = applicationContext; + } + + /** + * @return ApplicationContext + */ + final public static ApplicationContext getApplicationContext() + { + return context; + } + + public static Object getBean(String name) + { + return context.getBean(name); + } + + public static T getBean(String name, Class requiredType) + { + return context.getBean(name, requiredType); + } + + public static T getBean(Class requiredType) + { + return context.getBean(requiredType); + } + + public static Object getBean(String name, Object... args) + { + return context.getBean(name, args); + } + + public static Map getBeansOfType(Class type) + { + return context.getBeansOfType(type); + } + + public static List getBeans(Class type) + { + Collection beans = context.getBeansOfType(type).values(); + + @SuppressWarnings("unchecked") + List result = (List) Arrays.asList(beans.toArray()); + + return result; + } + + public static boolean containsBean(String name) + { + return context.containsBean(name); + } + + final public static ApplicationContext loadContext() + { + context = new ClassPathXmlApplicationContext("spring_mysql.xml"); + + return context; + } + + public static void main(String[] args) + { +// Map plugins = getBeansOfType(LoginPlugin.class); +// +// for (Map.Entry element: plugins.entrySet()) +// { +// System.out.println(element.getKey() + ": " + element.getValue()); +// } + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/config/CorsInterceptor.java b/wjcy-common/src/main/java/me/zhengjie/config/CorsInterceptor.java new file mode 100644 index 0000000..dd44563 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/CorsInterceptor.java @@ -0,0 +1,36 @@ +package me.zhengjie.config; + +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +/** + *

+ * + *

+ * + * @Author xx + * @Date 2021/7/19 + **/ +@Component +public class CorsInterceptor implements HandlerInterceptor { + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + response.setHeader("Access-Control-Allow-Origin", "*"); + response.setHeader("Access-Control-Allow-Credentials", "true"); + response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS"); + response.setHeader("Access-Control-Max-Age", "86400"); + response.setHeader("Access-Control-Allow-Headers", "*"); + + // 如果是OPTIONS则结束请求 + if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) { + response.setStatus(HttpStatus.NO_CONTENT.value()); + return false; + } + return true; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/config/CustomIdGenerator.java b/wjcy-common/src/main/java/me/zhengjie/config/CustomIdGenerator.java new file mode 100644 index 0000000..206c77c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/CustomIdGenerator.java @@ -0,0 +1,39 @@ +package me.zhengjie.config; + + +import java.util.concurrent.atomic.AtomicLong; + +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.reflection.SystemMetaObject; +import org.springframework.stereotype.Component; + +import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; + +import lombok.extern.slf4j.Slf4j; + +/** + *

+ * 自定义ID生成器 + *

+ * + * @Author xx + * @Date 2021/7/12 + **/ +@Slf4j +@Component +public class CustomIdGenerator implements IdentifierGenerator { + + private final AtomicLong al = new AtomicLong(1); + + @Override + public Long nextId(Object entity) { + //可以将当前传入的class全类名来作为bizKey,或者提取参数来生成bizKey进行分布式Id调用生成. + String bizKey = entity.getClass().getName(); + log.info("bizKey:{}", bizKey); + MetaObject metaObject = SystemMetaObject.forObject(entity); + String name = (String) metaObject.getValue("name"); + final long id = al.getAndAdd(1); + log.info("为{}生成主键值->:{}", name, id); + return id; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/config/DhApiProperties.java b/wjcy-common/src/main/java/me/zhengjie/config/DhApiProperties.java new file mode 100644 index 0000000..0c086a3 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/DhApiProperties.java @@ -0,0 +1,58 @@ +package me.zhengjie.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +/** + * 敦煌Api Properties + * @author rch + * @date 2022-06-27 + */ +@Component +@Configuration +public class DhApiProperties { + + public static String ACCESS_TOKEN; + public static String BUY_ORDER_URL; + public static String BUY_ORDER_METHOD; + public static String BUY_ORDER_V; + public static String PAY_ORDER_URL; + public static String PAY_ORDER_METHOD; + public static String PAY_ORDER_V; + + @Value("${dh.access_token}") + public void setAccessToken(String accessToken) { + DhApiProperties.ACCESS_TOKEN = accessToken; + } + + @Value("${dh.buy_order_url}") + public void setBuyOrderUrl(String buyOrderUrl) { + DhApiProperties.BUY_ORDER_URL = buyOrderUrl; + } + + @Value("${dh.buy_order_method}") + public void setBuyOrderMethod(String buyOrderMethod) { + DhApiProperties.BUY_ORDER_METHOD = buyOrderMethod; + } + + @Value("${dh.buy_order_v}") + public void setBuyOrderV(String buyOrderV) { + DhApiProperties.BUY_ORDER_V = buyOrderV; + } + + @Value("${dh.pay_order_url}") + public void setPayOrderUrl(String payOrderUrl) { + DhApiProperties.PAY_ORDER_URL = payOrderUrl; + } + + @Value("${dh.pay_order_method}") + public void setPayOrderMethod(String payOrderMethod) { + DhApiProperties.PAY_ORDER_METHOD = payOrderMethod; + } + + @Value("${dh.pay_order_v}") + public void setPayOrderV(String payOrderV) { + DhApiProperties.PAY_ORDER_V = payOrderV; + } +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/config/ElPermissionConfig.java b/wjcy-common/src/main/java/me/zhengjie/config/ElPermissionConfig.java new file mode 100644 index 0000000..9ae1fd5 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/ElPermissionConfig.java @@ -0,0 +1,37 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.config; + +import me.zhengjie.utils.SecurityUtils; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.stereotype.Service; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + */ +@Service(value = "el") +public class ElPermissionConfig { + + public Boolean check(String ...permissions){ + // 获取当前用户的所有权限 + List elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()); + // 判断当前用户的所有权限是否包含接口上定义的权限 + return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/config/FileProperties.java b/wjcy-common/src/main/java/me/zhengjie/config/FileProperties.java new file mode 100644 index 0000000..bf0ebf6 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/FileProperties.java @@ -0,0 +1,60 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.config; + +import lombok.Data; +import me.zhengjie.utils.ElAdminConstant; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * @author Zheng Jie + */ +@Data +@Configuration +@ConfigurationProperties(prefix = "file") +public class FileProperties { + + /** 文件大小限制 */ + private Long maxSize; + + /** 头像大小限制 */ + private Long avatarMaxSize; + + private ElPath mac; + + private ElPath linux; + + private ElPath windows; + + public ElPath getPath(){ + String os = System.getProperty("os.name"); + if(os.toLowerCase().startsWith(ElAdminConstant.WIN)) { + return windows; + } else if(os.toLowerCase().startsWith(ElAdminConstant.MAC)){ + return mac; + } + return linux; + } + + @Data + public static class ElPath{ + + private String path; + + private String avatar; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/config/MvcConfig.java b/wjcy-common/src/main/java/me/zhengjie/config/MvcConfig.java new file mode 100644 index 0000000..8a2da20 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/MvcConfig.java @@ -0,0 +1,31 @@ +package me.zhengjie.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + *

+ * 开放url访问上传到本地的图片 + *

+ * + * @Author xx + * @Date 2021/8/11 + **/ +@Configuration +public class MvcConfig implements WebMvcConfigurer { + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + /* + * 说明:增加虚拟路径(经过本人测试:在此处配置的虚拟路径,用springboot内置的tomcat时有效, + * 用外部的tomcat也有效;所以用到外部的tomcat时不需在tomcat/config下的相应文件配置虚拟路径了,阿里云linux也没问题) + */ + registry.addResourceHandler("/**").addResourceLocations("file:"+SystemConfig.IMG_PATH); + + // 因为doc.html是在jar包里的,需要使用资源处理器注册静态资源。 + registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/config/MyMetaObjectHandler.java b/wjcy-common/src/main/java/me/zhengjie/config/MyMetaObjectHandler.java new file mode 100644 index 0000000..1c9a7a6 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/MyMetaObjectHandler.java @@ -0,0 +1,82 @@ +package me.zhengjie.config; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.utils.DateUtil; +import me.zhengjie.utils.SecurityUtils; +import me.zhengjie.utils.StringUtils; +import me.zhengjie.utils.ValidationUtil; +import org.apache.ibatis.reflection.MetaObject; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + *

+ * MyBatis Plus自动填充插入&更新时间 + *

+ * + * @author: zeng + * @since: 2020-07-15 + */ +@Slf4j +@Component +public class MyMetaObjectHandler implements MetaObjectHandler { + + @Override + public void insertFill(MetaObject metaObject) { + log.info("start insert fill ...."); + Object object = metaObject.getOriginalObject(); + String gmName = getGmName(); + if (ObjectUtil.isNotEmpty(gmName)) { + setValue(object,"gmName",gmName); + } + + if (ValidationUtil.isExistFieldName("createdAt", object)) { + setValue(object, "createdAt", DateUtil.getCurrentTime()); + } + + if (ValidationUtil.isExistFieldName("updatedAt", object)) { + setValue(object, "updatedAt", DateUtil.getCurrentTime()); + } + } + + @SneakyThrows + @Override + public void updateFill(MetaObject metaObject) { + Object object = metaObject.getOriginalObject(); + log.info("start update fill ...."); + String gmName = getGmName(); + if (ObjectUtil.isNotNull(gmName)) { + setValue(object,"gmName",gmName); + } + + if (ValidationUtil.isExistFieldName("updatedAt", object)) { + setValue(object, "updatedAt", DateUtil.getCurrentTime()); + } + } + + private void setValue( Object object, String fieldName, Object value) { + try { + if (ObjectUtil.isNotNull(value)) { + String str = "set" + StringUtils.toUpperCase4Index(fieldName); + Method method = object.getClass().getMethod(str, String.class); + method.invoke(object, value); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + + private String getGmName() { + try { + return SecurityUtils.getCurrentUsername(); + } catch (Exception e) { + return null; + } + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/config/MybatisPlusConfig.java b/wjcy-common/src/main/java/me/zhengjie/config/MybatisPlusConfig.java new file mode 100644 index 0000000..56e1883 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/MybatisPlusConfig.java @@ -0,0 +1,32 @@ +package me.zhengjie.config; + +import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * @author + * @date + */ +@Configuration +@ConditionalOnClass(value = {PaginationInterceptor.class}) +@EnableTransactionManagement +public class MybatisPlusConfig { + @Bean + public PaginationInterceptor paginationInterceptor() { + PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); + return paginationInterceptor; + } + + /** + * 乐观锁 :CAS方案解决 当要更新一条记录的时候,希望这条记录没有被别人更新 + * @return + */ + @Bean + public OptimisticLockerInterceptor optimisticLockerInterceptor() { + return new OptimisticLockerInterceptor(); + } +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/config/PlatsProperties.java b/wjcy-common/src/main/java/me/zhengjie/config/PlatsProperties.java new file mode 100644 index 0000000..64e5da2 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/PlatsProperties.java @@ -0,0 +1,44 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.config; + +import lombok.Data; +import me.zhengjie.utils.ElAdminConstant; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * @author rch + * @date 2022-07-06 + */ +@Data +@Configuration +@ConfigurationProperties(prefix = "plats") +public class PlatsProperties { + + private DhProperties dh; + + + @Data + public static class DhProperties{ + private String buyOrderUrl; + private String buyOrderMethod; + private String buyOrderv; + private String payOrder_url; + private String payOrderMethod; + private String payOrderv; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/config/PropertiesConfig.java b/wjcy-common/src/main/java/me/zhengjie/config/PropertiesConfig.java new file mode 100644 index 0000000..c0f9b9f --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/PropertiesConfig.java @@ -0,0 +1,30 @@ +package me.zhengjie.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; +/** + *

+ * + *

+ * + * @Author xx + * @Date 2021/7/26 + **/ +@Data +@Component +@Configuration +@ConfigurationProperties(prefix = "config") +public class PropertiesConfig { + + private String uploadPrefix; + private Map uploadImgPath; + private List excludeUrlList; + private List sustainImgFormat; + /** 放掉的api 校验token */ + private String apiToken; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/config/RedisConfig.java b/wjcy-common/src/main/java/me/zhengjie/config/RedisConfig.java new file mode 100644 index 0000000..5366b99 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/RedisConfig.java @@ -0,0 +1,223 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.config; + +import cn.hutool.core.lang.Assert; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.utils.StringUtils; +import org.apache.commons.codec.digest.DigestUtils; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.data.redis.RedisProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cache.Cache; +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.interceptor.CacheErrorHandler; +import org.springframework.cache.interceptor.KeyGenerator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.data.redis.serializer.RedisSerializer; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Zheng Jie + * @date 2018-11-24 + */ +@Slf4j +@Configuration +@EnableCaching +@ConditionalOnClass(RedisOperations.class) +@EnableConfigurationProperties(RedisProperties.class) +public class RedisConfig extends CachingConfigurerSupport { + + /** + * 设置 redis 数据默认过期时间,默认2小时 + * 设置@cacheable 序列化方式 + */ + @Bean + public RedisCacheConfiguration redisCacheConfiguration(){ + FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); + RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig(); + configuration = configuration.serializeValuesWith(RedisSerializationContext. + SerializationPair.fromSerializer(fastJsonRedisSerializer)).entryTtl(Duration.ofHours(6)); + return configuration; + } + + @SuppressWarnings("all") + @Bean(name = "redisTemplate") + @ConditionalOnMissingBean(name = "redisTemplate") + public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate template = new RedisTemplate<>(); + //序列化 + FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); + // value值的序列化采用fastJsonRedisSerializer + template.setValueSerializer(fastJsonRedisSerializer); + template.setHashValueSerializer(fastJsonRedisSerializer); + // 全局开启AutoType,这里方便开发,使用全局的方式 + ParserConfig.getGlobalInstance().setAutoTypeSupport(true); + // 建议使用这种方式,小范围指定白名单 + // ParserConfig.getGlobalInstance().addAccept("me.zhengjie.domain"); + // key的序列化采用StringRedisSerializer + template.setKeySerializer(new StringRedisSerializer()); + template.setHashKeySerializer(new StringRedisSerializer()); + template.setConnectionFactory(redisConnectionFactory); + return template; + } + + @Bean + public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) { + StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(); + stringRedisTemplate.setConnectionFactory(redisConnectionFactory); + return stringRedisTemplate; + } + + /** + * 自定义缓存key生成策略,默认将使用该策略 + */ + @Bean + @Override + public KeyGenerator keyGenerator() { + return (target, method, params) -> { + Map container = new HashMap<>(3); + Class targetClassClass = target.getClass(); + // 类地址 + container.put("class",targetClassClass.toGenericString()); + // 方法名称 + container.put("methodName",method.getName()); + // 包名称 + container.put("package",targetClassClass.getPackage()); + // 参数列表 + for (int i = 0; i < params.length; i++) { + container.put(String.valueOf(i),params[i]); + } + // 转为JSON字符串 + String jsonString = JSON.toJSONString(container); + // 做SHA256 Hash计算,得到一个SHA256摘要作为Key + return DigestUtils.sha256Hex(jsonString); + }; + } + + @Bean + @Override + public CacheErrorHandler errorHandler() { + // 异常处理,当Redis发生异常时,打印日志,但是程序正常走 + log.info("初始化 -> [{}]", "Redis CacheErrorHandler"); + return new CacheErrorHandler() { + @Override + public void handleCacheGetError(RuntimeException e, Cache cache, Object key) { + log.error("Redis occur handleCacheGetError:key -> [{}]", key, e); + } + + @Override + public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) { + log.error("Redis occur handleCachePutError:key -> [{}];value -> [{}]", key, value, e); + } + + @Override + public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) { + log.error("Redis occur handleCacheEvictError:key -> [{}]", key, e); + } + + @Override + public void handleCacheClearError(RuntimeException e, Cache cache) { + log.error("Redis occur handleCacheClearError:", e); + } + }; + } + +} + +/** + * Value 序列化 + * + * @author / + * @param + */ + class FastJsonRedisSerializer implements RedisSerializer { + + private final Class clazz; + + FastJsonRedisSerializer(Class clazz) { + super(); + this.clazz = clazz; + } + + @Override + public byte[] serialize(T t) { + if (t == null) { + return new byte[0]; + } + return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(StandardCharsets.UTF_8); + } + + @Override + public T deserialize(byte[] bytes) { + if (bytes == null || bytes.length <= 0) { + return null; + } + String str = new String(bytes, StandardCharsets.UTF_8); + return JSON.parseObject(str, clazz); + } + +} + +/** + * 重写序列化器 + * + * @author / + */ +class StringRedisSerializer implements RedisSerializer { + + private final Charset charset; + + StringRedisSerializer() { + this(StandardCharsets.UTF_8); + } + + private StringRedisSerializer(Charset charset) { + Assert.notNull(charset, "Charset must not be null!"); + this.charset = charset; + } + + @Override + public String deserialize(byte[] bytes) { + return (bytes == null ? null : new String(bytes, charset)); + } + + @Override + public byte[] serialize(Object object) { + String string = JSON.toJSONString(object); + if (StringUtils.isBlank(string)) { + return null; + } + string = string.replace("\"", ""); + return string.getBytes(charset); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/config/RedissonConfig.java b/wjcy-common/src/main/java/me/zhengjie/config/RedissonConfig.java new file mode 100644 index 0000000..192fc03 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/RedissonConfig.java @@ -0,0 +1,48 @@ +package me.zhengjie.config; + +import cn.hutool.core.util.ObjectUtil; +import lombok.Data; +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.config.Config; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +/** + *

+ *redisson 配置类 + *

+ * + * @Author xx + * @Date 2021/8/11 + **/ +@Configuration +@Data +public class RedissonConfig { + @Value("${spring.redis.host}") + private String host; + + @Value("${spring.redis.port}") + private String port; + + @Value("${spring.redis.password}") + private String password; + + @Value("${spring.redis.database}") + private Integer database; + + @Bean + public RedissonClient getRedisson(){ + + Config config = new Config(); + // 若redis为设置密码,将密码设置为null (防止password='' 运行报错) + if (ObjectUtil.isEmpty(password)) { + password = null; + } + config.useSingleServer().setAddress("redis://" + host + ":" + port).setDatabase(database).setPassword(password); + //添加主从配置 +// config.useMasterSlaveServers().setMasterAddress("").setPassword("").addSlaveAddress(new String[]{"",""}); + + return Redisson.create(config); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/config/RsaProperties.java b/wjcy-common/src/main/java/me/zhengjie/config/RsaProperties.java new file mode 100644 index 0000000..a3594cd --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/RsaProperties.java @@ -0,0 +1,38 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.config; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * @author Zheng Jie + * @website https://el-admin.vip + * @description + * @date 2020-05-18 + **/ +@Data +@Component +public class RsaProperties { + + public static String privateKey; + + @Value("${rsa.private_key}") + public void setPrivateKey(String privateKey) { + RsaProperties.privateKey = privateKey; + } +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/config/SwaggerConfig.java b/wjcy-common/src/main/java/me/zhengjie/config/SwaggerConfig.java new file mode 100644 index 0000000..1c354b3 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/SwaggerConfig.java @@ -0,0 +1,217 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.ParameterBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.schema.ModelRef; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.service.Parameter; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc; + +import java.util.ArrayList; +import java.util.List; + +/** + * api页面 /doc.html + * @author Zheng Jie + * @date 2018-11-23 + */ +@Configuration +@EnableSwagger2WebMvc//新版本 +public class SwaggerConfig { + + @Bean(value = "buildBaseDocket") + public Docket buildBaseDocket() { + return new Docket(DocumentationType.SWAGGER_2) + .groupName("基础业务接口") + .apiInfo(buildApiInf()) + .select() + //controller包路径 + .apis(RequestHandlerSelectors.basePackage("me.zhengjie.modules.group.controller.base")) + .paths(PathSelectors.any()) + .build() + .globalOperationParameters(getParmeter()); + } + + @Bean(value = "buildOtherDocket") + public Docket buildOtherDocket() { + return new Docket(DocumentationType.SWAGGER_2) + .groupName("其他业务接口") + .apiInfo(buildApiInf()) + .select() + //controller包路径 + .apis(RequestHandlerSelectors.basePackage("me.zhengjie.modules.capital.controller.base")) + .paths(PathSelectors.any()) + .build() + .globalOperationParameters(getParmeter()); + } + + @Bean(value = "buildCallBackDocket") + public Docket buildCallBackDocket() { + return new Docket(DocumentationType.SWAGGER_2) + .groupName("回调业务接口") + .apiInfo(buildApiInf()) + .select() + //controller包路径 + .apis(RequestHandlerSelectors.basePackage("me.zhengjie.modules.group.controller.callbcak")) + .paths(PathSelectors.any()) + .build() + .globalOperationParameters(getParmeter()); + } + + @Bean(value = "buildSystemDocket") + public Docket buildSystemDocket() { + return new Docket(DocumentationType.SWAGGER_2) + .groupName("系统业务接口") + .apiInfo(buildApiInf()) + .select() + //controller包路径 + .apis(RequestHandlerSelectors.basePackage("me.zhengjie.modules.system.rest")) + .paths(PathSelectors.any()) + .build() + .globalOperationParameters(getParmeter()); + } + + /** + * 描述信息 + */ + private ApiInfo buildApiInf() { + return new ApiInfoBuilder() + // 文档标题 + .title("旺嘉分销管理系统-接口文档") + // 版本信息 + .version("1.0") + // 文档描述 + .description("旺嘉分销管理系统管理文档") + // 版权地址 + .termsOfServiceUrl("http://www.wjcy.com") + // 版权 + .license("旺嘉创亿") + // 联系人信息 + .contact(new Contact("rch", "http://www.baidu.com", "baidu@qq.com")) + .build(); + } + + + public List getParmeter() { + ParameterBuilder tokenPar = new ParameterBuilder(); + List pars = new ArrayList<>(); + tokenPar.name("Authorization").description("令牌").defaultValue("设置token默认值").modelRef(new ModelRef("string")).parameterType("header").required(false).build(); + pars.add(tokenPar.build()); + return pars; + } + + +// @Bean +// @SuppressWarnings("all") +// public Docket createRestApi() { +// return new Docket(DocumentationType.SWAGGER_2) +// .enable(enabled) +// .pathMapping("/") +// .apiInfo(apiInfo()) +// .select() +// .paths(Predicates.not(PathSelectors.regex("/error.*"))) +// .paths(PathSelectors.any()) +// .build() +// //添加登陆认证 +// .securitySchemes(securitySchemes()) +// .securityContexts(securityContexts()); +// } +// +// private ApiInfo apiInfo() { +// return new ApiInfoBuilder() +// .description("一个简单且易上手的 Spring boot 后台管理框架") +// .title("EL-ADMIN 接口文档") +// .version("2.6") +// .build(); +// } +// +// private List securitySchemes() { +// //设置请求头信息 +// List securitySchemes = new ArrayList<>(); +// ApiKey apiKey = new ApiKey(tokenHeader, tokenHeader, "header"); +// securitySchemes.add(apiKey); +// return securitySchemes; +// } +// +// private List securityContexts() { +// //设置需要登录认证的路径 +// List securityContexts = new ArrayList<>(); +// // ^(?!auth).*$ 表示所有包含auth的接口不需要使用securitySchemes即不需要带token +// // ^标识开始 ()里是一子表达式 ?!/auth表示匹配不是/auth的位置,匹配上则添加请求头,注意路径已/开头 .表示任意字符 *表示前面的字符匹配多次 $标识结束 +// securityContexts.add(getContextByPath()); +// return securityContexts; +// } +// +// private SecurityContext getContextByPath() { +// return SecurityContext.builder() +// .securityReferences(defaultAuth()) +// .forPaths(PathSelectors.regex("^(?!/auth).*$")) +// .build(); +// } +// +// private List defaultAuth() { +// List securityReferences = new ArrayList<>(); +// AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); +// AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; +// authorizationScopes[0] = authorizationScope; +// securityReferences.add(new SecurityReference(tokenHeader, authorizationScopes)); +// return securityReferences; +// } +//} +// +///** +// * 将Pageable转换展示在swagger中 +// */ +//@Configuration +//class SwaggerDataConfig { +// +// @Bean +// public AlternateTypeRuleConvention pageableConvention(final TypeResolver resolver) { +// return new AlternateTypeRuleConvention() { +// @Override +// public int getOrder() { +// return Ordered.HIGHEST_PRECEDENCE; +// } +// +// @Override +// public List rules() { +// return newArrayList(newRule(resolver.resolve(Pageable.class), resolver.resolve(Page.class))); +// } +// }; +// } +// +// @ApiModel +// @Data +// private static class Page { +// @ApiModelProperty("页码 (0..N)") +// private Integer page; +// +// @ApiModelProperty("每页显示的数目") +// private Integer size; +// +// @ApiModelProperty("以下列格式排序标准:property[,asc | desc]。 默认排序顺序为升序。 支持多种排序条件:如:id,asc") +// private List sort; +// } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/config/SystemConfig.java b/wjcy-common/src/main/java/me/zhengjie/config/SystemConfig.java new file mode 100644 index 0000000..264554a --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/SystemConfig.java @@ -0,0 +1,97 @@ +package me.zhengjie.config; + + +import cn.hutool.core.lang.Snowflake; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; +/** + *

+ * 系统配置类,从配置文件中注入配置信息 + *

+ * + * @Author xx + * @Date 2021/7/21 + **/ +@Component +@Configuration +public class SystemConfig { + + /** 聊天室默认头像 */ + public static String DEFAULT_MEMBER_HEAD = "/capital/chat/head/default.jpg"; + /** + * 图片存放的绝对路径 + */ + public static String IMG_PATH; + /** + * 静态资源访问路径(返回前端时添加) + */ + public static String FILE_VISIT_ADDR; + /** + * 文件上传接口后缀,用来放行xss过滤 + */ + public static String UPLOAD_SUFFIX; + /** + * 单文件上传大小限制,单位 :MB + */ + public static Integer MAX_FILE_SIZE; + /** + * 视频单文件上传大小限制,单位 :MB + */ + public static Integer VIDEO_MAX_FILE_SIZE; + + /** 多语言文件路径 */ + public static String LANGUAGE_PATH; + + public static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn4jGDcYFGhxNaIKO+oK6ALzHzXupk7+aYa7FYlnS6A/AM9cwgzdksGqfKi7//XDlrqp5jyfecciU7KW7xzs9g+8ZHGy8IEVBqhsOBOjPvi3twc9kdWPhtsRY5X1J2PfRilT/jIMDpBflLf0CrrrPXezKENwRMxlkmSOZqvg0sOwIDAQAB"; + public static final String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKfiMYNxgUaHE1ogo76groAvMfNe6mTv5phrsViWdLoD8Az1zCDN2Swap8qLv/9cOWuqnmPJ95xyJTspbvHOz2D7xkcbLwgRUGqGw4E6M++Le3Bz2R1Y+G2xFjlfUnY99GKVP+MgwOkF+Ut/QKuus9d7MoQ3BEzGWSZI5mq+DSw7AgMBAAECgYEAlnQ7JW5aicdSC4qG1LcRy+T/4filHXJ1+RFCbX7g+ze+MQ8zMg7o2wLEbtvRZFvVRe0xZ4K/+p+9SAj42ZIa/H7ktxhkaxNHVYHVafAuLu2/VFCc7vNPUVu5Fx1xLEg0q2q5TJ2OPlzh9aARh4PW1IetLPBeQSi1qUHVrhPQvskCQQDSxIYv3dpFw9ljqtSriNtIfHSqYAATGtp5SvFfw63fRtvxK6X5Zkdy9ExYe9SOm9u3Q7P4QEKbd4Rbf22Zp2O3AkEAy+mjDGtUP7unrfpuEpe/b+uMPB5+jcmTDDsu3ReZcTzH6BFCqeyR3FBsApLSVWLXuJNKfdKGmH/SwXv2nFUjnQJBAMUE7CKmkbkRYI7oS7ClV8YkgLIa1zcErSEgyw0nz8qdZE/G63l9AGEWuJ8l8gX076gaY4s2Fo1ZZaJaNcuiS3UCQCXFxbpLN3QG4uzLcxBmo8OrsnKAg5joOiEN5YR3FqlvROisKdkoRWy2SQvA/s1qXeOHBUmBcgVVyEinGeujqdECQAeBvDraddWeGuqTEtOXJhQiPxmahUWE2h5htpFdK3+cVt5HiRM89SLM64kHAx7m/RxiGscnhbbXUvSx0H/36R0="; + + /** websocket服务器连接地址 */ + public static String WS_URL; + /** 百度翻译 APPID */ + public static String BAIDU_APPID; + /** 百度翻译privateKey */ + public static String BAIDU_PRIVATEKEY; + /** 百度翻译URL */ + public static final String BAIDU_URL = "https://fanyi-api.baidu.com/api/trans/vip/translate"; + + public static String IP2REGION_DB_PATH; + @Value("${system.imgPath}") + public void setImgPath(String imgPath) { + IMG_PATH = imgPath; + } + + @Value("${system.fileVisitAddr}") + public void setFileVisitAddr(String fileVisitAddr) { + FILE_VISIT_ADDR = fileVisitAddr; + } + @Value("${system.uploadSuffix}") + public void setUploadSuffix(String uploadSuffix) { + UPLOAD_SUFFIX = uploadSuffix; + } + @Value("${system.maxFileSize}") + public void setMaxFileSize(Integer maxFileSize) { + MAX_FILE_SIZE = maxFileSize; + } + + @Value("${system.maxVideoFileSize}") + public void setVideoMaxFileSize(Integer maxVideoFileSize) { + VIDEO_MAX_FILE_SIZE = maxVideoFileSize; + } + + @Value("${system.ip2regionDbPath}") + public void setIp2regionDbPath(String ip2regionDbPath) { + IP2REGION_DB_PATH = ip2regionDbPath; + } + + @Value("${system.languagePath}") + public void setLanguagePath(String languagePath) { + LANGUAGE_PATH = languagePath; + } + + @Bean + public Snowflake snowFlakeInit() { + return new Snowflake(2, 3); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/config/YdApiProperties.java b/wjcy-common/src/main/java/me/zhengjie/config/YdApiProperties.java new file mode 100644 index 0000000..d0eb788 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/YdApiProperties.java @@ -0,0 +1,34 @@ +package me.zhengjie.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +/** + * 影刀Api Properties + * @author rch + * @date 2022-07-27 + */ +@Component +@Configuration +public class YdApiProperties { + + public static String ACCESS_KEY_ID; + public static String ACCESS_KEY_SECRET; + public static String CALLBACK; + + @Value("${yd.accessKeyId}") + public void setAccessKeyId(String accessKeyId) { + ACCESS_KEY_ID = accessKeyId; + } + + @Value("${yd.accessKeySecret}") + public void setAccessKeySecret(String accessKeySecret) { + ACCESS_KEY_SECRET = accessKeySecret; + } + + @Value("${yd.callback}") + public void setCALLBACK(String CALLBACK) { + YdApiProperties.CALLBACK = CALLBACK; + } +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/config/constant/Constants.java b/wjcy-common/src/main/java/me/zhengjie/config/constant/Constants.java new file mode 100644 index 0000000..df0364a --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/config/constant/Constants.java @@ -0,0 +1,30 @@ +package me.zhengjie.config.constant; + +/** + *

+ * 常量实体类 + *

+ * + * @author: rch + * @date: 2021-11-23 + */ +public class Constants { + /** redis token前缀*/ + public static final String TOKEN_PREFIX = "sessions:"; + /** 前端token请求头名称*/ + public static final String TOKEN_HEAD_NAME = "token"; + /** redis 手机验证码前缀*/ + public static final String PHONE_VERIFY_CODE = "phone:"; + /** 表单重复提交时间间隔,单位;秒 */ + public static final long FORM_SUB_SECOND = 1L; + /** 表单重复提交验证的token前缀*/ + public static final String FORM_SUB_TOKEN = "formSubToken:"; + /** 用户默认头像地址 */ + public static final String USER_DEFAULT_HEAD = "/sports/file/userHead/default.jpg"; + + /** 代理后台用户token redis key前缀 */ + public static final String PROXY_ADMIN_TOKEN_PREFIX = "proxy:sessions:"; + + /** 代理后台 访问量统计 "pageviews:"+invite_code*/ + public final static String PAGE_VIEWS_REDIS_PREFIX = "pageviews:"; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/constant/Constants.java b/wjcy-common/src/main/java/me/zhengjie/constant/Constants.java new file mode 100644 index 0000000..7a05f0c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/constant/Constants.java @@ -0,0 +1,16 @@ +package me.zhengjie.constant; + +/** + * 通用常量信息 + * + * @author rch + * @create 2022-08-01 + */ +public class Constants { + public final static String REBOT_STATU = "https://api.winrobot360.com/oapi/dispatch/v2/client/query"; + public final static String GET_SECRET = "https://api.winrobot360.com/oapi/token/v2/token/create"; + public final static String STAT_JOB_URL = "https://api.winrobot360.com/oapi/dispatch/v2/job/start"; + public final static String QUERY_JOB_URL = "https://api.winrobot360.com/oapi/dispatch/v2/job/query"; + + public final static String ERP_AUTH_TOKEN = "ErpAuthToken ddabd37130f86a8ee5f03887552c0b69"; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/constant/PublicConstant.java b/wjcy-common/src/main/java/me/zhengjie/constant/PublicConstant.java new file mode 100644 index 0000000..985b053 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/constant/PublicConstant.java @@ -0,0 +1,56 @@ +package me.zhengjie.constant; + +/** + * + * @Description 通用常量 + * @Date 2022/1/20 + * @Author zeng + */ +public interface PublicConstant { + + /** 缓存失效时间 */ + Integer CACHE_OVER_TIME = 1800; + + /** 设备使用缓存前缀 */ + String REBOT_PREFIX = "rebot:%s"; + + /** 全局系统设置 */ + String SETTING_SITE_PREFIX = "setting_site:%s"; + + /** 更新会员信息 */ + String MEMBER_PROFIT_LOCK_KEY = "member_update_key:%s"; + + String DH_REQUEST_SUCCESS_STATUS_CODE = "00000000"; + + String RESPONSE_SUCCESS = "SUCCESS"; + + Integer EXPORT_EXCEL_FILE_TYPE = 11; + + /** 刷单信息对应执行过的买家信息 */ + String CLICK_FARMING_EXEC_ID_SET = "click_farming_exec:id:%s"; + + /** 执行任务前缀 */ + String JOB_UUID_KEY_PREFIX = "JOB_UUID_KEY:%s"; + + static String getMemberUpdateKeyPrefix(Long memberId) { + return String.format(MEMBER_PROFIT_LOCK_KEY, memberId); + } + + static String getJobUuidKeyPrefix(String jobUuid) { + return String.format(JOB_UUID_KEY_PREFIX, jobUuid); + } + + /** + * 刷单信息对应执行过的买家Id集合拼接 + * @param clickFarmingId + * @return + */ + static String getClickFarmingExecBuyerIdPrefix(Long clickFarmingId) { + return String.format(CLICK_FARMING_EXEC_ID_SET, clickFarmingId); + } + + + static String getRebotKeyPrefix(String accountName) { + return String.format(REBOT_PREFIX, accountName); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtApplyDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtApplyDao.java new file mode 100644 index 0000000..a4abe36 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtApplyDao.java @@ -0,0 +1,39 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import me.zhengjie.entity.CtApply; +import me.zhengjie.service.vo.CtApplyListVO; +import me.zhengjie.service.vo.CtBuyerListVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + * 影刀应用信息(CtApply)表数据库访问层 + * + * @author rch + * @since 2022-07-23 + */ +@Mapper +public interface CtApplyDao extends BaseMapper { + + + @Select("select * from ct_apply ${ew.customSqlSegment}") + IPage searchPageList(IPage page, Wrapper ew); + + /** + * 获取所有应用名称 + * @return List + */ + @Select("select id,name, platform_id from ct_apply") + List getAllApplyName(); + + @Select("select * from ct_apply where task_name = #{taskName} and method_name = #{method}") + CtApply getApplyByTaskAndMethod(String taskName, String method); +} + + + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtBrowseDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtBrowseDao.java new file mode 100644 index 0000000..4054b15 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtBrowseDao.java @@ -0,0 +1,61 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import me.zhengjie.entity.CtBrowse; +import me.zhengjie.service.vo.CtBrowseDetailVO; +import me.zhengjie.service.vo.CtBrowseListVO; +import me.zhengjie.service.vo.CtBuyerListVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +/** + * 刷单-订单信息(CtBrowse)表数据库访问层 + * + * @author rch + * @since 2022-11-04 + */ +@Mapper +public interface CtBrowseDao extends BaseMapper { + + /** + * 分页查询 + * @param page + * @param ew + */ +// @Select("select * from ct_browse ${ew.customSqlSegment} ") + @Select("SELECT\n" + + "\tctBrowse.id,\n" + + "\tctBrowse.buyer_id,\n" + + "\tctBrowse.link_url,\n" + + "\tctBrowse.created_at,\n" + + "\tctBrowse.updated_at,\n" + + "\tctBrowse.payment_results,\n" + + "\tctBrowse.status,\n" + + "\tctBrowse.gm_name,\n" + + "\tctBuyer.contntry_short as country,\n" + + "\tctBuyer.account\n" + + "FROM\n" + + "\tct_browse ctBrowse\n" + + "LEFT JOIN \n" + + "\tct_buyer ctBuyer \n" + + "ON \n" + + "\tctBrowse.buyer_id = ctBuyer.id ${ ew.customSqlSegment}") + IPage searchPageList(IPage page, Wrapper ew); + + @Select("select * from ct_browse where id = #{id} for update") + CtBrowse getByIdLock(Long id); + + @Select("SELECT\n" + + "\tctBrowse.*,\n" + + "\tctBuyer.account,\n" + + "\tctBuyer.contntry_short as country\n" + + "FROM\n" + + "\tct_browse ctBrowse\n" + + "\tLEFT JOIN ct_buyer ctBuyer ON ctBrowse.buyer_id = ctBuyer.id \n" + + "WHERE\n" + + "\tctBrowse.id = #{id}") + CtBrowseDetailVO getBrowseDetailById(Long id); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtBuyerDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtBuyerDao.java new file mode 100644 index 0000000..358dcb1 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtBuyerDao.java @@ -0,0 +1,56 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import me.zhengjie.entity.CtBuyer; +import me.zhengjie.service.vo.CtBuyerDetailVO; +import me.zhengjie.service.vo.CtBuyerListVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + * 买家信息表(CtBuyer)表数据库访问层 + * + * @author rch + * @since 2022-06-22 + */ +@Mapper +public interface CtBuyerDao extends BaseMapper { + + // @Select("select t1.*, t2.name as companyName, t3.id as cardId, t3.number as number, t3.pwd as cardPwd, t3.holder_surname as holderSurname, t3.holder_name as holderName, t4.id as vpnId, t4.ip_address as ipAddress, t4.link as vpn from ct_buyer t1 left join ct_company t2 on t1.company_id = t2.id left join ct_card t3 on t1.card_id = t3.id left join ct_vpn t4 on t1.vpn_id = t4.id ${ew.customSqlSegment} ") + @Select("SELECT\n" + + "\tt1.*,\n" + + "\tt2.NAME AS companyName,\n" + + "\tt5.NAME AS platformName,\n" + + "\tt3.id AS cardId,\n" + + "\tt3.number AS number,\n" + + "\tt3.pwd AS cardPwd,\n" + + "\tt3.holder_surname AS holderSurname,\n" + + "\tt3.holder_name AS holderName,\n" + + "\tt4.id AS vpnId,\n" + + "\tt4.ip_address AS ipAddress,\n" + + "\tt4.link AS vpn \n" + + "FROM\n" + + "\tct_buyer t1\n" + + "\tLEFT JOIN ct_company t2 ON t1.company_id = t2.id\n" + + "\tLEFT JOIN ct_platform t5 ON t1.platform_id = t5.id\n" + + "\tLEFT JOIN ct_card t3 ON t1.card_id = t3.id\n" + + "\tLEFT JOIN ct_vpn t4 ON t1.vpn_id = t4.id ${ ew.customSqlSegment }") + IPage searchPageList(IPage page, Wrapper ew); + + @Select("select t1.*, t2.name as companyName, t3.ip_address as ipAddress, t3.link as vpn, t4.number, t4.pwd as cardPwd, t4.holder_surname as holderSurname, t4.holder_name as holderName from ct_buyer t1 left join ct_company t2 on t1.company_id = t2.id left join ct_vpn t3 on t1.vpn_id = t3.id left join ct_card t4 on t1.card_id = t4.id where t1.id = ${id}") + CtBuyerDetailVO getDetailById(Long id); + + @Select("select account from ct_buyer") + List getAllAccount(); + + @Select("select pwd from ct_buyer where account = #{name}") + String getPwdByName(String name); + + @Select("select id, occupy_status, company_id, platform_id from ct_buyer where account = #{buyerName} for update") + CtBuyer getBuyerOccupyStatusLock(String buyerName); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtCardDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtCardDao.java new file mode 100644 index 0000000..c43dc2d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtCardDao.java @@ -0,0 +1,34 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import me.zhengjie.entity.CtCard; +import me.zhengjie.entity.CtCardInfo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + * 信用卡信息(CtCard)表数据库访问层 + * + * @author rch + * @since 2022-07-07 + */ +@Mapper +public interface CtCardDao extends BaseMapper { + + @Select("select number from ct_card") + List getNumberList(); + + //@Select("select id,number from ct_card where number in ${number}") + @Select({ + "" + }) + List getCardInfoByNumber(List number); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtClickFarmingDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtClickFarmingDao.java new file mode 100644 index 0000000..1669d9e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtClickFarmingDao.java @@ -0,0 +1,90 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import me.zhengjie.entity.CtBuyerClickSuccess; +import me.zhengjie.entity.CtClickFarmYdParams; +import me.zhengjie.entity.CtClickFarming; +import me.zhengjie.service.vo.CtClickFarmEditDetailVO; +import me.zhengjie.service.vo.CtClickFarmingDetailVO; +import me.zhengjie.service.vo.CtClickFarmingVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + * 刷单Excel信息(CtClickFarming)表数据库访问层 + * + * @author rch + * @since 2022-08-16 + */ +@Mapper +public interface CtClickFarmingDao extends BaseMapper { + + // @Select("select farming.* from ct_click_farming farming left join ct_click_order clickOrder on farming.ct_click_order_id = clickOrder.id ${ew.customSqlSegment} ") + @Select("SELECT\n" + + "\tfarming.*,\n" + + "\tbuyer.contntry_short as country,\n" + + "\tbuyer.account\n" + + "FROM\n" + + "\tct_click_farming farming\n" + + "\tLEFT JOIN ct_click_order clickOrder ON farming.ct_click_order_id = clickOrder.id\n" + + "\tLEFT JOIN ct_buyer buyer ON buyer.id = farming.buyer_id\n" + + "${ew.customSqlSegment}") + IPage searchPageList(IPage page, Wrapper ew); + + @Select("select * from ct_click_farming where id = #{id} for update") + CtClickFarming getByIdLock(Long id); + + @Select("SELECT t1.*, t2.account AS buyer_name FROM ct_click_farming t1 LEFT JOIN ct_buyer t2 ON t1.buyer_id = t2.id where t1.id = #{id}") + CtClickFarmEditDetailVO getEditDetailById(Long id); + + @Select("SELECT t1.*, t2.account AS buyer_name FROM ct_click_farming t1 LEFT JOIN ct_buyer t2 ON t1.buyer_id = t2.id where t1.id = #{id}") + CtClickFarmingDetailVO getDetailById(Long id); + +// @Select("select buyer_id, count(1) as successCount from ct_click_farming where account != #{buyerAccount} and `status` = 3 GROUP BY buyer_id;") +// @Select("SELECT\n" + +// "\tclick.buyer_id,\n" + +// "\tcount( 1 ) AS successCount \n" + +// "FROM\n" + +// "\tct_click_farming AS click \t\n" + +// "\tLEFT JOIN ct_buyer AS buyer ON buyer.id = click.buyer_id and click.account != #{buyerAccount} AND click.status = 3\n" + +// "\tAND buyer.occupy_status = 2 AND buyer.country = #{country} and click.shopName != #{shopName} And ct\n" + +// "GROUP BY\n" + +// "\tbuyer_id;") +// @Select("SELECT click.buyer_id, count( 1 ) AS successCount, click.created_at FROM ct_click_farming AS click LEFT JOIN ct_buyer AS buyer ON buyer.id = click.buyer_id AND click.account != #{buyerAccount} AND click.STATUS = 3 AND buyer.occupy_status = 2 AND buyer.country = #{country} AND click.shop_name != #{shopName} GROUP BY buyer_id HAVING created_at < DATE_SUB(CURDATE(), INTERVAL 1 MONTH)") + @Select("SELECT click.buyer_id, count(1) AS successCount, click.status, click.created_at FROM ct_click_farming AS click LEFT JOIN ct_buyer AS buyer ON buyer.id = click.buyer_id AND click.account != #{buyerAccount} AND buyer.occupy_status = 2 AND buyer.country = #{country} AND click.shop_name != #{shopName} GROUP BY buyer_id HAVING created_at < DATE_SUB(CURDATE(), INTERVAL 1 MONTH) AND STATUS = 3") + List ruleGetCtBuyer(String buyerAccount, String country, String shopName); + + @Select("SELECT\n" + + "\tfarming.id,\n" + + "\tfarming.key_word as keyWord,\n" + + "\tfarming.number,\n" + + "\tfarming.params_type,\n" + + "\tfarming.specification,\n" + + "\tfarming.color,\n" + + "\tfarming.item,\n" + + "\tfarming.exchange,\n" + + "\tfarming.link,\n" + + "\tfarming.section_min as sectionMin,\n" + + "\tfarming.section_max as sectionMax,\n" + + "\tfarming.amessage,\n" + + "\tbuyer.contntry_short as country,\n" + + "\tbuyer.account,\n" + + "\tbuyer.pwd,\n" + + "\tctVpn.link as vpnShare,\n" + + "\tctCard.term_of_validity as termOfValidity,\n" + + "\tCONCAT(ctCard.holder_surname, \" \",ctCard.holder_name) AS cardName,\n" + + "\tctCard.number as cardNumber,\n" + + "\tctCard.pwd as cardPwd\n" + + "FROM\n" + + "\tct_click_farming farming\n" + + "\tLEFT JOIN ct_click_order clickOrder ON farming.ct_click_order_id = clickOrder.id\n" + + "\tLEFT JOIN ct_buyer buyer ON buyer.id = farming.buyer_id\n" + + "\tLEFT JOIN ct_vpn ctVpn ON buyer.vpn_id = ctVpn.id\n" + + "\tLEFT JOIN ct_card ctCard ON buyer.card_id = ctCard.id where farming.id = #{id}") + CtClickFarmYdParams getCtClickFarmYdParams(Long id); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtClickOrderDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtClickOrderDao.java new file mode 100644 index 0000000..b90cfa3 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtClickOrderDao.java @@ -0,0 +1,100 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import me.zhengjie.entity.CtClickFarmingOrderInfo; +import me.zhengjie.entity.CtClickOrder; +import me.zhengjie.service.vo.CtClickOrderDetailVO; +import me.zhengjie.service.vo.CtClickOrderListVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +/** + * 刷单-订单信息(CtClickOrder)表数据库访问层 + * + * @author rch + * @since 2022-09-14 + */ +@Mapper +public interface CtClickOrderDao extends BaseMapper { + + /** + * 分页查询 + * @param page + * @param ew + */ + //TODO sql 修改 +// @Select("SELECT\n" + +// "\t`order`.platform_id, \n" + +// "\t`order`.company_id, \n" + +// "\t`order`.id, \n" + +// "\t`order`.created_at, \n" + +// "\t`order`.updated_at, \n" + +// "\t`order`.amount, \n" + +// "\t`order`.shop, \n" + +// "\t`order`.order_id, \n" + +// "\t`order`.comment, \n" + +// "\t`order`.account, \n" + +// "\t`order`.pwd, \n" + +// "\tcompany.`name` AS companyName, \n" + +// "\tplatform.`name` AS platformName\n" + +// "FROM\n" + +// "\tct_click_order AS `order`\n" + +// "\tLEFT JOIN\n" + +// "\tct_platform AS platform\n" + +// "\tON \n" + +// "\t\t`order`.platform_id = platform.id\n" + +// "\tLEFT JOIN\n" + +// "\tct_company AS company\n" + +// "\tON \n" + +// "\t\t`order`.company_id = company.id ${ew.customSqlSegment} ") + @Select("SELECT clickOrder.company_id, clickOrder.type, clickOrder.status, clickOrder.id, clickOrder.created_at, clickOrder.updated_at, clickOrder.amount, clickOrder.shop, clickOrder.order_id, clickOrder.comment, company.name AS companyName FROM ct_click_order AS clickOrder LEFT JOIN ct_company AS company ON clickOrder.company_id = company.id ${ew.customSqlSegment}") + IPage searchPageList(IPage page, Wrapper ew); + + @Select("SELECT\n" + + "\tclickOrder.id,\n" + + "\tclickOrder.order_id,\n" + + "\tclickOrder.COMMENT,\n" + + "\tclickOrder.STATUS,\n" + + "\tclickOrder.paths,\n" + + "\tbuyer.country,\n" + + "\tbuyer.account,\n" + + "\tbuyer.pwd,\n" + + "\tctVpn.link as vpnShare\n" + + "FROM\n" + + "\tct_click_order clickOrder\n" + + "\tLEFT JOIN ct_click_farming clickFarming ON clickOrder.id = clickFarming.ct_click_order_id \n" + + "\tLEFT JOIN ct_buyer buyer ON buyer.id = clickFarming.buyer_id\n" + + "\tLEFT JOIN ct_vpn ctVpn ON buyer.vpn_id = ctVpn.id\n" + + "WHERE \n" + + "\tclickOrder.id = #{orderId}") + CtClickFarmingOrderInfo getClickFarmOrderById(Long orderId); + + @Select("select * from ct_click_order where id = #{id} for update") + CtClickOrder getByIdLock(Long id); + + @Select("SELECT\n" + + "\tclickOrder.id,\n" + + "\tclickOrder.created_at,\n" + + "\tclickOrder.updated_at,\n" + + "\tclickOrder.prices_number,\n" + + "\tclickOrder.payment_results,\n" + + "\tclickOrder.order_id,\n" + + "\tclickOrder.COMMENT,\n" + +// "\tclickOrder.status,\n" + +// "\tclickOrder.platform_id,\n" + + "\tclickOrder.company_id,\n" + + "\tclickOrder.amount,\n" + + "\tclickOrder.shop,\n" + + "\tclickOrder.shop_name,\n" + + "\tclickOrder.order_date,\n" + + "\tclickOrder.paths\n" + + "FROM\n" + + "\tct_click_order clickOrder\n" + + "\tLEFT JOIN ct_click_farming clickFarming ON clickOrder.id = clickFarming.ct_click_order_id \n" + + "WHERE\n" + + "\tclickOrder.id = #{orderId}") + CtClickOrderDetailVO getClickOrderDetailById(Long id); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtCompanyDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtCompanyDao.java new file mode 100644 index 0000000..a5ff0de --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtCompanyDao.java @@ -0,0 +1,34 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import me.zhengjie.entity.CtCompany; +import me.zhengjie.entity.CtCompanyInfo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + * 公司信息(CtCompany)表数据库访问层 + * + * @author zhw + * @since 2022-07-14 + */ +@Mapper +public interface CtCompanyDao extends BaseMapper { + + @Select({ + "" + }) + List getByName(@Param("names") List names); + + @Select("select id,name from ct_company") + List getCompanyList(); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtDhPayDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtDhPayDao.java new file mode 100644 index 0000000..3bc6536 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtDhPayDao.java @@ -0,0 +1,24 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import me.zhengjie.entity.CtDhPay; +import me.zhengjie.service.vo.CtBuyerListVO; +import me.zhengjie.service.vo.CtDhPayListVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +/** + * 平台信息(CtDyPay)表数据库访问层 + * + * @author rch + * @since 2022-07-28 + */ +@Mapper +public interface CtDhPayDao extends BaseMapper { + + @Select("select * from ct_dh_pay ${ew.customSqlSegment}") + IPage searchPageList(IPage page, Wrapper ew); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtExcelDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtExcelDao.java new file mode 100644 index 0000000..1291b82 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtExcelDao.java @@ -0,0 +1,17 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import me.zhengjie.entity.CtExcel; +import org.apache.ibatis.annotations.Mapper; + +/** + * Excel 导入信息(CtExcel)表数据库访问层 + * + * @author makejava + * @since 2022-06-23 10:37:44 + */ +@Mapper +public interface CtExcelDao extends BaseMapper { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtExcelImportInfoDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtExcelImportInfoDao.java new file mode 100644 index 0000000..94f2f76 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtExcelImportInfoDao.java @@ -0,0 +1,17 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import me.zhengjie.entity.CtExcelImportInfo; +import org.apache.ibatis.annotations.Mapper; + +/** + * Excel导入信息(CtExcelImportInfo)表数据库访问层 + * + * @author rch + * @since 2022-06-23 + */ +@Mapper +public interface CtExcelImportInfoDao extends BaseMapper { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtOrderDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtOrderDao.java new file mode 100644 index 0000000..c20f9da --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtOrderDao.java @@ -0,0 +1,17 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import me.zhengjie.entity.CtOrder; +import org.apache.ibatis.annotations.Mapper; + +/** + * (CtOrder)表数据库访问层 + * + * @author rch + * @since 2022-07-01 + */ +@Mapper +public interface CtOrderDao extends BaseMapper { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtPlatformDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtPlatformDao.java new file mode 100644 index 0000000..486b02c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtPlatformDao.java @@ -0,0 +1,17 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import me.zhengjie.entity.CtPlatform; +import org.apache.ibatis.annotations.Mapper; + +/** + * 平台信息(CtPlatform)表数据库访问层 + * + * @author rch + * @since 2022-06-23 10:37:44 + */ +@Mapper +public interface CtPlatformDao extends BaseMapper { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtRebotDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtRebotDao.java new file mode 100644 index 0000000..589314c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtRebotDao.java @@ -0,0 +1,41 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import me.zhengjie.base.BaseEntity; +import me.zhengjie.entity.CtRebot; +import me.zhengjie.service.vo.CtRebotListVO; +import me.zhengjie.utils.PageUtils; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; + +import java.util.List; + +/** + * 影刀设备-机器人信息(CtRebot)表数据库访问层 + * + * @author rch + * @since 2022-07-23 + */ +@Mapper +public interface CtRebotDao extends BaseMapper { + + @Select("select * from ct_rebot where account_name = #{accountName} for update") + CtRebot getByAccountNameLock(String accountName); + + + @Select("select * from ct_rebot ${ew.customSqlSegment}") + IPage searchRebotList(IPage page, Wrapper ew); + + @Select("select account_name from ct_rebot") + List getAccountNameList(); + + @Select("select robot_client_uuid from ct_rebot") + List getClientUuidList(); + + @Update("update ct_rebot set status = #{newStatus} where id = #{id} and status = #{oldStatus}") + Boolean updateNewStatusByOldStatus(Long id, Integer newStatus, Integer oldStatus); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtResponseOrderAddressDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtResponseOrderAddressDao.java new file mode 100644 index 0000000..e2195fb --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtResponseOrderAddressDao.java @@ -0,0 +1,17 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import me.zhengjie.entity.CtResponseOrderAddress; +import org.apache.ibatis.annotations.Mapper; + +/** + * 下注成功订单响应收货地址信息(CtResponseOrderAddress)表数据库访问层 + * + * @author rch + * @since 2022-07-01 + */ +@Mapper +public interface CtResponseOrderAddressDao extends BaseMapper { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtResponseOrderDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtResponseOrderDao.java new file mode 100644 index 0000000..5824efb --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtResponseOrderDao.java @@ -0,0 +1,17 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import me.zhengjie.entity.CtResponseOrder; +import org.apache.ibatis.annotations.Mapper; + +/** + * 下单成功响应订单商品信息(CtResponseOrder)表数据库访问层 + * + * @author rch + * @since 2022-07-01 + */ +@Mapper +public interface CtResponseOrderDao extends BaseMapper { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtResponseOrderProductDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtResponseOrderProductDao.java new file mode 100644 index 0000000..0ff58c8 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtResponseOrderProductDao.java @@ -0,0 +1,17 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import me.zhengjie.entity.CtResponseOrderProduct; +import org.apache.ibatis.annotations.Mapper; + +/** + * 下单订单响应产品信息(CtResponseOrderProduct)表数据库访问层 + * + * @author rch + * @since 2022-07-01 + */ +@Mapper +public interface CtResponseOrderProductDao extends BaseMapper { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/CtVpnDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/CtVpnDao.java new file mode 100644 index 0000000..7d0aa3e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/CtVpnDao.java @@ -0,0 +1,35 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import me.zhengjie.entity.CtVpn; +import me.zhengjie.entity.CtVpnInfo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + * VPN信息表(CtVpn)表数据库访问层 + * + * @author rch + * @since 2022-07-07 + */ +@Mapper +public interface CtVpnDao extends BaseMapper { + + @Select("select ip_address from ct_vpn") + List getIpList(); + + //@Select("select id,ip_address from ct_vpn where ip_address in ${ipAddress}") + @Select({ + "" + }) + List getVpnInfoByIp(List ipAddress); + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/DhAddCarDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/DhAddCarDao.java new file mode 100644 index 0000000..89e96ba --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/DhAddCarDao.java @@ -0,0 +1,61 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import me.zhengjie.entity.DhAddCar; +import me.zhengjie.service.vo.dhaddcar.DhAddCarVO; +import me.zhengjie.service.vo.dhaddcar.DhAddCarListVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +/** + * 敦煌加入购物车(DhAddCar)表数据库访问层 + * + * @author rch + * @since 2022-11-17 09:11:53 + */ +@Mapper +public interface DhAddCarDao extends BaseMapper { + + @Select("SELECT\n" + + "\tdhAddCar.*,\n" + + "\tbuyer.id AS buyerId,\n" + + "\tbuyer.account,\n" + + "\tbuyer.contntry_short AS country,\n" + + "\tcompany.NAME AS companyName\n" + + "\t\n" + + "FROM\n" + + "\tdh_add_car AS dhAddCar\n" + + "LEFT JOIN\n" + + "\tct_buyer buyer ON dhAddCar.buyer_id = buyer.id\n" + + "LEFT JOIN\n" + + "\tct_company company ON buyer.company_id = company.id\n" + + "\t${ew.customSqlSegment}") + IPage searchPageList(IPage page, Wrapper ew); + + + @Select("SELECT\n" + + " dhAddCar.id,\n" + + "\tdhAddCar.params_type,\n" + + "\tdhAddCar.car_good_ids AS carGoodIds,\n" + + "\tbuyer.id AS buyerId,\n" + + "\tbuyer.account,\n" + + "\tbuyer.contntry_short as country,\n" + + "\tbuyer.pwd,\n" + + "\tvpn.link as vpnShare,\n" + + "\tdhAddCar.status,\n" + + "\tcompany.NAME AS companyName\n" + + "FROM\n" + + "\tdh_add_car AS dhAddCar\n" + + "\tLEFT JOIN ct_buyer buyer ON dhAddCar.buyer_id = buyer.id\n" + + "\tLEFT JOIN ct_vpn vpn ON buyer.vpn_id = vpn.id\n" + + "\tLEFT JOIN\n" + + "\tct_company company ON buyer.company_id = company.id\n" + + "\tWHERE dhAddCar.id = #{id}") + DhAddCarVO getDetailById(Long id); + + @Select("select * from dh_add_car where id = #{id}") + DhAddCar getByIdLock(Long id); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/DhAddCarOrderDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/DhAddCarOrderDao.java new file mode 100644 index 0000000..c103c95 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/DhAddCarOrderDao.java @@ -0,0 +1,48 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import me.zhengjie.entity.DhAddCarOrder; +import me.zhengjie.service.vo.dhaddcar.DhAddCarListVO; +import me.zhengjie.service.vo.dhcarorder.DhAddCarOrderListVO; +import me.zhengjie.service.vo.dhcarorder.DhCarOrderParamsVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +/** + * 敦煌-加购物车-订单(DhAddCarOrder)表数据库访问层 + * + * @author rch + * @since 2022-11-17 09:11:57 + */ +@Mapper +public interface DhAddCarOrderDao extends BaseMapper { + + @Select("select * from dh_add_car_order where id = #{id} for update") + DhAddCarOrder getByIdLock(Long id); + + @Select("select * from dh_add_car_order ${ew.customSqlSegment}") + IPage searchPageList(IPage page, Wrapper ew); + + @Select("SELECT\n" + + "\tdhAddCarOrder.id,\n" + + "\tdhAddCarOrder.order_id,\n" + + "\tdhAddCar.params_type,\n" + + "\tdhAddCar.car_good_ids AS carGoodIds,\n" + + "\tbuyer.id AS buyerId,\n" + + "\tbuyer.account,\n" + + "\tbuyer.contntry_short AS country,\n" + + "\tbuyer.pwd,\n" + + "\tvpn.link AS vpnShare\n" + + "FROM\n" + + "\tdh_add_car_order as dhAddCarOrder\n" + + "\tLEFT JOIN dh_add_car dhAddCar ON dhAddCar.id = dhAddCarOrder.add_car_id\n" + + "\tLEFT JOIN ct_buyer buyer ON dhAddCar.buyer_id = buyer.id\n" + + "\tLEFT JOIN ct_vpn vpn ON buyer.vpn_id = vpn.id\n" + + "\tLEFT JOIN ct_company company ON buyer.company_id = company.id \n" + + "WHERE\n" + + "\tdhAddCarOrder.id = #{id}") + DhCarOrderParamsVO getYdParams(Long id); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/DhCarGoodsDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/DhCarGoodsDao.java new file mode 100644 index 0000000..8aa8743 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/DhCarGoodsDao.java @@ -0,0 +1,17 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import me.zhengjie.entity.DhCarGoods; +import org.apache.ibatis.annotations.Mapper; + +/** + * 敦煌-加入购物车商品信息(DhCarGoods)表数据库访问层 + * + * @author makejava + * @since 2022-11-17 09:12:01 + */ +@Mapper +public interface DhCarGoodsDao extends BaseMapper { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/LoginIpDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/LoginIpDao.java new file mode 100644 index 0000000..0acee04 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/LoginIpDao.java @@ -0,0 +1,17 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import me.zhengjie.entity.LoginIp; +import org.apache.ibatis.annotations.Mapper; + +/** + * (LoginIp)表数据库访问层 + * + * @author zeng + * @since 2022-03-21 14:07:01 + */ +@Mapper +public interface LoginIpDao extends BaseMapper { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/SettingSiteDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/SettingSiteDao.java new file mode 100644 index 0000000..b4f548f --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/SettingSiteDao.java @@ -0,0 +1,17 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import me.zhengjie.entity.CtSettingSite; +import org.apache.ibatis.annotations.Mapper; + +/** + * 站点配置(CtSettingSite)表数据库访问层 + * + * @author rch + * @since 2021-11-23 + */ +@Mapper +public interface SettingSiteDao extends BaseMapper { + String getValueByKey(String key); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/SysQuartzJobDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/SysQuartzJobDao.java new file mode 100644 index 0000000..ca96b7c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/SysQuartzJobDao.java @@ -0,0 +1,26 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import me.zhengjie.entity.SysQuartzJob; +import me.zhengjie.service.vo.SysQuartzJobListVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +/** + * 定时任务(SysQuartzJob)表数据库访问层 + * + * @author zhw + * @since 2022-07-21 + */ +@Mapper +public interface SysQuartzJobDao extends BaseMapper { + + @Select("select * from sys_quartz_job ${ew.customSqlSegment}") + IPage searchPageList(IPage page, Wrapper ew); + + @Select("select * from sys_quartz_job where task_num = #{taskNum}") + SysQuartzJob getByTaskNum(String taskNum); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/SysQuartzLogDao.java b/wjcy-common/src/main/java/me/zhengjie/dao/SysQuartzLogDao.java new file mode 100644 index 0000000..64b4ba5 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/SysQuartzLogDao.java @@ -0,0 +1,23 @@ +package me.zhengjie.dao; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import me.zhengjie.entity.SysQuartzLog; +import me.zhengjie.service.vo.SysQuartzLogListVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +/** + * 定时任务(SysQuartzLog)表数据库访问层 + * + * @author rch + * @since 2022-07-20 + */ +@Mapper +public interface SysQuartzLogDao extends BaseMapper { + + @Select("select * from sys_quartz_log ${ew.customSqlSegment} ") + IPage searchPageList(IPage page, Wrapper ew); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/dao/mapper/CtDhPayService.xml b/wjcy-common/src/main/java/me/zhengjie/dao/mapper/CtDhPayService.xml new file mode 100644 index 0000000..25a0430 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dao/mapper/CtDhPayService.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/dto/Dto.java b/wjcy-common/src/main/java/me/zhengjie/dto/Dto.java new file mode 100644 index 0000000..159b385 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dto/Dto.java @@ -0,0 +1,73 @@ +package me.zhengjie.dto; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.error.ErrorCodeEnum; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * 请求结果通用数据结构 + *

+ * + * @author: zeng + * @since: 2020-07-01 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Slf4j +public class Dto implements Serializable { + + private int code; + + private String message; + + private T data; + + private Dto(Object data) { + this.code = 200; + this.message = "请求成功"; + this.data =(T) data; + } + + private Dto(int code, String message) { + this.code = code; + this.message = message; + } + + public Dto setData(String key, Object value) { + if (this.data == null) { + data = (T)new HashMap(16); + } + ((Map) data).put(key, value); + return this; + } + + public static Dto returnResult(Object data) { + return new Dto(data); + } + + public static Dto returnErrorResult(String message) { + return new Dto(-1, message); + } + + public static Dto getInstance(ErrorCodeEnum errorCodeEnum) { + log.error("---枚举类返回错误信息:--return error:" + errorCodeEnum.getDesc()); + return new Dto(errorCodeEnum.getCode(), errorCodeEnum.getDesc()); + } + + public boolean success(Dto dto){ + if (dto.getCode() == 200) { + return true; + } else { + return false; + } + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/dto/PageDTO.java b/wjcy-common/src/main/java/me/zhengjie/dto/PageDTO.java new file mode 100644 index 0000000..ed0fa84 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dto/PageDTO.java @@ -0,0 +1,49 @@ +package me.zhengjie.dto; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * @Description 分页查询参数 + * @Date 2022-06-22 + * @Author rch + */ +@Data +public class PageDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 当前页码 */ + @Min(value = 1) + @NotNull + private Integer page; + /** 页面大小 */ + @Min(value = 1) + @NotNull + private Integer pageSize; + /** 排序字段 */ + private String sort; + /** 排序方式 asc/desc */ + private String order; + + /** 获取mysql limit 分页的起始位置 */ + public Integer getLimitStart() { + int i = (page-1)*pageSize; + return i > 0 ? i : 0; + } + + public IPage getiPage(){ + return new Page(page, pageSize); + } + + + public boolean isAsc() { + return "asc".equalsIgnoreCase(order); + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/dto/StatementAggregateDTO.java b/wjcy-common/src/main/java/me/zhengjie/dto/StatementAggregateDTO.java new file mode 100644 index 0000000..ba9bf10 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/dto/StatementAggregateDTO.java @@ -0,0 +1,38 @@ +package me.zhengjie.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.PageUtils; + +import java.util.List; + +/** + * 本页合计、总计DTO + * @author zeng + * @since 2021/10/11 19:37 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class StatementAggregateDTO { + + /** 列表 */ + private List list; + + /** 本页小计 */ + private T pageTotal; + + /** 总计 */ + private T aggregate; + + /** 总记录数 */ + private Long total; + + public StatementAggregateDTO(PageUtils pageUtils, T pageTotal, T aggregate) { + this.list = pageUtils.getList(); + this.pageTotal = pageTotal; + this.aggregate = aggregate; + this.total = pageUtils.getTotal(); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtApply.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtApply.java new file mode 100644 index 0000000..f09b9de --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtApply.java @@ -0,0 +1,73 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 影刀应用信息(CtApply)表实体类 + * + * @author rch + * @since 2022-07-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel +public class CtApply extends Model { + + @TableId(value = "id", type = IdType.AUTO) + @ApiModelProperty(value = "id") + private Long id; + + @TableField(fill = FieldFill.INSERT) + @ApiModelProperty(value = "创建时间") + private String createdAt; + + @TableField(fill = FieldFill.INSERT_UPDATE) + @ApiModelProperty(value = "修改时间") + private String updatedAt; + + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + @ApiModelProperty(value = "操作人账号") + private String gmName; + + /** 应用名称 */ + @ApiModelProperty(value = "应用名称") + private String name; + + /** 任务名称 */ + @ApiModelProperty(value = "任务名称") + private String taskName; + + /** 方法名称 */ + @ApiModelProperty(value = "方法名称") + private String methodName; + + /** accessKeyId */ + @ApiModelProperty(value = "accessKeyId") + private String accessKeyId; + + /** accessKeySecret */ + @ApiModelProperty(value = "accessKeySecret") + private String accessKeySecret; + + /** 应用id */ + @ApiModelProperty(value = "应用id") + private String robotUuid; + + /** 备注 */ + @ApiModelProperty(value = "备注") + private String remark; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtBrowse.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtBrowse.java new file mode 100644 index 0000000..2a64547 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtBrowse.java @@ -0,0 +1,45 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 浏览收藏(CtBrowse)表实体类 + * + * @author rch + * @since 2022-11-04 09:45:31 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtBrowse extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 买家ID */ + private Long buyerId; + + /** 收藏链接 */ + private String linkUrl; + + /** 状态描述 */ + private String paymentResults; + + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + private Integer status; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtBrowseYdParams.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtBrowseYdParams.java new file mode 100644 index 0000000..89f99a6 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtBrowseYdParams.java @@ -0,0 +1,33 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 浏览好评订单影刀参数 + * + * @author rch + * @since 2022-11-07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtBrowseYdParams { + private Long id; + + /** 国家 */ + private String country; + + /** 账号 */ + private String account; + + /** 密码 */ + private String pwd; + + /** vpn分享链接 */ + private String vpnShare; + + /** 收藏链接 */ + private String linkUrl; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyer.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyer.java new file mode 100644 index 0000000..49ab741 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyer.java @@ -0,0 +1,103 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +/** + * 买家信息表(CtBuyer)表实体类 + * + * @author rch + * @since 2022-06-22 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtBuyer extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 昵称*/ + private String nickName; + /** 账号*/ + private String account; + /** 密码*/ + private String pwd; + /** 公司id */ + private Long companyId; + /** 平台id */ + private Integer platformId; + /** 平台名称 */ +// private String platformName; + + // TODO 导入需要的字段接着往下添加 + + /** 国家 */ + private String contntryShort; + /** 邮件 */ + private String email; + /** Email密码 */ + private String emailPwd; + /** VPN_ID(导入excel里包含) */ + private Long vpnId; + /** 信用卡ID */ + private Long cardId; + /** 用户等级(导入默认内部账号) 1.普通 2.精品 3.压力 4.内部账号 */ + private Integer level; + /** 占用状态 1.已占用 2.未占用 */ + private Integer occupyStatus; + /** 占用账户 */ + private String occupyAccount; + /** 账户余额 */ + private BigDecimal balance; + /** 账户购买总金额 */ + private BigDecimal buyTotalMoney; + /** mac */ + private String mac; + /** route_mac*/ + private String routeMac; + /** Cookies值 */ + private String cookies; + /** 过期时间 */ + private String expireDate; + /** 状态(导入默认正常) 1.待注册 2待验证 3.待完善 4.正常 5.异常 6.可用但已用 7.删除 */ + private Integer status; + + // ==================地址信息相关========================================begin + /** 地址1 */ + private String addressline1; + /** 国家 */ + private String country; + /** 州 */ + private String state; + /** 电话 */ + private String tel; + /** lastname */ + private String lastname; + /** 税号 */ + private String vatNumber; + /** 城市 */ + private String city; + /** 地址2 */ + private String addressline2; + /** firstname */ + private String firstname; + /** 邮政编码 */ + private String postalcode; + // ==================地址信息相关========================================end +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerClickSuccess.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerClickSuccess.java new file mode 100644 index 0000000..13f46d8 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerClickSuccess.java @@ -0,0 +1,19 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 统计买家刷单成功个数信息 + * + * @author rch + * @create 2022-10-10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtBuyerClickSuccess { + private Long buyerId; + private Integer successCount; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerContactInfo.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerContactInfo.java new file mode 100644 index 0000000..a680207 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerContactInfo.java @@ -0,0 +1,45 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * 买家收款地址信息 + * + * @author rch + * @since 2022-07-18 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtBuyerContactInfo { + /** 地址1 */ + private String addressline1; + /** 国家 */ + private String country; + /** 州 */ + private String state; + /** 电话 */ + private String tel; + /** lastname */ + private String lastname; + /** 税号 */ + private String vatNumber; + /** 城市 */ + private String city; + /** 地址2 */ + private String addressline2; + /** firstname */ + private String firstname; + /** 邮政编码 */ + private String postalcode; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerExport.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerExport.java new file mode 100644 index 0000000..92efaa9 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerExport.java @@ -0,0 +1,71 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + + +/** + * 买家信息(CtBuyer)表实体类 导出对象信息 + * @author zhw + * @since 2022-07-14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtBuyerExport { + + + @ExcelExport(value = "昵称") + /** 昵称*/ + private String nickName; + /** 账号*/ + @ExcelExport(value = "账号") + private String account; + /** 密码*/ + @ExcelExport(value = "密码") + private String pwd; + /** 公司名称 */ + @ExcelExport(value = "公司名称") + private String companyName; + /** 平台名称 */ + @ExcelExport(value = "平台名称") + private String platformName; + /** 国家 */ + @ExcelExport(value = "所属国家") + private String contntryShort; + /** VPN_IP地址*/ + @ExcelExport(value = "VPN_IP地址") + private String vpnIp; + /** 信用卡卡号 */ + @ExcelExport(value = "信用卡卡号") + private String cardNumber; + /** 地址1 */ + @ExcelExport(value = "地址1") + private String addressline1; + /** 国家 */ + @ExcelExport(value = "国家") + private String country; + /** 州 */ + @ExcelExport(value = "州") + private String state; + /** 电话 */ + @ExcelExport(value = "电话") + private String tel; + /** lastname */ + @ExcelExport(value = "lastname") + private String lastname; + /** 城市 */ + @ExcelExport(value = "城市") + private String city; + /** firstname */ + @ExcelExport(value = "firstname") + private String firstname; + /** 邮政编码 */ + @ExcelExport(value = "邮政编码") + private String postalcode; + /** 异常信息 */ + @ExcelExport(value = "异常信息") + private String error; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerExportTemple.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerExportTemple.java new file mode 100644 index 0000000..c92d084 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerExportTemple.java @@ -0,0 +1,67 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + + +/** + * 买家信息(CtBuyer)表实体类 导出excel模板 + * @author zhw + * @since 2022-07-18 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtBuyerExportTemple { + + @ExcelExport(value = "昵称") + /** 昵称*/ + private String nickName; + /** 账号*/ + @ExcelExport(value = "账号") + private String account; + /** 密码*/ + @ExcelExport(value = "密码") + private String pwd; + /** 公司名称 */ + @ExcelExport(value = "公司名称") + private String companyName; + /** 平台名称 */ + @ExcelExport(value = "平台名称") + private String platformName; + /** 国家 */ + @ExcelExport(value = "所属国家") + private String contntryShort; + /** VPN_IP地址*/ + @ExcelExport(value = "VPN_IP地址") + private String vpnIp; + /** 信用卡卡号 */ + @ExcelExport(value = "信用卡卡号") + private String cardNumber; + /** 地址1 */ + @ExcelExport(value = "地址1") + private String addressline1; + /** 国家 */ + @ExcelExport(value = "国家") + private String country; + /** 州 */ + @ExcelExport(value = "州") + private String state; + /** 电话 */ + @ExcelExport(value = "电话") + private String tel; + /** lastname */ + @ExcelExport(value = "lastname") + private String lastname; + /** 城市 */ + @ExcelExport(value = "城市") + private String city; + /** firstname */ + @ExcelExport(value = "firstname") + private String firstname; + /** 邮政编码 */ + @ExcelExport(value = "邮政编码") + private String postalcode; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerImport.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerImport.java new file mode 100644 index 0000000..742bbdb --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtBuyerImport.java @@ -0,0 +1,84 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelImport; + +/** + * Buyer信息(CtBuyer)表实体类 Import + * + * @author zhw + * @since 2022-07-14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtBuyerImport { + + private int rowNum; + private String rowTips; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + @ExcelImport(value = "昵称", required = true) + /** 昵称*/ + private String nickName; + /** 账号*/ + @ExcelImport(value = "账号", required = true, unique = true) + private String account; + /** 密码*/ + @ExcelImport(value = "密码", required = true) + private String pwd; + /** 公司名称 */ + @ExcelImport(value = "公司名称", required = true) + private String companyName; + /** 平台名称 */ + @ExcelImport(value = "平台名称", required = true) + private String platformName; + /** 国家 */ + @ExcelImport(value = "所属国家", required = true) + private String contntryShort; + /** VPN_IP地址*/ + @ExcelImport(value = "VPN_IP地址", required = true) + private String vpnIp; + /** 信用卡卡号 */ + @ExcelImport(value = "信用卡卡号") + private String cardNumber; + /** 地址1 */ + @ExcelImport(value = "地址1", required = true) + private String addressline1; + /** 国家 */ + @ExcelImport(value = "国家", required = true) + private String country; + /** 州 */ + @ExcelImport(value = "州", required = true) + private String state; + /** 电话 */ + @ExcelImport(value = "电话", required = true) + private String tel; + /** lastname */ + @ExcelImport(value = "lastname", required = true) + private String lastname; + /** 城市 */ + @ExcelImport(value = "城市", required = true) + private String city; + /** firstname */ + @ExcelImport(value = "firstname", required = true) + private String firstname; + /** 邮政编码 */ + @ExcelImport(value = "邮政编码", required = true) + private String postalcode; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtCard.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtCard.java new file mode 100644 index 0000000..777745f --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtCard.java @@ -0,0 +1,80 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 信用卡信息(CtCard)表实体类 + * + * @author rch + * @since 2022-07-07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtCard extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 父ID */ + private Long parentId; + /** 卡号 */ + private String number; +// /** PIN码 */ +// private String pinNumber; + /** 持卡人姓氏 */ + private String holderSurname; + /** 持卡人名称 */ + private String holderName; + /** 有效期 */ + private String termOfValidity; + /** 余额 */ + private BigDecimal balance; + /** 累计消费 */ + private BigDecimal sumConsume; + /** 开卡日期 */ + private Date openDate; + /** 所属国家 */ + private String contntryShort; + /** 信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡 */ + private Integer type; + /** 所属厂商:1.AmzKeys 2.Airwallex */ + private Integer cardDealer; + /** 身份证号 */ + private String idNumber; + /** 省份 */ + private String province; + /** 城市 */ + private String country; + /** 地址 */ + private String address; + /** 手机号 */ + private String phone; + /** 邮箱 */ + private String email; + /** 登陆账号 */ + private String account; + /** 密码 */ + private String pwd; + /** 状态:1.正常、2.异常、3.已删除 */ + private Integer status; + /** 备注 */ + private String remarks; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtCardExport.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtCardExport.java new file mode 100644 index 0000000..7ed9aae --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtCardExport.java @@ -0,0 +1,40 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + +/** + * 信用卡信息(CtCard)表实体类 导出对象信息 + * + * @author rch + * @since 2022-07-07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtCardExport extends Model { + /** 卡号 */ + @ExcelExport(value = "卡号") + private String number; +// /** PIN码 */ +// @ExcelExport(value = "PIN码") +// private String pinNumber; + /** 有效期 */ + @ExcelExport(value = "有效期") + private String termOfValidity; + /** 信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡 */ + @ExcelExport(value = "信用卡类型", kv = "1-Payoneer;2-万事达虚拟卡;3-Visa信用卡") + private Integer type; + /** 所属厂商:1.AmzKeys 2.Airwallex */ + @ExcelExport(value = "所属厂商", kv = "1-AmzKeys;2-Airwallex") + private Integer cardDealer; + /** 状态:1.正常、2.异常、3.已删除 */ + @ExcelExport(value = "状态", kv = "1-正常;2-异常;3-已删除") + private Integer status; + /** 异常信息 */ + @ExcelExport(value = "异常信息") + private String error; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtCardExportTemple.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtCardExportTemple.java new file mode 100644 index 0000000..45d23c8 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtCardExportTemple.java @@ -0,0 +1,46 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + +/** + * 信用卡信息(CtCard)表实体类 导出模版对象信息 + * + * @author rch + * @since 2022-07-07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtCardExportTemple extends Model { + /** 卡号 */ + @ExcelExport(value = "卡号") + private String number; + /** PIN码 */ +// @ExcelExport(value = "PIN码") +// private String pinNumber; + /** 密码 */ + @ExcelExport(value = "密码") + private String pwd; + /** 有效期 */ + @ExcelExport(value = "有效期(文本:yyyy-MM-dd)") + private String termOfValidity; + /** 信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡 */ + @ExcelExport(value = "信用卡类型", kv = "1-Payoneer;2-万事达虚拟卡;3-Visa信用卡") + private Integer type; + /** 所属厂商:1.AmzKeys 2.Airwallex */ + @ExcelExport(value = "所属厂商", kv = "1-AmzKeys;2-Airwallex") + private Integer cardDealer; + /** 状态:1.正常、2.异常、3.已删除 */ + @ExcelExport(value = "状态", kv = "1-正常;2-异常;3-已删除") + private Integer status; + /** 持卡人姓氏 */ + @ExcelExport(value = "持卡人姓氏") + private String holderSurname; + /** 持卡人名称 */ + @ExcelExport(value = "持卡人名称") + private String holderName; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtCardImport.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtCardImport.java new file mode 100644 index 0000000..16f2235 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtCardImport.java @@ -0,0 +1,96 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelImport; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 信用卡信息(CtCard)表实体类 Import + * + * @author rch + * @since 2022-07-07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtCardImport extends Model { + + /** Excel 行号 */ + private int rowNum; + + /** Excel 错误提示 */ + private String rowTips; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 父ID */ + private Long parentId; + /** 卡号 */ + @ExcelImport(value = "卡号", required = true, unique = true) + private String number; +// /** PIN码 */ +// @ExcelImport(value = "PIN码", required = true, unique = true) +// private String pinNumber; + /** 持卡人姓氏 */ + @ExcelImport(value = "持卡人姓氏") + private String holderSurname; + /** 持卡人名称 */ + @ExcelImport(value = "持卡人名称") + private String holderName; + /** 有效期 */ + @ExcelImport(value = "有效期(文本:yyyy-MM-dd)", required = true) + private String termOfValidity; + /** 余额 */ + private BigDecimal balance; + /** 累计消费 */ + private BigDecimal sumConsume; + /** 开卡日期 */ + private Date openDate; + /** 所属国家 */ + private String contntryShort; + /** 信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡 */ + @ExcelImport(value = "信用卡类型", kv = "1-Payoneer;2-万事达虚拟卡;3-Visa信用卡", required = true) + private Integer type; + /** 所属厂商:1.AmzKeys 2.Airwallex */ + @ExcelImport(value = "所属厂商", kv = "1-AmzKeys;2-Airwallex", required = true) + private Integer cardDealer; + /** 身份证号 */ + private String idNumber; + /** 省份 */ + private String province; + /** 城市 */ + private String country; + /** 地址 */ + private String address; + /** 手机号 */ + private String phone; + /** 邮箱 */ + private String email; + /** 登陆账号 */ + private String account; + /** 密码 */ + @ExcelImport(value = "密码") + private String pwd; + /** 状态:1.正常、2.异常、3.已删除 */ + @ExcelImport(value = "状态", kv = "1-正常;2-异常;3-已删除", required = true) + private Integer status; + /** 备注 */ + private String remarks; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtCardInfo.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtCardInfo.java new file mode 100644 index 0000000..70d4443 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtCardInfo.java @@ -0,0 +1,22 @@ +package me.zhengjie.entity; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Card(CtCard)表实体类 + * + * @author zhw + * @since 2022-07-14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtCardInfo { + /** id */ + private Long id; + /** 信用卡卡号 */ + private String number; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmSupplyMentYdParams.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmSupplyMentYdParams.java new file mode 100644 index 0000000..e700dee --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmSupplyMentYdParams.java @@ -0,0 +1,41 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 刷单补录 + * + * @author rch + * @since 2022-08-16 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickFarmSupplyMentYdParams { + + private Long id; + /** 刷单类型 */ + private Integer paramsType; + /** 国家 */ + private String country; + /** 账号 */ + private String account; + /** 密码 */ + private String pwd; + /** vpn分享链接 */ + private String vpnShare; + + /** item */ + private String item; + /** 有效期 */ + private String termOfValidity; + /** 信用卡持卡人名称 */ + private String cardName; + /** 信用卡卡号 */ + private String cardNumber; + /** 信用卡密码 */ + private String cardPwd; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmYdParams.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmYdParams.java new file mode 100644 index 0000000..489e5b1 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmYdParams.java @@ -0,0 +1,59 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; + +/** + * 刷单信息 影刀参数 + * + * @author rch + * @since 2022-08-16 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickFarmYdParams { + + private Long id; + /** 刷单类型 */ + private Integer paramsType; + /** 国家 */ + private String country; + /** 账号 */ + private String account; + /** 密码 */ + private String pwd; + /** 关键词 */ + private String keyWord; + /** 数量 */ + private Integer number; + /** 规格 */ + private String specification; + /** 颜色 */ + private String color; + /** item */ + private String item; + private String exchange; + /** 最小价格区间 */ + private String sectionMin; + /** 最大价格区间 */ + private String sectionMax; + /** vpn分享链接 */ + private String vpnShare; + /** 链接 */ + private String link; + /** 留言 */ + private String amessage; + /** 有效期 */ + private String termOfValidity; + /** 信用卡持卡人名称 */ + private String cardName; + /** 信用卡卡号 */ + private String cardNumber; + /** 信用卡密码 */ + private String cardPwd; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarming.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarming.java new file mode 100644 index 0000000..e46c75a --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarming.java @@ -0,0 +1,70 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 刷单Excel信息(CtClickFarming)表实体类 + * + * @author rch + * @since 2022-08-16 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickFarming extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 关联刷单订单ID */ + private Long ctClickOrderId; + /** 买家id */ + private Long buyerId; + /** 刷单类型 */ + private Integer paramsType; + /** 店铺名称 */ + private String shopName; + /** 关键词 */ + private String keyWord; + /** 标题 */ + private String title; + /** 链接 */ + private String link; + /** 数量 */ + private Integer number; + /** 规格 */ + private String specification; + /** 颜色 */ + private String color; + /** item */ + private String item; + /** 优惠劵 */ + private String exchange; + /** 最小价格区间 */ + private String sectionMin; + /** 最大价格区间 */ + private String sectionMax; + /** 执行结果 */ + private String response; + /** 支付订单ID */ + private String payOrderId; + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + private Integer status; + /** 留言 */ + private String amessage; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmingExport.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmingExport.java new file mode 100644 index 0000000..d26f1cf --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmingExport.java @@ -0,0 +1,59 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; +import me.zhengjie.utils.excel.ExcelImport; + +/** + * 刷单信息信息(CtCard)表实体类 Import + * + * @author rch + * @since 2022-08-16 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickFarmingExport { + /** 国家 */ + @ExcelExport(value = "国家") + private String country; + /** 账号 */ + @ExcelExport(value = "账号") + private String account; + /** 密码 */ + @ExcelExport(value = "密码") + private String pwd; + /** 店铺名称 */ + @ExcelExport(value = "店铺名称") + private String shopName; + /** 关键词 */ + @ExcelExport(value = "关键词") + private String keyWord; + /** 标题 */ + @ExcelExport(value = "标题") + private String title; + /** 链接 */ + @ExcelExport(value = "链接") + private String link; + /** 数量 */ + @ExcelExport(value = "数量") + private Integer number; + /** 规格 */ + @ExcelExport(value = "规格") + private String specification; + /** 颜色 */ + @ExcelExport(value = "颜色") + private String color; + /** item */ + @ExcelExport(value = "item") + private String item; + /** vpn分享链接 */ + @ExcelExport(value = "vpn分享链接") + private String vpnShare; + /** 异常信息 */ + @ExcelExport(value = "异常信息") + private String error; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmingExportTemp.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmingExportTemp.java new file mode 100644 index 0000000..2f3d623 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmingExportTemp.java @@ -0,0 +1,53 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + +/** + * 刷单信息信息(CtCard)表实体类 Import + * + * @author rch + * @since 2022-08-16 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickFarmingExportTemp { + /** 账号 */ + @ExcelExport(value = "账号") + private String account; + /** 商品属性类型:1.关键词 2.链接 */ + @ExcelExport(value = "商品属性类型", kv = "1-关键词;2-链接") + private Integer paramsType; + /** 店铺名称 */ + @ExcelExport(value = "店铺名称") + private String shopName; + /** 关键词 */ + @ExcelExport(value = "关键词") + private String keyWord; + /** 标题 */ + @ExcelExport(value = "标题") + private String title; + /** 链接 */ + @ExcelExport(value = "链接") + private String link; + /** 数量 */ + @ExcelExport(value = "数量") + private Integer number; + /** 规格 */ + @ExcelExport(value = "规格") + private String specification; + /** 颜色 */ + @ExcelExport(value = "颜色") + private String color; + @ExcelExport(value = "优惠卷") + private String exchange; + /** 商品item */ + @ExcelExport(value = "商品item") + private String item; + /** 留言 */ + @ExcelExport(value = "留言") + private String amessage; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmingImport.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmingImport.java new file mode 100644 index 0000000..2144533 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmingImport.java @@ -0,0 +1,64 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelImport; + +/** + * 刷单信息信息(CtCard)表实体类 Import + * + * @author rch + * @since 2022-08-16 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickFarmingImport { + + /** Excel 行号 */ + private int rowNum; + + /** Excel 错误提示 */ + private String rowTips; + + /** 买家id */ + private Long buyerId; + + /** 账号 */ + @ExcelImport(value = "账号", required = true, unique = true) + private String account; + /** 商品属性类型:1.关键词 2.链接 */ + @ExcelImport(value = "商品属性类型", kv = "1-关键词; 2-链接") + private Integer paramsType; + /** 店铺名称 */ + @ExcelImport(value = "店铺名称") + private String shopName; + /** 关键词 */ + @ExcelImport(value = "关键词") + private String keyWord; + /** 标题 */ + @ExcelImport(value = "标题") + private String title; + /** 链接 */ + @ExcelImport(value = "链接") + private String link; + /** 数量 */ + @ExcelImport(value = "数量") + private Integer number; + /** 规格 */ + @ExcelImport(value = "规格") + private String specification; + /** 颜色 */ + @ExcelImport(value = "颜色") + private String color; + /** item */ + @ExcelImport(value = "商品item") + private String item; + /** 优惠劵 */ + @ExcelImport(value = "优惠卷") + private String exchange; + /** 留言 */ + @ExcelImport(value = "留言", required = true) + private String amessage; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmingOrderInfo.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmingOrderInfo.java new file mode 100644 index 0000000..280ca9c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickFarmingOrderInfo.java @@ -0,0 +1,37 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 刷单订单信息详情(刷单信息+订单信息) + * + * @author rch + * @since 2022-08-16 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickFarmingOrderInfo { + + private Long id; + /** 国家 */ + private String country; + /** 账号 */ + private String account; + /** 密码 */ + private String pwd; + /** vpn分享链接 */ + private String vpnShare; + + /** 订单id */ + private String orderId; + /** 评论 */ + private String comment; + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + private Integer status; + /** 图片地址 */ + private String paths; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrder.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrder.java new file mode 100644 index 0000000..9e1ed52 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrder.java @@ -0,0 +1,55 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 刷单-订单信息(CtClickOrder)表实体类 + * + * @author rch + * @since 2022-09-14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickOrder extends Model { + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + /** 公司ID */ + private Long companyId; + /** 类型 1.导入 2.刷单*/ + private Integer type; + /** 总金额 */ + private String amount; + /** 状态描述 */ + private String paymentResults; + /** 店铺名称 */ + private String shop; + /** 购买数量 */ + private String pricesNumber; + /** 订单id */ + private String orderId; + /** 商品名称 */ + private String shopName; + /** 时间 */ + private String orderDate; + /** 评论 */ + private String comment; + /** 图片地址 */ + private String paths; + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + private Integer status; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrderExport.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrderExport.java new file mode 100644 index 0000000..3e2935e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrderExport.java @@ -0,0 +1,37 @@ +package me.zhengjie.entity; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + +/** + * 刷单订单实体类 导出模版对象信息 + * + * @author rch + * @since 2022-09-27 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickOrderExport { + + /** 公司名称 */ + @ExcelExport(value = "公司名称") + private String companyName; + /** 总金额 */ + @ExcelExport(value = "总金额") + private String amount; + /** 店铺名称 */ + @ExcelExport(value = "店铺名称") + private String shop; + /** 订单id */ + @ExcelExport(value = "订单id") + private String orderId; + /** 评论 */ + @ExcelExport(value = "评论") + private String comment; + @ExcelExport(value = "异常信息") + private String error; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrderExportTemple.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrderExportTemple.java new file mode 100644 index 0000000..49e25f7 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrderExportTemple.java @@ -0,0 +1,39 @@ +package me.zhengjie.entity; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; +import me.zhengjie.utils.excel.ExcelImport; + +/** + * 刷单订单实体类 导出模版对象信息 + * + * @author rch + * @since 2022-09-27 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickOrderExportTemple { + + /** 平台名称 */ + @ExcelExport(value = "平台名称") + private Integer platformId; + /** 公司名称 */ + @ExcelExport(value = "公司名称") + private Long companyId; + /** 总金额 */ + @ExcelExport(value = "总金额") + private String amount; + /** 店铺名称 */ + @ExcelExport(value = "店铺名称") + private String shop; + /** 订单id */ + @ExcelExport(value = "订单id") + private String orderId; + /** 评论 */ + @ExcelExport(value = "评论") + private String comment; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrderImport.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrderImport.java new file mode 100644 index 0000000..a4695dc --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrderImport.java @@ -0,0 +1,40 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; +import me.zhengjie.utils.excel.ExcelImport; + +/** + * Vpn信息(CtVpn)表实体类 Import + * + * @author rch + * @since 2022-09-27 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickOrderImport { + private int rowNum; + + private String rowTips; + + /** 公司ID */ + private Long companyId; + /** 公司名称 */ + @ExcelImport(value = "公司名称", required = true) + private String companyName; + /** 总金额 */ + @ExcelImport(value = "总金额", required = true) + private String amount; + /** 店铺名称 */ + @ExcelImport(value = "店铺名称", required = true) + private String shop; + /** 订单id */ + @ExcelImport(value = "订单id", required = true) + private String orderId; + /** 评论 */ + @ExcelImport(value = "评论") + private String comment; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrderYdParams.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrderYdParams.java new file mode 100644 index 0000000..9a1b5e6 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtClickOrderYdParams.java @@ -0,0 +1,33 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 刷单订单影刀参数 + * + * @author rch + * @since 2022-10-21 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickOrderYdParams { + private Long id; + /** 国家 */ + private String country; + /** 账号 */ + private String account; + /** 密码 */ + private String pwd; + /** vpn分享链接 */ + private String vpnShare; + /** 订单id */ + private String orderId; + /** 评论 */ + private String comment; + /** 图片 */ + private String paths; + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtCompany.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtCompany.java new file mode 100644 index 0000000..eff48bf --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtCompany.java @@ -0,0 +1,43 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 公司信息(CtCompany)表实体类 + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtCompany extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + /** 名称 */ + private String name; + /** 地址 */ + private String address; + /** 电话 */ + private String phone; + /** 商户码(公司调用api公司唯一标识) */ + private String number; + /** 商户token(公司调用api公司token身份标识) */ + private String token; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtCompanyInfo.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtCompanyInfo.java new file mode 100644 index 0000000..de0f007 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtCompanyInfo.java @@ -0,0 +1,23 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 公司信息(CtCompany)表实体类 + * + * @author zhw + * @since 2022-07-14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtCompanyInfo { + + /** id */ + private Long id; + /** 名称 */ + private String name; + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtDhPay.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtDhPay.java new file mode 100644 index 0000000..222896e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtDhPay.java @@ -0,0 +1,44 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 平台信息(CtDyPay)表实体类 + * + * @author rch + * @since 2022-07-28 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtDhPay extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 买家名称 */ + private String buyerName; + /** 支付订单ID(敦煌的) */ + private String orderId; + /** 请求响应详情 */ + private String response; + /** 状态 0.待处理 1.支付成功 2.支付失败 */ + private Integer status; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtDhPayExport.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtDhPayExport.java new file mode 100644 index 0000000..3586977 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtDhPayExport.java @@ -0,0 +1,29 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + +/** + * 敦煌支付信息(CtDhPay)表实体类 Export + * + * @author rch + * @since 2022-07-28 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtDhPayExport extends Model { + /** 买家名称 */ + @ExcelExport(value = "买家账号") + private String buyerName; + /** 支付订单ID(敦煌的) */ + @ExcelExport(value = "支付订单") + private String orderId; + + /** 异常信息 */ + @ExcelExport(value = "异常信息") + private String error; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtDhPayExportTemple.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtDhPayExportTemple.java new file mode 100644 index 0000000..4f5614e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtDhPayExportTemple.java @@ -0,0 +1,25 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + +/** + * 敦煌支付信息(CtDhPay)表实体类 导出模版对象信息 + * + * @author rch + * @since 2022-07-28 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtDhPayExportTemple extends Model { + /** 买家名称 */ + @ExcelExport(value = "买家账号") + private String buyerName; + /** 支付订单ID(敦煌的) */ + @ExcelExport(value = "支付订单") + private String orderId; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtDhPayImport.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtDhPayImport.java new file mode 100644 index 0000000..863019c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtDhPayImport.java @@ -0,0 +1,40 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelImport; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 敦煌支付信息(CtDhPay)表实体类 Import + * + * @author rch + * @since 2022-07-28 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtDhPayImport{ + + /** Excel 行号 */ + private int rowNum; + + /** Excel 错误提示 */ + private String rowTips; + + /** 买家名称 */ + @ExcelImport(value = "买家账号", required = true, unique = true) + private String buyerName; + + /** 支付订单ID(敦煌的) */ + @ExcelImport(value = "支付订单", required = true, unique = true) + private String orderId; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtExcel.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtExcel.java new file mode 100644 index 0000000..4c9bef7 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtExcel.java @@ -0,0 +1,41 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Excel 导入信息(CtExcel)表实体类 + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtExcel extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 备注 */ + private String remarks; + /** excel路径 */ + + private String path; + private String errorPath; + /** 状态 1.待导入 2.导入成功 3.导入失败 */ + private Integer status; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtExcelExportInfo.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtExcelExportInfo.java new file mode 100644 index 0000000..f9954c3 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtExcelExportInfo.java @@ -0,0 +1,40 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + +/** + * Excel 导出信息(CtExcelImportInfo)表实体类 + * + * @author rch + * @since 2022-07-18 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtExcelExportInfo extends Model { + + /** 公司主键 */ + @ExcelExport("公司主键") + private Long companyId; + + /** 鉴权枚举 */ + @ExcelExport("鉴权枚举") + private Long tokenEnum; + + /** 订单来源 */ + @ExcelExport("订单来源") + private String fromDetailInfo; + + /** 产品信息-JSON */ + @ExcelExport("产品信息") + private String cartList; + + /** 异常信息 */ + @ExcelExport(value = "异常信息") + private String error; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtExcelExportTemple.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtExcelExportTemple.java new file mode 100644 index 0000000..cd9499b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtExcelExportTemple.java @@ -0,0 +1,33 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + +/** + * EXCEL(CtExcel)表实体类 导出excel模板 + * @author zhw + * @since 2022-07-18 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtExcelExportTemple { + + /** 公司主键 */ + @ExcelExport("公司主键") + private Long companyId; + + /** 鉴权枚举 */ + @ExcelExport("鉴权枚举") + private Long tokenEnum; + + /** 订单来源 */ + @ExcelExport("订单来源") + private String fromDetailInfo; + + /** 产品信息-JSON */ + @ExcelExport("产品信息") + private String cartList; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtExcelImportInfo.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtExcelImportInfo.java new file mode 100644 index 0000000..153b8ca --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtExcelImportInfo.java @@ -0,0 +1,59 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelImport; + +/** + * Excel导入信息(CtExcelImportInfo)表实体类 + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtExcelImportInfo extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 公司主键 */ + @ExcelImport("公司主键") + private Long companyId; + + /** 鉴权枚举 */ + @ExcelImport("鉴权枚举") + private Long tokenEnum; + + /** 订单来源 */ + @ExcelImport("订单来源") + private String fromDetailInfo; + + /** 产品信息-JSON */ + @ExcelImport("产品信息") + private String cartList; + + /** 订单收货地址-JSON */ + private String contactInfo; + + /** 我们平台订单编号 */ + private String orderNo; + + /** 状态 1.待处理 2.处理成功 3.处理失败 */ + private Integer status; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtOrder.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtOrder.java new file mode 100644 index 0000000..8117c8b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtOrder.java @@ -0,0 +1,55 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * (CtOrder)表实体类 + * + * @author rch + * @since 2022-06-30 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtOrder extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + + /** 公司Id */ + private Long companyId; + /** ExcelId 信息 */ + private Long excelInfoId; + /** 买家ID */ + private Long buyerId; + /** 买家buy_access_token */ + private String buyAccessToken; + /** 我们平台订单编号 */ + private String ctOrderNo; + /** 订单号,下单成功响应的订单号(冗余字段 下单成功响应订单信息里有) */ + private Long orderNo; + /** 下单成功响应的产品id( a,b,c 格式) (响应字段很多,先少些几个) */ + private Long responseProductId; + /** 下单成功响应的订单地址id(响应字段很多,先少些几个) */ + private Long responseOrderAddressId; + /** 下单成功响应的订单信息 (响应字段很多,先少些几个) */ + private Long responseOrderId; + /** 响应码信息 */ + private String orderResponseStatus; + /** 响应码信息 */ + private String payResponseStatus; + /** 状态 1.待支付(下单成功) 2.支付成功 3.支付失败*/ + private Integer status; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtParamContactInfo.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtParamContactInfo.java new file mode 100644 index 0000000..2feb27c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtParamContactInfo.java @@ -0,0 +1,39 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 下单API请求参数订单收货地址信息 + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtParamContactInfo { + /** 必须 所在国家; 示例值:US 所在国家 */ + private String country; + /** 必须 收货人lastname ;示例值:zhao 收货人firstname */ + private String firstname; + /** 必须 收货人联系电话,固定电话或者移动电话 ;示例值:1311111111 收货人联系电话,固定电话或者移动电话 */ + private String tel; + /** 否 收货人地址1 ;示例值:chengfulu road, hawio 收货人地址2 */ + private String addressline2; + /** 必须 所在州 ;示例值:California 所在州 */ + private String state; + /** 必须 所在城市; 示例值:Chicago 所在城市 */ + private String city; + /** 必须 收货人地址1 ;示例值:chengfulu road, hawio 收货人地址1 */ + private String addressline1; + /** 必须 地址邮编 ;示例值:12345 地址邮编 */ + private String postalcode; + /** 必须 收货人lastname ;示例值:yiyi 收货人lastname */ + private String lastname; + /** 否 税号:BR,AR,EC,AO,LB,TR,KR必填 税号 */ + private String vatNumber; + /** 否 Email地址 ;示例值:zhaoyiyi@163.com Email地址 */ + private String email; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtParamProduct.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtParamProduct.java new file mode 100644 index 0000000..0a8a937 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtParamProduct.java @@ -0,0 +1,29 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 下单Api请求产品信息参数实体类 + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtParamProduct { + /** 必须 产品购买数量 示例值:2 产品数量 */ + private Integer quantity; + /** 否 可以从获取商品运费详情API获取expressType字段(分销API>物流API>dh.dropshipping.ship.get$1.0);示例值:ePacket 物流方式 */ + private String shipType; + /** 否 可根据国家字典查询国家详情(dh.base.countrys.get$1.0); 示例值:CN;默认值:CN 备货国家ID */ + private String stockin; + /** 否 站点 站点 */ + private String siteId; + /** 必须 产品itemcode ;示例值:634706114 产品编码 */ + private Long itemcode; + /** 必须 产品skuMd5,可以从商品详情API获取(分析API>商品API>dh.dropshipping.item.get$1.0) ;示例值:562e86410bd37a7bb4170cfe6e03203f 产品skuMd5 */ + private String skuMd5; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtPlatform.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtPlatform.java new file mode 100644 index 0000000..81ba872 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtPlatform.java @@ -0,0 +1,40 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 平台信息(CtPlatform)表实体类 + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtPlatform extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 名称 */ + private String name; + /** 地址 */ + private String address; + /** 电话 */ + private String phone; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtRebot.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtRebot.java new file mode 100644 index 0000000..9c6371d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtRebot.java @@ -0,0 +1,41 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 影刀设备-机器人信息(CtRebot)表实体类 + * + * @author rch + * @since 2022-07-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtRebot extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 机器人账号 */ + private String accountName; + /** 机器人Uuid信息 */ + private String robotClientUuid; + /** 状态 0.未占用 1.占用 */ + private Integer status; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtRebotExport.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtRebotExport.java new file mode 100644 index 0000000..c486f3b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtRebotExport.java @@ -0,0 +1,31 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; +import me.zhengjie.utils.excel.ExcelImport; + +/** + * 影刀机器人信息(ct_rebot) 导出 + * + * @Author zhw + * @Date 2022-07-25 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtRebotExport { + /** 机器人账号 */ + @ExcelExport(value = "机器人账号") + private String accountName; + /** 机器人Uuid信息 */ + @ExcelExport(value = "Uuid信息") + private String robotClientUuid; + @ExcelExport(value = "异常信息") + private String error; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtRebotExportTemple.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtRebotExportTemple.java new file mode 100644 index 0000000..d7c80f7 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtRebotExportTemple.java @@ -0,0 +1,24 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + +/** + * 机器人模板EXCEL导出(ct_rebot) + * + * @Author zhw + * @Date 2022-07-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtRebotExportTemple { + /** 机器人账号 */ + @ExcelExport(value = "机器人账号") + private String accountName; + /** 机器人Uuid信息 */ + @ExcelExport(value = "Uuid信息") + private String robotClientUuid; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtRebotImport.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtRebotImport.java new file mode 100644 index 0000000..54fe190 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtRebotImport.java @@ -0,0 +1,43 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelImport; + +/** + * 影刀机器人信息(ct_rebot) import + * + * @Author zhw + * @Date 2022-07-25 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtRebotImport { + + private int romNum; + private String rowTips; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 机器人账号 */ + @ExcelImport(value = "机器人账号", required = true) + private String accountName; + /** 机器人Uuid信息 */ + @ExcelImport(value = "Uuid信息", required = true) + private String robotClientUuid; + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtResponseOrder.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtResponseOrder.java new file mode 100644 index 0000000..9d2e35f --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtResponseOrder.java @@ -0,0 +1,67 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 下单成功响应订单商品信息(CtResponseOrder)表实体类 + * + * @author rch + * @since 2022-06-30 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtResponseOrder extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 运费 */ + private Double shipCost; + /** 产品总价 */ + private Double totalPriceOfProduct; + /** 备货期 */ + private Double leadingTime; + /** 订单总价 */ + private Double orderTotal; + /** 卖家Id */ + private String supplierId; + /** 卖家店铺coupon */ + private Double couponOfSeller; + /** 运输方式 */ + private String shipType; + /** 订单优惠 */ + private Double orderSave; + /** 税费手续费 */ + private Double taxCharge; + /** 买家Id */ + private String buyerId; + /** 税费 */ + private Double tax; + /** 促销折扣 */ + private Double promoDiscount; + /** 订单号--这个要特殊处理这个是对应响应的id字段 */ + private Long orderId; + /** DHcoupon */ + private Double couponDiscount; + /** 下单站点 */ + private String siteId; + /** 创建时间 */ + private Date createTime; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtResponseOrderAddress.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtResponseOrderAddress.java new file mode 100644 index 0000000..cfecf60 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtResponseOrderAddress.java @@ -0,0 +1,53 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 下注成功订单响应收货地址信息(CtResponseOrderAddress)表实体类 + * + * @author rch + * @since 2022-06-30 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtResponseOrderAddress extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 地址1 */ + private String addressline1; + /** 国家 */ + private String country; + /** 州 */ + private String state; + /** 电话 */ + private String tel; + /** lastname */ + private String lastname; + /** 税号 */ + private String vatNumber; + /** 城市 */ + private String city; + /** 地址2 */ + private String addressline2; + /** firstname */ + private String firstname; + /** 邮政编码 */ + private String postalcode; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtResponseOrderProduct.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtResponseOrderProduct.java new file mode 100644 index 0000000..9682b76 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtResponseOrderProduct.java @@ -0,0 +1,96 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 下单订单响应产品信息(CtResponseOrderProduct)表实体类 + * + * @author rch + * @since 2022-06-30 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtResponseOrderProduct extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 秒杀类型 */ + private String flashDeals; + /** 卖家设置价格 */ + private Double prodPriceOrg; + /** 产品skuId */ + private String skuId; + /** 购买数量 */ + private Integer cateDispId; + /** 商品总金额 */ + private Double amount; + /** 发布类目id */ + private String catePubId; + /** 促销折扣 */ + private Double promDis; + /** 产品单位名称 */ + private String measureName; + /** 短描 */ + private String shortDescription; + /** 卖家承诺运达天数 */ + private Integer promiseDays; + /** 备货国家 */ + private String stockin; + /** 产品图片(小图) */ + private String thumbnailImage; + /** 是否为样品 */ + private String isSample; + /** 最终运费 */ + private Double shipCost; + /** 卖家Id */ + private String supplierId; + /** 跨店满减金额 */ + private BigDecimal crossReduceAmount; + /** 产品itemcode */ + private Integer itemcode; + /** buyer选择的运输方式 */ + private String shipType; + /** 销售价格 */ + private Double originPrice; + /** 产品长描地址 */ + private String htmlUrl; + /** 产品图片(大图) */ + private String imageUrl; + /** 最终价格 */ + private Double price; + /** 产品URL */ + private String productUrl; + /** 备注 */ + private String remark; + /** lots */ + private Integer lots; + /** 产品名称 */ + private String productName; + /** 产品Id */ + private String productId; + /** 产品skumd5 */ + private String skuMd5; + /** 创建时间 */ + private Date createTime; + /** 产品单位Id */ + private String measureId; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtSettingSite.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtSettingSite.java new file mode 100644 index 0000000..a2209ea --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtSettingSite.java @@ -0,0 +1,43 @@ +package me.zhengjie.entity; + + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 站点配置(CtSettingSite)表实体类 + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtSettingSite extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 设置KEY */ + private String settingKey; + /** 设置value */ + private String settingValue; + /** 中文描述 */ + private String content; + /** 单位 */ + private String unit; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtVpn.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtVpn.java new file mode 100644 index 0000000..7e613ab --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtVpn.java @@ -0,0 +1,55 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * VPN信息表(CtVpn)表实体类 + * + * @author rch + * @since 2022-07-07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtVpn extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 所属国家简称 */ + private String contntryShort; + /** IP地址 */ + private String ipAddress; + /** 父ip地址 */ + private String parentIpAddress; + /** 端口 */ + private Integer port; + /** 名称 */ + private String name; + /** 密码 */ + private String pwd; + /** VPS类型 1.传统 */ + private Integer vpsType; + /** 经销商 1.V2 */ + private Integer dealer; + /** mac地址 */ + private String mac; + /** 链接 */ + private String link; + /** 经销商 1.可用 2.禁用 */ + private Integer status; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtVpnExport.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtVpnExport.java new file mode 100644 index 0000000..cff274d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtVpnExport.java @@ -0,0 +1,45 @@ +package me.zhengjie.entity; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + +/** + * Vpn信息(CtCard)表实体类 export + * + * @author zhw + * @since 2022-07-13 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtVpnExport { + + /** 所属国家简称 */ + @ExcelExport(value = "所属国家简称") + private String contntryShort; + /** IP地址 */ + @ExcelExport(value = "IP地址") + private String ipAddress; + @ExcelExport(value = "端口") + private Integer port; + /** 名称 */ + @ExcelExport(value = "名称") + private String name; + /** 密码 */ + @ExcelExport(value = "密码") + private String pwd; + /** VPS类型 1.传统 */ + @ExcelExport(value = "VPS类型", kv = "1-传统") + private Integer vpsType; + /** 经销商 1.V2 */ + @ExcelExport(value = "经销商", kv = "1-V2") + private Integer dealer; + @ExcelExport(value = "链接") + private String link; + @ExcelExport(value = "异常信息") + private String error; + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtVpnExportTemple.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtVpnExportTemple.java new file mode 100644 index 0000000..1e3bca1 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtVpnExportTemple.java @@ -0,0 +1,43 @@ +package me.zhengjie.entity; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + +/** + * Vpn信息(CtVpn)表实体类 导出模版对象信息 + * + * @author zhw + * @since 2022-07-13 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtVpnExportTemple { + + /** 所属国家简称 */ + @ExcelExport(value = "所属国家简称", example = "中国") + private String contntryShort; + /** IP地址 */ + @ExcelExport(value = "IP地址", example = "192.0.0.1") + private String ipAddress; + @ExcelExport(value = "端口", example = "8088") + private Integer port; + /** 名称 */ + @ExcelExport(value = "名称", example = "示例") + private String name; + /** 密码 */ + @ExcelExport(value = "密码", example = "123123") + private String pwd; + /** VPS类型 1.传统 */ + @ExcelExport(value = "VPS类型", kv = "1-传统", example = "传统") + private Integer vpsType; + @ExcelExport(value = "链接", example = "vmess://ew0KICAidiI6ICIyIiwNCiAgInBzIjogIjEwNC4yMjEuMTk5LjgyIiwNCiAgImFkZCI6ICJ1cy1lczM0LmZvYmhlbHAuY29tIiwNCiAgInBvcnQiOiAiMzAwNDMiLA0KICAiaWQiOiAiYzA4NDk5ODQtZWNjNC01MzY3LTlmOTctYTI2ODljNTQ5N2QyIiwNCiAgImFpZCI6ICI2NCIsDQogICJzY3kiOiAiYXV0byIsDQogICJuZXQiOiAidGNwIiwNCiAgInR5cGUiOiAibm9uZSIsDQogICJob3N0IjogIiIsDQogICJwYXRoIjogIiIsDQogICJ0bHMiOiAiIiwNCiAgInNuaSI6ICIiDQp9") + private String link; + /** 经销商 1.V2 */ + @ExcelExport(value = "经销商", kv = "1-V2", example = "V2") + private Integer dealer; + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtVpnImport.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtVpnImport.java new file mode 100644 index 0000000..e1cb352 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtVpnImport.java @@ -0,0 +1,66 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelImport; + +/** + * Vpn信息(CtVpn)表实体类 Import + * + * @author zhw + * @since 2022-07-13 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtVpnImport { + private int rowNum; + + private String rowTips; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 所属国家简称 */ + @ExcelImport(value = "所属国家简称", required = true) + private String contntryShort; + /** IP地址 */ + @ExcelImport(value = "IP地址", required = true, unique = true) + private String ipAddress; + /** 父ip地址 */ + private String parentIpAddress; + /** 端口 */ + @ExcelImport(value = "端口", required = true) + private Integer port; + /** 名称 */ + @ExcelImport(value = "名称", required = true) + private String name; + /** 密码 */ + @ExcelImport(value = "密码", required = true) + private String pwd; + /** VPS类型 1.传统 */ + @ExcelImport(value = "VPS类型", kv = "1-传统", required = true) + private Integer vpsType; + /** 经销商 1.V2 */ + @ExcelImport(value = "经销商", kv = "1-V2", required = true) + private Integer dealer; + /** mac地址 */ + private String mac; + /** 链接 */ + @ExcelImport(value = "链接", required = true, maxLength = 2000) + private String link; + /** 状态 1.可用 2.禁用 */ + private Integer status; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/CtVpnInfo.java b/wjcy-common/src/main/java/me/zhengjie/entity/CtVpnInfo.java new file mode 100644 index 0000000..2fd174b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/CtVpnInfo.java @@ -0,0 +1,23 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + + +/** + * Vpn(CtVpn)表实体类 + * + * @author zhw + * @since 2022-07-14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtVpnInfo { + + /** id */ + private Long id; + /** Ip地址 */ + private String ipAddress; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/DhAddCar.java b/wjcy-common/src/main/java/me/zhengjie/entity/DhAddCar.java new file mode 100644 index 0000000..a0e2c3c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/DhAddCar.java @@ -0,0 +1,48 @@ +package me.zhengjie.entity; + +import java.util.Date; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 敦煌加入购物车(DhAddCar)表实体类 + * + * @author rch + * @since 2022-11-17 09:11:54 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DhAddCar extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 买家ID */ + private Long buyerId; + /** 商品属性类型:1.关键词 2.链接 */ + private Integer paramsType; + /** 加购物车商品ids */ + private String carGoodIds; + /** 执行结果 */ + private String response; + /** 状态 1.待执行 2.执行中 3.加购成功 4.加购失败 5.下单成功 6.支付成功 7.抓单成功 8.抓单失败 */ + private Integer status; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/DhAddCarOrder.java b/wjcy-common/src/main/java/me/zhengjie/entity/DhAddCarOrder.java new file mode 100644 index 0000000..6c656d4 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/DhAddCarOrder.java @@ -0,0 +1,55 @@ +package me.zhengjie.entity; + +import java.util.Date; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 敦煌-加购物车-订单(DhAddCarOrder)表实体类 + * + * @author rch + * @since 2022-11-17 09:11:58 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DhAddCarOrder extends Model { + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 1.导入 2.刷单 */ + private Integer type; + /** 关联敦煌加购的id */ + private Long addCarId; +// /** 关联敦煌加购的ids */ +// private Long addCarIds; + /** 总金额 */ + private String amount; + /** 状态描述 */ + private String paymentResults; + /** 店铺名称 */ + private String shop; + /** 订单id */ + private String orderId; + /** 时间 */ + private String orderDate; + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + private Integer status; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/DhCarGoods.java b/wjcy-common/src/main/java/me/zhengjie/entity/DhCarGoods.java new file mode 100644 index 0000000..e19bc32 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/DhCarGoods.java @@ -0,0 +1,62 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 敦煌-加入购物车商品信息(DhCarGoods)表实体类 + * + * @author makejava + * @since 2022-11-17 09:12:02 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DhCarGoods extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + /** 商品属性类型:1.关键词 2.链接 */ + private Integer paramsType; + /** 店铺名称 */ + private String shopName; + /** 关键词 */ + private String keyWord; + /** 标题 */ + private String title; + /** 链接 */ + private String link; + /** 数量 */ + private Integer number; + /** 规格 */ + private String specification; + /** 颜色 */ + private String color; + /** item */ + private String item; + /** 最小价格区间 */ + private String sectionMin; + /** 最大价格区间 */ + private String sectionMax; + /** 评论 */ + private String comment; + /** 图片url */ + private String paths; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/ExcelImportInfo.java b/wjcy-common/src/main/java/me/zhengjie/entity/ExcelImportInfo.java new file mode 100644 index 0000000..4090e67 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/ExcelImportInfo.java @@ -0,0 +1,38 @@ +//package me.zhengjie.entity; +// +//import lombok.AllArgsConstructor; +//import lombok.Data; +//import lombok.NoArgsConstructor; +//import me.zhengjie.utils.excel.ExcelImport; +// +///** +// * Excel导入信息实体类 +// * +// * @author rch +// * @create 2022-06-23 +// */ +//@Data +//@AllArgsConstructor +//@NoArgsConstructor +//public class ExcelImportInfo { +// /** 公司主键 */ +// @ExcelImport("公司主键") +// private Long companyId; +// +// /** 鉴权枚举 */ +// @ExcelImport("鉴权枚举") +// private Integer tokenEnum; +// +// /** 订单来源 */ +// @ExcelImport("订单来源") +// private String fromDetailInfo; +// +// /** 产品信息-JSON */ +// @ExcelImport("产品信息") +// private String cartList; +// +// /** 订单收货地址-JSON */ +// @ExcelImport("订单收货地址") +// private String contactInfo; +// +//} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/LoginIp.java b/wjcy-common/src/main/java/me/zhengjie/entity/LoginIp.java new file mode 100644 index 0000000..8a20668 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/LoginIp.java @@ -0,0 +1,39 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +/** + * (LoginIp)表实体类 + * + * @author rch + * @since 2022-06-23 + */ +@Data +public class LoginIp extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + @TableField(fill = FieldFill.INSERT) + private String createdAt; + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updatedAt; + + /** 开始IP */ + private String ipStart; + /** 结束IP */ + private String ipEnd; + /** 备注 */ + private String remark; + /** 有效截至时间 */ + private String vaildTime; + /** 操作账号 */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/QueryWrapperAndPage.java b/wjcy-common/src/main/java/me/zhengjie/entity/QueryWrapperAndPage.java new file mode 100644 index 0000000..48d8f52 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/QueryWrapperAndPage.java @@ -0,0 +1,15 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class QueryWrapperAndPage { + QueryWrapper queryWrapper; + Page page; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/ResultObj.java b/wjcy-common/src/main/java/me/zhengjie/entity/ResultObj.java new file mode 100644 index 0000000..21e6c83 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/ResultObj.java @@ -0,0 +1,20 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 影刀回调响应-resultObj + * + * @author rch + * @create 2022-08-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ResultObj { + private String name; + private String type; + private String value; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/ReturnObje.java b/wjcy-common/src/main/java/me/zhengjie/entity/ReturnObje.java new file mode 100644 index 0000000..46d863c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/ReturnObje.java @@ -0,0 +1,28 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 影刀回调返回值-ReturnObj + * + * @author rch + * @create 2022-08-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ReturnObje { + private String msg; + private List result; + private String jobUuid; + private String robotClientName; + private String robotName; + private String robotClientUuid; + private String startTime; + private String endTime; + private String status; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/SysQuartzJob.java b/wjcy-common/src/main/java/me/zhengjie/entity/SysQuartzJob.java new file mode 100644 index 0000000..cdab873 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/SysQuartzJob.java @@ -0,0 +1,70 @@ +package me.zhengjie.entity; + +import java.util.Date; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * 定时任务(SysQuartzJob)表实体类 + * + * @author rch + * @since 2022-07-20 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SysQuartzJob extends Model { + + public static final String JOB_KEY = "JOB_KEY"; + + @TableId(value = "job_id", type = IdType.AUTO) + private Long jobId; + + private String createTime; + private String updateTime; + /** 操作人账号*/ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String gmName; + + private Long taskNum; + /** 类型 1.普通 2.影刀 */ + private Integer type; + /** Spring Bean名称 */ + private String beanName; + /** cron 表达式 */ + private String cronExpression; + /** 状态:1暂停、0启用 */ + private Integer isPause; + /** 任务名称 */ + private String jobName; + /** 方法名称 */ + private String methodName; + /** 参数 */ + private String params; + /** 参数类型 */ + private Integer paramsType; + /** 备注 */ + private String description; + /** 负责人 */ + private String personInCharge; + /** 报警邮箱 */ + private String email; + /** 子任务ID */ + private String subTask; + /** 任务失败后是否暂停 */ + private Integer pauseAfterFailure; + /** 创建者 */ + private String createBy; + /** 更新者 */ + private String updateBy; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/SysQuartzLog.java b/wjcy-common/src/main/java/me/zhengjie/entity/SysQuartzLog.java new file mode 100644 index 0000000..3ed54bf --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/SysQuartzLog.java @@ -0,0 +1,58 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.sql.Timestamp; + +/** + * @author rch + * @date 2022-07-20 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SysQuartzLog extends Model { + + private Long logId; + /** bean名称 */ + private String beanName; + /** 方法名称 */ + private String methodName; + + /** 参数 */ + private String params; + + /** cron表达式 */ + private String cronExpression; + + /** 状态 */ + private Boolean isSuccess; + + /** 异常详情 */ + private String exceptionDetail; + + /** 执行耗时 */ + private Long time; + + /** 创建时间 */ + private Timestamp createTime; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/YdSign.java b/wjcy-common/src/main/java/me/zhengjie/entity/YdSign.java new file mode 100644 index 0000000..7e69897 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/YdSign.java @@ -0,0 +1,32 @@ +package me.zhengjie.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 影刀 鉴权 + * + * @author rch + * @since 2022-07-26 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YdSign extends Model { + + /** 时间戳 */ + private Long timestamp; + /** accessKeyId */ + private String accessKeyId; + /** accessKeySecret */ + private String accessKeySecret; + /** bodyMd5 */ + private String bodyMd5; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/YdStartReturn.java b/wjcy-common/src/main/java/me/zhengjie/entity/YdStartReturn.java new file mode 100644 index 0000000..abf9b72 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/YdStartReturn.java @@ -0,0 +1,24 @@ +package me.zhengjie.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 调用影刀启动任务响应信息 + * + * @author rch + * @create 2022-08-24 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class YdStartReturn { + private String code; + private Boolean success; + private TaskUuid data; +} + +class TaskUuid { + private String taskUuid; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/quartz/Boss.java b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/Boss.java new file mode 100644 index 0000000..b6cd0db --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/Boss.java @@ -0,0 +1,23 @@ +package me.zhengjie.entity.quartz; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 调用影刀json信息 + * + * @author rch + * @create 2022-08-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Boss { + private String accountName; + private String robotUuid; + private Long applyId; + private List params; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/quartz/DataInfo.java b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/DataInfo.java new file mode 100644 index 0000000..97d9a32 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/DataInfo.java @@ -0,0 +1,19 @@ +package me.zhengjie.entity.quartz; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 调用影刀响应子集信息 + * + * @author rch + * @create 2022-08-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DataInfo { + private String accessToken; + private String expiresIn; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryByUuid.java b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryByUuid.java new file mode 100644 index 0000000..f80e95d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryByUuid.java @@ -0,0 +1,18 @@ +package me.zhengjie.entity.quartz; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 根据影刀任务ID查询影刀任务执行信息 + * + * @author rch + * @create 2022-08-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class JobQueryByUuid { + private String jobUuid; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryByUuidData.java b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryByUuidData.java new file mode 100644 index 0000000..54bc9f6 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryByUuidData.java @@ -0,0 +1,28 @@ +package me.zhengjie.entity.quartz; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 根据影刀任务id 查询影刀任务详情信息 + * + * @author rch + * @create 2022-08-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class JobQueryByUuidData { + private JobQueryByUuidRobotParams robotParams; + private String jobUuid; + private String status; + private String statusName; + private String robotUuid; + private String robotName; + private String startTime; + private String endTime; + private String remark; + private String robotClientUuid; + private String robotClientName; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryByUuidReturn.java b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryByUuidReturn.java new file mode 100644 index 0000000..3217b49 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryByUuidReturn.java @@ -0,0 +1,93 @@ +package me.zhengjie.entity.quartz; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 根据影刀任务id 查询影刀任务详情信息 + * + * @author rch + * @create 2022-08-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class JobQueryByUuidReturn { + private String code; + private Boolean success; + private JobQueryByUuidData data; + + /** + * { + * "data": { + * "jobUuid": "e925cd35-6857-48ae-a4ef-40ceea975e50", + * "status": "error", + * "statusName": "异常", + * "robotUuid": "9107fa36-a6d0-4ac6-932f-8fcbb7deb89b", + * "robotName": "刷单系统", + * "startTime": "2022-09-09 15:14:32", + * "endTime": "2022-09-09 15:15:52", + * "remark": "【e925cd35-6857-48ae-a4ef-40ceea975e50】任务失败,在【1-2清空浏览器数据】中第1行:出错:The tab was closed.", + * "robotParams": { + * "inputs": [ + * { + * "name": "id", + * "value": "4", + * "type": "str" + * }, + * { + * "name": "country", + * "value": "Korea", + * "type": "str" + * }, + * { + * "name": "account", + * "value": "borislanphere553@gmail.com", + * "type": "str" + * }, + * { + * "name": "pwd", + * "value": "sdwjcy2021", + * "type": "str" + * }, + * { + * "name": "keyWord", + * "value": "neck electric massage", + * "type": "str" + * }, + * { + * "name": "number", + * "value": "10", + * "type": "str" + * }, + * { + * "name": "specification", + * "value": "type-c", + * "type": "str" + * }, + * { + * "name": "color", + * "value": "Full Function", + * "type": "str" + * }, + * { + * "name": "item", + * "value": "1005001346919788", + * "type": "str" + * }, + * { + * "name": "vpnShare", + * "value": "ew0KICAidiI6ICIyIiwNCiAgInBzIjogIjEwNC4yMjEuMTk5LjgyIiwNCiAgImFkZCI6ICJ1cy1lczM0LmZvYmhlbHAuY29tIiwNCiAgInBvcnQiOiAiMzAwNDMiLA0KICAiaWQiOiAiYzA4NDk5ODQtZWNjNC01MzY3LTlmOTctYTI2ODljNTQ5N2QyIiwNCiAgImFpZCI6ICI2NCIsDQogICJzY3kiOiAiYXV0byIsDQogICJuZXQiOiAidGNwIiwNCiAgInR5cGUiOiAibm9uZSIsDQogICJob3N0IjogIiIsDQogICJwYXRoIjogIiIsDQogICJ0bHMiOiAiIiwNCiAgInNuaSI6ICIiDQp9", + * "type": "str" + * } + * ] + * }, + * "robotClientUuid": "13d29cc7-3feb-46b5-a02c-66dced9dfeca", + * "robotClientName": "linbiaoyuan@vogocm" + * }, + * "code": 200, + * "success": true + * } + */ +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryByUuidRobotParams.java b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryByUuidRobotParams.java new file mode 100644 index 0000000..64c3501 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryByUuidRobotParams.java @@ -0,0 +1,22 @@ +package me.zhengjie.entity.quartz; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.entity.ResultObj; + +import java.util.List; + +/** + * 根据影刀任务id查询影刀 + * + * @author rch + * @create 2022-09-09 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class JobQueryByUuidRobotParams { + private List inputs; + private List outputs; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryReturnResult.java b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryReturnResult.java new file mode 100644 index 0000000..5958ca9 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/JobQueryReturnResult.java @@ -0,0 +1,22 @@ +package me.zhengjie.entity.quartz; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 根据影刀任务id 查询影刀任务详情信息 + * + * @author rch + * @create 2022-08-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class JobQueryReturnResult { + private String id; + private String status; + private String statusName; + private String code; + private Boolean success; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/quartz/Param.java b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/Param.java new file mode 100644 index 0000000..921efcd --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/Param.java @@ -0,0 +1,20 @@ +package me.zhengjie.entity.quartz; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 调用影刀真正入参信息 + * + * @author rch + * @create 2022-08-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Param { + private String name; + private String value; + private String type = "str"; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/quartz/Params.java b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/Params.java new file mode 100644 index 0000000..a5782be --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/Params.java @@ -0,0 +1,22 @@ +package me.zhengjie.entity.quartz; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 调用影刀json信息 params里的 params是一个跟业务相关的主建 + * + * @author rch + * @create 2022-08-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Params { + private String accountName; + private Long applyId; + private String params; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/quartz/RebotStatu.java b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/RebotStatu.java new file mode 100644 index 0000000..415baad --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/RebotStatu.java @@ -0,0 +1,19 @@ +package me.zhengjie.entity.quartz; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 机器人相应信息子集 + * + * @author rch + * @create 2022-08-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RebotStatu { + private String robotClientUuid; + private String accountName; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/quartz/RebotStatuInfo.java b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/RebotStatuInfo.java new file mode 100644 index 0000000..33f5e40 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/RebotStatuInfo.java @@ -0,0 +1,29 @@ +package me.zhengjie.entity.quartz; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 影刀机器人状态信息 + * + * @author rch + * @create 2022-08-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RebotStatuInfo { + /** 状态 connected:已连接 idle:空闲 running:运行中 allocated:已分配 abnormal:异常 offline:离线 */ + private String status; + /** 机器人客户端ip */ + private String clientIp; + /** 机器人uuid */ + private String robotClientUuid; + /** 机器人名称 */ + private String robotClientName; + /** 机器人备注 */ + private String description; + /** 运行备注 */ + private String remark; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/quartz/RebotStatuReturn.java b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/RebotStatuReturn.java new file mode 100644 index 0000000..20b7669 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/RebotStatuReturn.java @@ -0,0 +1,20 @@ +package me.zhengjie.entity.quartz; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 机器人相应信息 + * + * @author rch + * @create 2022-08-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RebotStatuReturn { + private String code; + private Boolean success; + private RebotStatuInfo data; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/quartz/SecreInfo.java b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/SecreInfo.java new file mode 100644 index 0000000..c835970 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/SecreInfo.java @@ -0,0 +1,21 @@ +package me.zhengjie.entity.quartz; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 调用影刀相应信息 + * + * @author rch + * @create 2022-08-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SecreInfo { + private String code; + private Boolean success; + private String requestId; + private DataInfo data; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/entity/quartz/StartYdReturnInfo.java b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/StartYdReturnInfo.java new file mode 100644 index 0000000..fffefe0 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/entity/quartz/StartYdReturnInfo.java @@ -0,0 +1,22 @@ +package me.zhengjie.entity.quartz; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 启动影刀任务响应信息 + * + * @author rch + * @create 2022-10-27 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class StartYdReturnInfo { + private String code; + private Boolean success; + private String requestId; + private String serverInstName; + private String msg; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/BuyerLevelEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/BuyerLevelEnum.java new file mode 100644 index 0000000..cb93bf3 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/BuyerLevelEnum.java @@ -0,0 +1,77 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 用户等级 1.普通 2.精品 3.压力 4.内部账号 + *

+ * + * @Author rch + * @Date 2022-07-18 + **/ +public enum BuyerLevelEnum implements IntegerEnum { + /** + * 用户等级 1.普通 2.精品 3.压力 4.内部账号 + */ + + GENERAL(1), + BOUTIQUR(2), + PRESSURE(3), + INNER_ACCOUNT(4); + + private final Integer value; + + private BuyerLevelEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static BuyerLevelEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (BuyerLevelEnum obj : EnumUtils.getEnumList(BuyerLevelEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/BuyerOccupyStatusEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/BuyerOccupyStatusEnum.java new file mode 100644 index 0000000..3c09adb --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/BuyerOccupyStatusEnum.java @@ -0,0 +1,75 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 占用状态 1.已占用 2.未占用 + *

+ * + * @Author rch + * @Date 2022-07-18 + **/ +public enum BuyerOccupyStatusEnum implements IntegerEnum { + /** + * 占用状态 1.已占用 2.未占用 + */ + + OCCUPIED(1), + UN_OCCUPIED(2); + + private final Integer value; + + private BuyerOccupyStatusEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static BuyerOccupyStatusEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (BuyerOccupyStatusEnum obj : EnumUtils.getEnumList(BuyerOccupyStatusEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/BuyerStatusEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/BuyerStatusEnum.java new file mode 100644 index 0000000..eb64052 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/BuyerStatusEnum.java @@ -0,0 +1,80 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 状态(导入默认正常) 1.待注册 2待验证 3.待完善 4.正常 5.异常 6.可用但已用 7.删除 + *

+ * + * @Author rch + * @Date 2022-06-23 + **/ +public enum BuyerStatusEnum implements IntegerEnum { + /** + * 状态(导入默认正常) 1.待注册 2待验证 3.待完善 4.正常 5.异常 6.可用但已用 7.删除', + */ + + TOBE_REGISTER(1), + TOBE_CHECKING(2), + TOBE_PERFECT(3), + NORMAL(4), + AB_NORMAL(5), + AVAILABLE_BUT_USED(6), + DEL(7); + + private final Integer value; + + private BuyerStatusEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static BuyerStatusEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (BuyerStatusEnum obj : EnumUtils.getEnumList(BuyerStatusEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/CardDealerTypeEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/CardDealerTypeEnum.java new file mode 100644 index 0000000..de8c646 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/CardDealerTypeEnum.java @@ -0,0 +1,75 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 信用卡所属厂商类型 枚举 + *

+ * + * @Author rch + * @Date 2022-07-09 + **/ +public enum CardDealerTypeEnum implements IntegerEnum { + /** + * 所属厂商:1.AmzKeys 2.Airwallex + */ + + AMZKEYS(1), + AIRWALLEX(2); + + private final Integer value; + + private CardDealerTypeEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static CardDealerTypeEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (CardDealerTypeEnum obj : EnumUtils.getEnumList(CardDealerTypeEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/CardStatusEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/CardStatusEnum.java new file mode 100644 index 0000000..7c2966e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/CardStatusEnum.java @@ -0,0 +1,76 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 信用卡类状态枚举 + *

+ * + * @Author rch + * @Date 2022-07-11 + **/ +public enum CardStatusEnum implements IntegerEnum { + /** + * 状态:1.正常、2.异常、3.已删除 + */ + + NORMAL(1), + AB_NORMAL(2), + DEL(3); + + private final Integer value; + + private CardStatusEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static CardStatusEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (CardStatusEnum obj : EnumUtils.getEnumList(CardStatusEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/CardTypeEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/CardTypeEnum.java new file mode 100644 index 0000000..24db1b5 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/CardTypeEnum.java @@ -0,0 +1,76 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 信用卡类型 枚举 + *

+ * + * @Author rch + * @Date 2022-07-09 + **/ +public enum CardTypeEnum implements IntegerEnum { + /** + * 信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡 + */ + + PAYONEER(1), + WSD_INVENTED(2), + VISA(3); + + private final Integer value; + + private CardTypeEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static CardTypeEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (CardTypeEnum obj : EnumUtils.getEnumList(CardTypeEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/ClickBrowseStatusEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/ClickBrowseStatusEnum.java new file mode 100644 index 0000000..650fd7d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/ClickBrowseStatusEnum.java @@ -0,0 +1,77 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 浏览好评状态枚举 + *

+ * + * @Author rch + * @Date 2022-11-07 + **/ +public enum ClickBrowseStatusEnum implements IntegerEnum { + /** + * 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 + */ + + TOBE_EXECUTION(1), + IN_EXECUTION(2), + EXECUTION_SUCCESS(3), + EXECUTION_FAILE(4); + + private final Integer value; + + private ClickBrowseStatusEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static ClickBrowseStatusEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (ClickBrowseStatusEnum obj : EnumUtils.getEnumList(ClickBrowseStatusEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/ClickFarmingStatusEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/ClickFarmingStatusEnum.java new file mode 100644 index 0000000..2f0ae99 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/ClickFarmingStatusEnum.java @@ -0,0 +1,79 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 刷单状态枚举 + *

+ * + * @Author rch + * @Date 2022-07-11 + **/ +public enum ClickFarmingStatusEnum implements IntegerEnum { + /** + * 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 5.待支付 6.支付成功异常 (加购比较特殊 判断是否有订单号, 执行成功没有订单号是加购物车成功,区分抓单成功) + */ + + TOBE_EXECUTION(1), + IN_EXECUTION(2), + EXECUTION_SUCCESS(3), + EXECUTION_FAILE(4), + AWAITING_PAYMENT(5), + PAY_OK_ERROR(6); + + private final Integer value; + + private ClickFarmingStatusEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static ClickFarmingStatusEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (ClickFarmingStatusEnum obj : EnumUtils.getEnumList(ClickFarmingStatusEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/ClickOrderStatusEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/ClickOrderStatusEnum.java new file mode 100644 index 0000000..5530634 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/ClickOrderStatusEnum.java @@ -0,0 +1,77 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 刷单订单状态枚举 + *

+ * + * @Author rch + * @Date 2022-07-11 + **/ +public enum ClickOrderStatusEnum implements IntegerEnum { + /** + * 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 + */ + + TOBE_EXECUTION(1), + IN_EXECUTION(2), + EXECUTION_SUCCESS(3), + EXECUTION_FAILE(4); + + private final Integer value; + + private ClickOrderStatusEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static ClickOrderStatusEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (ClickOrderStatusEnum obj : EnumUtils.getEnumList(ClickOrderStatusEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/CtReboteStatusEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/CtReboteStatusEnum.java new file mode 100644 index 0000000..a4e828b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/CtReboteStatusEnum.java @@ -0,0 +1,75 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 机器人 状态0.未占用 1.占用 + *

+ * + * @Author xxs + * @Date 2021/9/26 + **/ +public enum CtReboteStatusEnum implements IntegerEnum { + /** + * 状态0.未占用 1.占用 + */ + + UNOCCUPIED(0), + OCCUPY(1); + + private final Integer value; + + private CtReboteStatusEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static CtReboteStatusEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (CtReboteStatusEnum obj : EnumUtils.getEnumList(CtReboteStatusEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/DhAddCarStatusEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/DhAddCarStatusEnum.java new file mode 100644 index 0000000..9c7ed42 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/DhAddCarStatusEnum.java @@ -0,0 +1,82 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 敦煌加购状态枚举 + *

+ * + * @Author rch + * @Date 2022-07-11 + **/ +public enum DhAddCarStatusEnum implements IntegerEnum { + /** + * 状态 1.待执行 2.执行中 3.加购成功 4.加购失败 5.下单成功 6.待抓单 7.抓单中 8.抓单成功 9.抓单失败 + */ + + TOBE_EXECUTION(1), + IN_EXECUTION(2), + Add_CARD_SUCCESS(3), + ADD_CARD_FAILE(4), + ORDER_SUCCESS(5), + TO_BE_CATCH_ORDER(6), + CATCH_ORDER_ING(7), + CATCH_ORDER_SUCCESS(8), + CATCH_ORDER_FAILE(9); + + private final Integer value; + + private DhAddCarStatusEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static DhAddCarStatusEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (DhAddCarStatusEnum obj : EnumUtils.getEnumList(DhAddCarStatusEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/DhPayStatusEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/DhPayStatusEnum.java new file mode 100644 index 0000000..a232181 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/DhPayStatusEnum.java @@ -0,0 +1,77 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 敦煌支付状态枚举 + *

+ * + * @Author rch + * @Date 2022-07-28 + **/ +public enum DhPayStatusEnum implements IntegerEnum { + /** + * 状态 0.待处理 1.支付成功 2.支付失败 + */ + + TO_BE(0), + PAY_SUCCESS(1), + PAY_FAIL(2), + DEL(3); + + private final Integer value; + + private DhPayStatusEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static DhPayStatusEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (DhPayStatusEnum obj : EnumUtils.getEnumList(DhPayStatusEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/ExcelInfoRequestTypeEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/ExcelInfoRequestTypeEnum.java new file mode 100644 index 0000000..65a14d2 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/ExcelInfoRequestTypeEnum.java @@ -0,0 +1,75 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 请求类型:1.下单请求 2.支付请求 + *

+ * + * @Author rch + * @Date 2022-06-23 + **/ +public enum ExcelInfoRequestTypeEnum implements IntegerEnum { + /** + * 请求类型:1.下单请求 2.支付请求 + */ + + BUY_ORDER(1), + PAY_ORDER(2); + + private final Integer value; + + private ExcelInfoRequestTypeEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static ExcelInfoRequestTypeEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (ExcelInfoRequestTypeEnum obj : EnumUtils.getEnumList(ExcelInfoRequestTypeEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/ExcelStatusEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/ExcelStatusEnum.java new file mode 100644 index 0000000..9cdce5e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/ExcelStatusEnum.java @@ -0,0 +1,76 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 状态1.待导入 2.导入成功 3.导入失败 + *

+ * + * @Author rch + * @Date 2022-06-23 + **/ +public enum ExcelStatusEnum implements IntegerEnum { + /** + * 状态1.待导入 2.导入成功 3.导入失败 + */ + + TOBE(1), + SUCCESS(2), + FAILE(3); + + private final Integer value; + + private ExcelStatusEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static ExcelStatusEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (ExcelStatusEnum obj : EnumUtils.getEnumList(ExcelStatusEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/LanguageEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/LanguageEnum.java new file mode 100644 index 0000000..79ce4d8 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/LanguageEnum.java @@ -0,0 +1,38 @@ +package me.zhengjie.enums; + +/** + * 多语言枚举类 + * + * @author zeng + * @since 2021/08/24 10:08 + */ + +public enum LanguageEnum { + + ZH("简体中文"), + + EN("英文"), + + CW("繁体中文"), + ; + + private final String des; + + LanguageEnum(String des) { + this.des = des; + } + + public String getValue() { + return this.name().toLowerCase(); + } + + public static boolean isInclude(String language) { + for (LanguageEnum value : LanguageEnum.values()) { + if (value.getValue().equals(language)) { + return true; + } + } + return false; + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/OrderTypeEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/OrderTypeEnum.java new file mode 100644 index 0000000..238cda8 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/OrderTypeEnum.java @@ -0,0 +1,75 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 刷单订单类型枚举 + *

+ * + * @Author rch + * @Date 2022-10-24 + **/ +public enum OrderTypeEnum implements IntegerEnum { + /** + * 状态 1.导入 2.刷单 + */ + + IMPORT(1), + CLICK_FARMING(2); + + private final Integer value; + + private OrderTypeEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static OrderTypeEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (OrderTypeEnum obj : EnumUtils.getEnumList(OrderTypeEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/ParamsTypeEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/ParamsTypeEnum.java new file mode 100644 index 0000000..59a9f18 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/ParamsTypeEnum.java @@ -0,0 +1,75 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 参数类型类型 枚举 + *

+ * + * @Author rch + * @Date 2022-07-09 + **/ +public enum ParamsTypeEnum implements IntegerEnum { + /** + * 商品属性类型:1.关键词 2.链接 + */ + + KEY_WORD(1), + LINK(2); + + private final Integer value; + + private ParamsTypeEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static ParamsTypeEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (ParamsTypeEnum obj : EnumUtils.getEnumList(ParamsTypeEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/PlatTypeEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/PlatTypeEnum.java new file mode 100644 index 0000000..3b96ba6 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/PlatTypeEnum.java @@ -0,0 +1,92 @@ +package me.zhengjie.enums; + +import org.apache.commons.lang3.EnumUtils; + +import java.util.Arrays; + +/** + *

+ * 平台类型 1.敦煌 + *

+ * + * @Author rch + * @Date 2022-07-06 + **/ +public enum PlatTypeEnum { + + //平台类型 1.敦煌 + DH(1, "敦煌"), + SMT(2, "速卖通"), + MB(3, "马帮"); + + + private final Integer type; + private final String desc; + + private PlatTypeEnum(Integer type, String desc) { + this.type = type; + this.desc = desc; + } + + public static String getDescByType(Integer type) { + if (type == null) { + return ""; + } + PlatTypeEnum[] enumAry = PlatTypeEnum.values(); + for(int i = 0; i < Arrays.asList(enumAry).size(); i++){ + if (enumAry[i].getType().equals(type)) { + return enumAry[i].getDesc(); + } + } + return ""; + } + + public static Integer getValueByDesc(String desc) { + PlatTypeEnum[] enumAry = PlatTypeEnum.values(); + for (PlatTypeEnum currencyTypeEnum : enumAry) { + if (currencyTypeEnum.getDesc().equals(desc)) { + return currencyTypeEnum.getType(); + } + } + return null; + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static PlatTypeEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (PlatTypeEnum obj : EnumUtils.getEnumList(PlatTypeEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } + + /** + * 值相等 + * + * @param value + * @return + */ + public boolean eqValue(Integer value) { + if (value != null && type.equals(value)) { + return true; + } + return false; + } + + public Integer getType() { + return type; + } + + public String getDesc() { + return desc; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/RobotStatusEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/RobotStatusEnum.java new file mode 100644 index 0000000..adcaa1c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/RobotStatusEnum.java @@ -0,0 +1,77 @@ +package me.zhengjie.enums; + +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 机器人状态 枚举 + *

+ * + * @Author rch + * @Date 2022-07-09 + **/ +public enum RobotStatusEnum{ + /** + * 状态 connected:已连接 idle:空闲 running:运行中 allocated:已分配 abnormal:异常 offline:离线 + */ + + CONNECTED("connected"), + IDLE("idle"), + RUNNING("running"), + ALLOCATED("allocated"), + ABNORMAL("abnormal"), + OFFLINE("offline"); + + private final String value; + + private RobotStatusEnum(String value) { + this.value = value; + } + + + public String value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(String value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(String value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static RobotStatusEnum getEnum(String value) { + if (value == null) { + return null; + } + for (RobotStatusEnum obj : EnumUtils.getEnumList(RobotStatusEnum.class)) { + if (obj.value().equals(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/TaskInfoEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/TaskInfoEnum.java new file mode 100644 index 0000000..421bff1 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/TaskInfoEnum.java @@ -0,0 +1,54 @@ +package me.zhengjie.enums; + +import java.util.Arrays; + +/** + *

+ * Task 信息枚举 包含task基本信息 + *

+ * + * @Author rch + * @Date 2022-08-01 + **/ +public enum TaskInfoEnum { + + // 1.Demo-Task + BOSS_TASK("bossTask", "run"), + CLICK_FARMING("clickFarmTask", "run"), + CLICK_FARMING_SUPPLE_MENY("clickFarmSuppleMentTask", "run"), + WELL_RECEIVED("wellReceivedTask", "run"), + BROWSE("browseTask", "run"), + DH_ADD_CAR_FARMING("dhAddCarTask", "run"), + DH_ADD_CAR_CATCH_ORDER("dhCatchOrderTask", "run"), + DH_WELL_RECEIVED("dhWellReceivedTask", "run"); + + + private final String taskName; + private final String methodName; + + private TaskInfoEnum(String taskName, String methodName) { + this.taskName = taskName; + this.methodName = methodName; + } + + public static String getMethodNameByTaskName(String taskName) { + if (taskName == null) { + return ""; + } + TaskInfoEnum[] enumAry = TaskInfoEnum.values(); + for(int i = 0; i < Arrays.asList(enumAry).size(); i++){ + if (enumAry[i].getTaskName().equals(taskName)) { + return enumAry[i].getMethodName(); + } + } + return ""; + } + + public String getTaskName() { + return taskName; + } + + public String getMethodName() { + return methodName; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/TaskIsPauseEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/TaskIsPauseEnum.java new file mode 100644 index 0000000..440f9f0 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/TaskIsPauseEnum.java @@ -0,0 +1,75 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 状态 1.暂停 2.启用 + *

+ * + * @Author rch + * @Date 2022-10-06 + **/ +public enum TaskIsPauseEnum implements IntegerEnum { + /** + * 类型 1.暂停 0.启用 + */ + + IS_PAUSE(1), + NOT_PAUSE(0); + + private final Integer value; + + private TaskIsPauseEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static TaskIsPauseEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (TaskIsPauseEnum obj : EnumUtils.getEnumList(TaskIsPauseEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/TaskTypeEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/TaskTypeEnum.java new file mode 100644 index 0000000..6f25196 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/TaskTypeEnum.java @@ -0,0 +1,75 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * 类型 1.普通 2.影刀 + *

+ * + * @Author rch + * @Date 2022-07-20 + **/ +public enum TaskTypeEnum implements IntegerEnum { + /** + * 类型 1.普通 2.影刀 + */ + + ORDINARY(1), + SHADOW_KNIFE(2); + + private final Integer value; + + private TaskTypeEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static TaskTypeEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (TaskTypeEnum obj : EnumUtils.getEnumList(TaskTypeEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/VpnDealerEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/VpnDealerEnum.java new file mode 100644 index 0000000..b08953e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/VpnDealerEnum.java @@ -0,0 +1,74 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * VPN经销商枚举 + *

+ * + * @Author zhw + * @Date 2022-07-18 + **/ +public enum VpnDealerEnum implements IntegerEnum { + /** + * 状态:1.V2 + */ + + V2(1); + + private final Integer value; + + private VpnDealerEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static VpnDealerEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (VpnDealerEnum obj : EnumUtils.getEnumList(VpnDealerEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/VpnStatusEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/VpnStatusEnum.java new file mode 100644 index 0000000..b246388 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/VpnStatusEnum.java @@ -0,0 +1,75 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * VPN类状态枚举 + *

+ * + * @Author zhw + * @Date 2022-07-18 + **/ +public enum VpnStatusEnum implements IntegerEnum { + /** + * 状态:1.可用、2.禁用 + */ + + AVAILABLE(1), + DISABLED(2); + + private final Integer value; + + private VpnStatusEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static VpnStatusEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (VpnStatusEnum obj : EnumUtils.getEnumList(VpnStatusEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/VpnTypeEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/VpnTypeEnum.java new file mode 100644 index 0000000..b52d540 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/VpnTypeEnum.java @@ -0,0 +1,74 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * VPN类型枚举 + *

+ * + * @Author zhw + * @Date 2022-07-18 + **/ +public enum VpnTypeEnum implements IntegerEnum { + /** + * 状态:1.传统 + */ + + TRADITION(1); + + private final Integer value; + + private VpnTypeEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static VpnTypeEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (VpnTypeEnum obj : EnumUtils.getEnumList(VpnTypeEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/YesOrNoEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/YesOrNoEnum.java new file mode 100644 index 0000000..5b58315 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/YesOrNoEnum.java @@ -0,0 +1,75 @@ +package me.zhengjie.enums; + +import me.zhengjie.enums.interfaces.IntegerEnum; +import org.apache.commons.lang3.EnumUtils; + +/** + *

+ * Yes or No + *

+ * + * @Author xxs + * @Date 2021/9/26 + **/ +public enum YesOrNoEnum implements IntegerEnum { + /** + * 类型型(1.YES 0.NO ) + */ + + YES(1), + NO(0); + + private final Integer value; + + private YesOrNoEnum(Integer value) { + this.value = value; + } + + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static YesOrNoEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (YesOrNoEnum obj : EnumUtils.getEnumList(YesOrNoEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/interfaces/IntegerEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/interfaces/IntegerEnum.java new file mode 100644 index 0000000..f944411 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/interfaces/IntegerEnum.java @@ -0,0 +1,40 @@ +package me.zhengjie.enums.interfaces; + +/** + *

+ * Integer类型枚举 + *

+ * + * @Author xx + * @Date 2021/7/22 + **/ +public interface IntegerEnum { + + /**值 + * @return + */ + Integer value(); + + /** + * 值相等 + * + * @param value + * @return + */ + default boolean eqValue(Integer value) { + if (value != null && value().equals(value)) { + return true; + } + return false; + } + + /** + * 值不相等 + * + * @param value + * @return + */ + default boolean neValue(Integer value) { + return !eqValue(value); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/interfaces/LongEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/interfaces/LongEnum.java new file mode 100644 index 0000000..8b210fa --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/interfaces/LongEnum.java @@ -0,0 +1,40 @@ +package me.zhengjie.enums.interfaces; + +/** + *

+ * Long类型枚举 + *

+ * + * @Author xx + * @Date 2021/7/22 + **/ +public interface LongEnum { + + /**值 + * @return + */ + Long value(); + + /** + * 值相等 + * + * @param value + * @return + */ + default boolean eqValue(Long value) { + if (value != null && value().equals(value)) { + return true; + } + return false; + } + + /** + * 值不相等 + * + * @param value + * @return + */ + default boolean neValue(Long value) { + return !eqValue(value); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/enums/interfaces/MemberIsUsedEnum.java b/wjcy-common/src/main/java/me/zhengjie/enums/interfaces/MemberIsUsedEnum.java new file mode 100644 index 0000000..e5992be --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/enums/interfaces/MemberIsUsedEnum.java @@ -0,0 +1,71 @@ +package me.zhengjie.enums.interfaces; + +import org.apache.commons.lang3.EnumUtils; +/** + *

+ * 用户是否使用过 + *

+ * + * @Author xx + * @Date 2021/8/11 + **/ +public enum MemberIsUsedEnum implements IntegerEnum { + /** 未使用 */ + UN_USED(0), + /** 已使用*/ + IS_USED(1); + + private final Integer value; + + private MemberIsUsedEnum(Integer value) { + this.value = value; + } + + @Override + public Integer value() { + return this.value; + } + + /** + * 判断是否存在指定值 + * + * @param value + * @return + */ + public static boolean hasValue(Integer value) { + boolean hasVal = false; + if (getEnum(value) != null) { + hasVal = true; + } + return hasVal; + } + + /** + * 判断是否不存在指定值 + * + * @param value + * @return + */ + public static boolean notHasValue(Integer value) { + return !hasValue(value); + } + + /** + * 获取指定值对应的枚举 + * + * @param value + * @return + */ + public static MemberIsUsedEnum getEnum(Integer value) { + if (value == null) { + return null; + } + for (MemberIsUsedEnum obj : EnumUtils.getEnumList(MemberIsUsedEnum.class)) { + if (obj.eqValue(value)) { + return obj; + } + } + return null; + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/error/ErrorCodeEnum.java b/wjcy-common/src/main/java/me/zhengjie/error/ErrorCodeEnum.java new file mode 100644 index 0000000..834a36e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/error/ErrorCodeEnum.java @@ -0,0 +1,143 @@ +package me.zhengjie.error; + +import cn.hutool.core.convert.Convert; +import me.zhengjie.utils.PropertiesUtil; +import me.zhengjie.utils.RequestHolder; + +/** + *

+ * 返回错误枚举类型 + *

+ * + * @Author xx + * @Date 2021/7/19 + **/ +public enum ErrorCodeEnum { + RETURN_SUCCESS(200, "响应成功"), + UNKNOWN_ERROR(2000,"服务器开小差了....,请稍后再试!"), + BAD_CREDENTIALS(2001,"坏的凭证"), + ENTITY_EXIST(2003,"信息重复添加"), + ENTITY_NOT_FOUND(2004,"数据不存在"), + METHOD_ARGUMENT_NOT_VALID(2005,"数据验证失败异常"), + VALIDATION_ERROR(2006,"参数验证失败"), + HANDLE_BIND_ERROR(2007,"参数绑定失败"), + MESSAGE_NOT_READABLE(2008,"参数解析失败"), + MISSING_REQUEST_HEADER(2009,"缺少请求头参数"), + NO_HANDLER_FOUND(2010,"Not Found"), + METHOD_NOT_SUPPORTED(2011,"不支持当前请求方法"), + MEDIA_TYPE_NOT_SUPPORTED(2012,"不支持当前媒体类型"), + MAX_UPLOAD_SIZE_EXCEEDED(2013,"文件上传-文件大小超过限制"), + NO_PERMISSION_FOR_THIS_OPERATION(1328, "暂无权限"), + UPLOAD_IMG_FORMAT_ERROR(2015,"上传图片格式错误"), + REQUEST_PARAMS_NULL_ERROR(2016,"请求参数空值异常,请检查后重试!"), + SERVER_DESERTION_ERROR(2017,"服务器开小差了....,请稍后再试!"), + FORM_SUBMISSION_REPETITION_ERROR(1360, "操作过于频繁,请稍后再试"), + LOGIN_PWD_ERROR(2218, "密码错误!"), + BLOCKED_ACCOUNT_ERROR(2219, "多次输人错误的密码,账户已被冻结!"), + LOGIN_IP_FORMAT_ERROR(2220, "IP地址格式错误!"), + BLOCKED_LOGIN_IP_ERROR(2221, "非法IP!"), + ERROR_2222(2222, "验证码错误!"), + ERROR_2223(2223, "验证码不存在或已过期!"), + + // 业务 + // 买家 + ERROR_NOT_FIND_BUYER_USER(3000, "买家信息不存在!"), + ERROR_EXIST_FIND_BUYER_USER(3001, "买家信息已存在!"), + ERROR_NOT_UPDATE_EXIST_ORDER_BUYER_USER(3002, "买家存在订单信息,不允许修改token和平台信息"), + ERROR_NOT_DEL_EXIST_ORDER_BUYER_USER(3003, "买家存在订单信息,不允许删除"), + + + // EXCEL + ERROR_NOT_FIND_EXCEL_USER(3100, "卖家信息不存在!"), + + + // 平台 + ERROR_NOT_FIND_PLAT_USER(3200, "平台信息不存在!"), + ERROR_EXITS_COMPANY_INFO(3201,"该平台下存在公司,不允许删除!"), + + // 公司 + ERROR_NOT_FIND_COMPANY(3300, "公司信息不存在!"), + ERROR_EXITS_CT_ORDER_INFO(3201,"该公司下存在订单信息,不允许删除!"), + + // 信用卡 + ERROR_NOT_FIND_CARD_INFO(3300, "信用卡信息不存在,或者已删除或异常!"), + ERROR_NOT_FIND_CARD(3301, "信用卡信息不存在!"), + + //VPN + ERROR_NOT_FIND_VPN(3300, "VPN信息不存在,或者已删除!"), + + //影刀任务信息 + ERROR_NOT_FIND_JOB(3400,"影刀任务信息不存在,或者已删除"), + ERROR_NOT_FIND_TASK(3401,"影刀应用信息异常, 请检查后重试!"), + + //应用信息Apply + ERROR_NOT_FIND_APPLY(3500,"应用信息不存在,或者已删除"), + + //影刀机器人信息 rebot + ERROR_NOT_FIND_REBOT(3600,"机器人信息不存在,或者已删除"), + ERROR_NOT_FIND_OR_OCCUPY(3601, "机器人不存在,或者已占用"), + + // 影刀回调 + ERROR_PARAM_NULL(3700, "影刀回调参数空值异常!"), + ERROR_CALLBACK_SIGN_NULL(3701, "影刀回调鉴权异常!"), + + + // 敦煌支付 + ERROR_DH_PAY_NOT_FIND_OR_SUCCESS(3800,"敦煌支付信息不存在,或已删除!"), + + // 刷单流程 + ERROR_NOT_FIND_CLICKFARMING_INFO(3900, "刷单信息不存在!"), + ERROR_DEL_CLICKFARMING_INFO(3901, "只有待执行的刷单信息才允许删除!"), + ERROR_CLICKFARMING_NOT_TOBE(3902, "刷单信息非待执行状态,请检查后重新操作!"), + ERROR_CLICKFARMING_NOT_SUPPLEMENT(3903, "仅支付成功失败状态才允许补录!"), + ERROR_CLICK_ORDER_NOT_COMMENT(3904, "仅刷单成功状态,才拥有订单信息!"), + + // 订单信息 + ERROR_NOT_FIND_CLICK_ORDER_INFO(4100, "订单信息不存在"), + ERROR_NOT_NULL_ERP_AUTH_TOKEN(4101, "鉴权信息不能为空!"), + ERROR_ERP_AUTH_TOKEN(4102, "鉴权信息错误,请检查后重试!"), + + // 应用 + ERROR_NOT_REPEAT_ID(4200, "应用ID存在重复!"), + ERROR_NOT_FIND_METHOD_NAME(4201, "不存在对应方法名称!"), + + // 浏览信息不存在 + ERROR_NOT_FIND_BROWSE(4300, "浏览信息不存在!"), + + // 敦煌加购 + ERROR_ADD_CAR_KEY_NULL(4400, "关键词类型-商品关键词属性不能为空"), + ERROR_ADD_CAR_LINK_NULL(4401, "链接类型-商品关键词属性不能为空"), + ERROR_ADD_CAR_GOODS_NULL(4403, "商品属性不能为空"), + ERROR_NOT_FIND_ADD_CAR_INFO(4404, "敦煌加购信息不存在,或者已删除或异常!"), + ERROR_DEL_ADD_CAR_INFO(4405, "只有待执行的刷单信息才允许删除!"), + ERROR_NOT_EDIT_ADD_CAR_INFO(4406, "敦煌加购信息仅带执行才允许修改!"), + ERROR_NOT_WELL_RECEIVED_ADD_CAR_INFO(4407, "敦煌加购信息仅抓单成功才允许评论!"); + + private int code; + + private String desc; + /** 初始化 */ + ErrorCodeEnum(int code, String desc) { + this.code = code; + this.desc = desc; + } + /** 获取错误状态码 */ + public int getCode() { + return code; + } + /** 设置错误状态码 */ + public void setCode(int code) { + this.code = code; + } + /** 获取错误描述 */ + public String getDesc() { +// String language = RequestHolder.getLanguage(); +// String message = Convert.toStr(PropertiesUtil.getByCode(code, language), desc); + return desc; + } + /** 设置错误描述 */ + public void setDesc(String desc) { + this.desc = desc; + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/exception/BadConfigurationException.java b/wjcy-common/src/main/java/me/zhengjie/exception/BadConfigurationException.java new file mode 100644 index 0000000..ede3691 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/exception/BadConfigurationException.java @@ -0,0 +1,98 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.exception; + +/** + * 统一关于错误配置信息 异常 + * + * @author: liaojinlong + * @date: 2020/6/10 18:06 + */ +public class BadConfigurationException extends RuntimeException { + /** + * Constructs a new runtime exception with {@code null} as its + * detail message. The cause is not initialized, and may subsequently be + * initialized by a call to {@link #initCause}. + */ + public BadConfigurationException() { + super(); + } + + /** + * Constructs a new runtime exception with the specified detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public BadConfigurationException(String message) { + super(message); + } + + /** + * Constructs a new runtime exception with the specified detail message and + * cause.

Note that the detail message associated with + * {@code cause} is not automatically incorporated in + * this runtime exception's detail message. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public BadConfigurationException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new runtime exception with the specified cause and a + * detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). This constructor is useful for runtime exceptions + * that are little more than wrappers for other throwables. + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public BadConfigurationException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new runtime exception with the specified detail + * message, cause, suppression enabled or disabled, and writable + * stack trace enabled or disabled. + * + * @param message the detail message. + * @param cause the cause. (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @param enableSuppression whether or not suppression is enabled + * or disabled + * @param writableStackTrace whether or not the stack trace should + * be writable + * @since 1.7 + */ + protected BadConfigurationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/exception/BadRequestException.java b/wjcy-common/src/main/java/me/zhengjie/exception/BadRequestException.java new file mode 100644 index 0000000..3501adc --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/exception/BadRequestException.java @@ -0,0 +1,50 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.exception; + +import lombok.Getter; +import me.zhengjie.error.ErrorCodeEnum; +import org.springframework.http.HttpStatus; +import static org.springframework.http.HttpStatus.BAD_REQUEST; + +/** + * @author Zheng Jie + * @date 2018-11-23 + * 统一异常处理 + */ +@Getter +public class BadRequestException extends RuntimeException{ + + + private Integer status = BAD_REQUEST.value(); + + public BadRequestException(String msg){ + super(msg); + } + + public BadRequestException(HttpStatus status,String msg){ + super(msg); + this.status = status.value(); + } + public BadRequestException(Integer status,String msg){ + super(msg); + this.status = status; + } + public BadRequestException(ErrorCodeEnum errorCodeEnum){ + super(errorCodeEnum.getDesc()); + this.status = errorCodeEnum.getCode(); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/exception/EntityExistException.java b/wjcy-common/src/main/java/me/zhengjie/exception/EntityExistException.java new file mode 100644 index 0000000..03f9bf2 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/exception/EntityExistException.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.exception; + +import org.springframework.util.StringUtils; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +public class EntityExistException extends RuntimeException { + + public EntityExistException(Class clazz, String field, String val) { + super(EntityExistException.generateMessage(clazz.getSimpleName(), field, val)); + } + + private static String generateMessage(String entity, String field, String val) { + return StringUtils.capitalize(entity) + + " with " + field + " "+ val + " existed"; + } +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/exception/EntityNotFoundException.java b/wjcy-common/src/main/java/me/zhengjie/exception/EntityNotFoundException.java new file mode 100644 index 0000000..bcdc956 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/exception/EntityNotFoundException.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.exception; + +import org.springframework.util.StringUtils; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +public class EntityNotFoundException extends RuntimeException { + + public EntityNotFoundException(Class clazz, String field, String val) { + super(EntityNotFoundException.generateMessage(clazz.getSimpleName(), field, val)); + } + + private static String generateMessage(String entity, String field, String val) { + return StringUtils.capitalize(entity) + + " with " + field + " "+ val + " does not exist"; + } +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/exception/handler/ApiError.java b/wjcy-common/src/main/java/me/zhengjie/exception/handler/ApiError.java new file mode 100644 index 0000000..5112730 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/exception/handler/ApiError.java @@ -0,0 +1,52 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.exception.handler; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import java.time.LocalDateTime; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Data +class ApiError { + + private Integer status = 400; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime timestamp; + private String message; + + private ApiError() { + timestamp = LocalDateTime.now(); + } + + public static ApiError error(String message){ + ApiError apiError = new ApiError(); + apiError.setMessage(message); + return apiError; + } + + public static ApiError error(Integer status, String message){ + ApiError apiError = new ApiError(); + apiError.setStatus(status); + apiError.setMessage(message); + return apiError; + } +} + + diff --git a/wjcy-common/src/main/java/me/zhengjie/exception/handler/GlobalExceptionHandler.java b/wjcy-common/src/main/java/me/zhengjie/exception/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..4561bae --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/exception/handler/GlobalExceptionHandler.java @@ -0,0 +1,197 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.exception.handler; + +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.dto.Dto; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.exception.EntityExistException; +import me.zhengjie.exception.EntityNotFoundException; +import me.zhengjie.utils.ThrowableUtil; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.validation.BindException; +import org.springframework.validation.FieldError; +import org.springframework.validation.ObjectError; +import org.springframework.web.HttpMediaTypeNotSupportedException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingRequestHeaderException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.multipart.MaxUploadSizeExceededException; +import org.springframework.web.servlet.NoHandlerFoundException; + +import javax.annotation.Resource; +import javax.validation.ValidationException; +import java.util.List; + +import static me.zhengjie.error.ErrorCodeEnum.*; +import static me.zhengjie.error.ErrorCodeEnum.MAX_UPLOAD_SIZE_EXCEEDED; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + /** + * 不允许访问的异常 + */ + @ExceptionHandler(AccessDeniedException.class) + public Dto accessDeniedException(Throwable e) { + // 打印堆栈信息 + log.error(NO_PERMISSION_FOR_THIS_OPERATION.getCode()+ThrowableUtil.getStackTrace(e)); + return Dto.getInstance(NO_PERMISSION_FOR_THIS_OPERATION); + } + + /** + * 处理所有不可知的异常 + */ + @ExceptionHandler(Throwable.class) + public Dto handleException(Throwable e) { + // 打印堆栈信息 + log.error(UNKNOWN_ERROR.getCode()+ThrowableUtil.getStackTrace(e)); + return Dto.getInstance(UNKNOWN_ERROR); + } + + /** + * BadCredentialsException + */ + @ExceptionHandler(BadCredentialsException.class) + public Dto badCredentialsException(BadCredentialsException e) { + // 打印堆栈信息 + log.error(BAD_CREDENTIALS.getCode()+ThrowableUtil.getStackTrace(e)); + return Dto.getInstance(BAD_CREDENTIALS); + } + + /** + * 处理自定义异常 + */ + @ExceptionHandler(value = BadRequestException.class) + public Dto badRequestException(BadRequestException e) { + // 打印堆栈信息 + log.error(e.getStatus()+ThrowableUtil.getStackTrace(e)); + Dto dto = Dto.returnResult(false); + dto.setCode(e.getStatus()); + dto.setMessage(e.getMessage()); + return dto; + } + + /** + * 处理 EntityExist + */ + @ExceptionHandler(value = EntityExistException.class) + public Dto entityExistException(EntityExistException e) { + // 打印堆栈信息 + log.error(ENTITY_EXIST.getCode()+ThrowableUtil.getStackTrace(e)); + return Dto.getInstance(ENTITY_EXIST); + } + + /** + * 处理 EntityNotFound + */ + @ExceptionHandler(value = EntityNotFoundException.class) + public Dto entityNotFoundException(EntityNotFoundException e) { + // 打印堆栈信息 + log.error(ENTITY_NOT_FOUND.getCode()+ThrowableUtil.getStackTrace(e)); + return Dto.getInstance(ENTITY_NOT_FOUND); + } + + /** + * 处理所有接口数据验证异常 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public Dto handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { + // 打印堆栈信息 + log.error(ThrowableUtil.getStackTrace(e)); + StringBuffer sbf = new StringBuffer(); + List allErrors = e.getBindingResult().getAllErrors(); + for (ObjectError allError : allErrors) { + if (allError instanceof FieldError) { + FieldError fieldError = (FieldError)allError; + sbf.append("["+fieldError.getField() + ":" + fieldError.getDefaultMessage() + "] "); + } + } + Dto dto = Dto.getInstance(METHOD_ARGUMENT_NOT_VALID); + if (ObjectUtil.isNotEmpty(sbf)) { + dto.setMessage(sbf.toString()); + } + return dto; + } + + @ExceptionHandler(ValidationException.class) + @ResponseBody + public Dto handleValidationException(ValidationException e) { + log.error(VALIDATION_ERROR.getCode()+ThrowableUtil.getStackTrace(e)); + return Dto.getInstance(VALIDATION_ERROR); + } + + @ExceptionHandler(BindException.class) + @ResponseBody + public Dto handleBindException(BindException e) { + log.error(HANDLE_BIND_ERROR.getCode()+ThrowableUtil.getStackTrace(e)); + return Dto.getInstance(HANDLE_BIND_ERROR); + } + + @ExceptionHandler(HttpMessageNotReadableException.class) + @ResponseBody + public Dto handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { + log.error(MESSAGE_NOT_READABLE.getCode()+ThrowableUtil.getStackTrace(e)); + return Dto.getInstance(MESSAGE_NOT_READABLE); + } + + @ExceptionHandler(MissingRequestHeaderException.class) + @ResponseBody + public Dto missingRequestHeaderException(MissingRequestHeaderException e) { + log.error(MISSING_REQUEST_HEADER.getCode()+ThrowableUtil.getStackTrace(e)); + return Dto.getInstance(MISSING_REQUEST_HEADER); + } + + @ExceptionHandler(NoHandlerFoundException.class) + @ResponseBody + public Dto noHandlerFoundException(NoHandlerFoundException e) { + log.error(NO_HANDLER_FOUND.getCode()+ThrowableUtil.getStackTrace(e)); + return Dto.getInstance(NO_HANDLER_FOUND); + } + + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + @ResponseBody + public Dto handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) { + log.error(METHOD_NOT_SUPPORTED.getCode()+ThrowableUtil.getStackTrace(e)); + return Dto.getInstance(METHOD_NOT_SUPPORTED); + } + + @ExceptionHandler(HttpMediaTypeNotSupportedException.class) + @ResponseBody + public Dto handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e) { + log.error(MEDIA_TYPE_NOT_SUPPORTED.getCode()+ThrowableUtil.getStackTrace(e)); + return Dto.getInstance(MEDIA_TYPE_NOT_SUPPORTED); + } + + @ExceptionHandler(value = MaxUploadSizeExceededException.class) + @ResponseBody + public Dto maxUploadSizeExceededException(MaxUploadSizeExceededException e) { + log.error(MAX_UPLOAD_SIZE_EXCEEDED.getCode()+ThrowableUtil.getStackTrace(e)); + return Dto.getInstance(MAX_UPLOAD_SIZE_EXCEEDED); + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/mybatis/LambdaQueryWrapperImpl.java b/wjcy-common/src/main/java/me/zhengjie/mybatis/LambdaQueryWrapperImpl.java new file mode 100644 index 0000000..d1911cb --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/mybatis/LambdaQueryWrapperImpl.java @@ -0,0 +1,29 @@ +package me.zhengjie.mybatis; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; + +/* + * + * @Description + * @Date 2021/12/6 + * @Author zeng + */ +public class LambdaQueryWrapperImpl extends LambdaQueryWrapper { + + private String name; + + @Override + public String getCustomSqlSegment() { + String customSqlSegment = super.getCustomSqlSegment(); + if (ObjectUtil.isNotEmpty(name)) { + customSqlSegment = customSqlSegment.replaceAll("ew.", name + "."); + } + return customSqlSegment; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtApplyService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtApplyService.java new file mode 100644 index 0000000..c67a12d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtApplyService.java @@ -0,0 +1,42 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtApply; +import me.zhengjie.service.vo.CtApplyListVO; +import me.zhengjie.utils.PageUtils; + +import java.util.List; + +/** + * 影刀应用信息(CtApply)表服务接口 + * + * @author rch + * @since 2022-07-23 + */ +public interface CtApplyService extends IService { + + /** + * 分页查询 + * @param page + * @param ew + * @return PageUtils + */ + PageUtils searchPageList(IPage page, Wrapper ew); + + /** + * 查询所有应用信息 + * @return LIST + */ + List getAllApplyName(); + + /** + * 根据方法应用对应的TaskName和Method查询应用信息 + * @param taskName + * @param method + * @return + */ + CtApply getApplyByTaskAndMethod(String taskName, String method); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtBrowseService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtBrowseService.java new file mode 100644 index 0000000..b0b8401 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtBrowseService.java @@ -0,0 +1,41 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtBrowse; +import me.zhengjie.service.vo.CtBrowseDetailVO; +import me.zhengjie.service.vo.CtBrowseListVO; +import me.zhengjie.utils.PageUtils; + +/** + * 浏览收藏(CtBrowse)表服务接口 + * + * @author rch + * @since 2022-11-04 09:45:32 + */ +public interface CtBrowseService extends IService { + + /** + * 分页查询 + * @param page + * @param ew + * @return + */ + PageUtils searchPageList(IPage page, Wrapper ew); + + /** + * 获取好评刷单信息-加锁 + * @param id + * @return + */ + CtBrowse getByIdLock(Long id); + + /** + * 根据id获取详情 + * @param id + * @return + */ + CtBrowseDetailVO getBrowseDetailById(Long id); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtBuyerService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtBuyerService.java new file mode 100644 index 0000000..b6c71d9 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtBuyerService.java @@ -0,0 +1,50 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtBuyer; +import me.zhengjie.service.vo.CtBuyerDetailVO; +import me.zhengjie.service.vo.CtBuyerListVO; +import me.zhengjie.utils.PageUtils; + +import java.util.List; +import java.util.Map; + +/** + * 买家表(CtBuyer)表服务接口 + * + * @author rch + * @since 2022-06-22 + */ +public interface CtBuyerService extends IService { + + /** + * 分页查询买家信息 + * @param page + * @param ew + * @return + */ + PageUtils searchPageList(IPage page, Wrapper ew); + + /** + * 根据Id获取详情信息 + * @param id + * @return + */ + CtBuyerDetailVO getDetailById(Long id); + + List getAllAccount(); + + String getPwdByName(String name); + + CtBuyer getBuyerOccupyStatusLock(String buyerName); + + /** + * 根据买家账号 返回存在的买家信息 + * @param buyerAccountList + * @return + */ + Map getBuyerList(List buyerAccountList); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtCardService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtCardService.java new file mode 100644 index 0000000..6727e2e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtCardService.java @@ -0,0 +1,26 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtCard; +import me.zhengjie.entity.CtCardInfo; + +import java.util.List; + +/** + * 信用卡信息(CtCard)表服务接口 + * + * @author rch + * @since 2022-07-07 + */ +public interface CtCardService extends IService { + + List getNumberList(); + + /** + * 根据信用卡号查询信用卡信息 + * @param number + * @return ctCardInfo(id,number) + */ + List getCardInfoByNumber(List number); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtClickFarmingService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtClickFarmingService.java new file mode 100644 index 0000000..f88d31f --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtClickFarmingService.java @@ -0,0 +1,36 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtBuyerClickSuccess; +import me.zhengjie.entity.CtClickFarmYdParams; +import me.zhengjie.entity.CtClickFarming; +import me.zhengjie.service.vo.CtClickFarmEditDetailVO; +import me.zhengjie.service.vo.CtClickFarmingDetailVO; +import me.zhengjie.service.vo.CtClickFarmingVO; +import me.zhengjie.utils.PageUtils; + +import java.util.List; + +/** + * 刷单Excel信息(CtClickFarming)表服务接口 + * + * @author rch + * @since 2022-08-16 + */ +public interface CtClickFarmingService extends IService { + + PageUtils searchPageList(IPage page, Wrapper ew); + + CtClickFarming getByIdLock(Long id); + + CtClickFarmEditDetailVO getEditDetailById(Long id); + + CtClickFarmingDetailVO getDetailById(Long id); + + List ruleGetCtBuyer(String buyerAccount, String country, String shopName); + + CtClickFarmYdParams getCtClickFarmYdParams(Long valueOf); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtClickOrderService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtClickOrderService.java new file mode 100644 index 0000000..30b471c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtClickOrderService.java @@ -0,0 +1,65 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtClickFarmingOrderInfo; +import me.zhengjie.entity.CtClickOrder; +import me.zhengjie.service.vo.CtClickOrderDetailVO; +import me.zhengjie.service.vo.CtClickOrderListVO; +import me.zhengjie.utils.PageUtils; + +import java.util.List; + +/** + * 刷单-订单信息(CtClickOrder)表服务接口 + * + * @author rch + * @since 2022-09-14 + */ +public interface CtClickOrderService extends IService { + + /** + * 返回实际存在的订单id + * @param importOrderIdList + * @return + */ + List getOrderId(List importOrderIdList); + + /** + * 分页查询 + * @param page + * @param ew + * @return + */ + PageUtils searchPageList(IPage page, Wrapper ew); + + /** + * 手动补录刷单信息对应的订单信息 + * @param clickFarmingId + * @param ctClickOrder + */ + Boolean supplement(Long clickFarmingId, CtClickOrder ctClickOrder); + + /** + * 根据订单id 获取刷单订单详情信息 + * @param orderId + * @return + */ + CtClickFarmingOrderInfo getClickFarmOrderById(Long orderId); + + /** + * 悲观锁根据id获取刷单订单信息 + * @param valueOf + * @return + */ + CtClickOrder getByIdLock(Long valueOf); + + /** + * 根据订单Id获取订单详情 + * @param id + * @return + */ + CtClickOrderDetailVO getClickOrderDetailById(Long id); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtCompanyService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtCompanyService.java new file mode 100644 index 0000000..10d4c04 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtCompanyService.java @@ -0,0 +1,34 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtCompany; +import me.zhengjie.entity.CtCompanyInfo; + +import java.util.List; +import java.util.Map; + +/** + * 公司信息(CtCompany)表服务接口 + * + * @author makejava + * @since 2022-06-23 10:37:44 + */ +public interface CtCompanyService extends IService { + + /** + * 根据公司名字 获取公司信息 + * @param name + * @return + */ + List getByNmae(List name); + + List getCompanyList(); + + /** + * 根据名称返回存在的公司信息 Map形式 key:id value:公司名称 + * @param platNameList + * @return + */ + Map getNameList(List platNameList); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtDhPayService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtDhPayService.java new file mode 100644 index 0000000..22612f4 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtDhPayService.java @@ -0,0 +1,29 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtDhPay; +import me.zhengjie.service.vo.CtDhPayListVO; +import me.zhengjie.utils.PageUtils; + +/** + * 平台信息(CtDyPay)表服务接口 + * + * @author rch + * @since 2022-07-28 + */ +public interface CtDhPayService extends IService { + + PageUtils searchPageList(IPage page, Wrapper ew); + + void toPay(); + + /** + * 调用支付接口 + * @param ctDhPay + * @return + */ + public Boolean payOrderApi(CtDhPay ctDhPay); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtExcelImportInfoService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtExcelImportInfoService.java new file mode 100644 index 0000000..9f2ba5a --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtExcelImportInfoService.java @@ -0,0 +1,23 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtExcelImportInfo; + +import java.io.IOException; + +/** + * Excel导入信息(CtExcelImportInfo)表服务接口 + * + * @author rch + * @since 2022-06-23 + */ +public interface CtExcelImportInfoService extends IService { + + /** + * Excel 数据导入Mysql + * + * TODO 先做一版批量导入的,如果导入过程错误先不考虑 + */ + void importExcel() throws IOException; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtExcelService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtExcelService.java new file mode 100644 index 0000000..a3d470b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtExcelService.java @@ -0,0 +1,15 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtExcel; + +/** + * Excel 导入信息(CtExcel)表服务接口 + * + * @author makejava + * @since 2022-06-23 10:37:44 + */ +public interface CtExcelService extends IService { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtOrderService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtOrderService.java new file mode 100644 index 0000000..0bba1ec --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtOrderService.java @@ -0,0 +1,31 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtExcelImportInfo; +import me.zhengjie.entity.CtOrder; +import org.springframework.stereotype.Service; + +/** + * (CtOrder)表服务接口 + * + * @author rch + * @since 2022-07-01 + */ +@Service +public interface CtOrderService extends IService { + + /** + * Excel 数据转换存储到订单表里 Order 一对多 + */ + void excelToOrder(); + + Boolean buyOrderApi(CtExcelImportInfo ctExcelImportInfo); + + /** + * 订单支付 + */ + void toPay(); + + Boolean payOrderApi(CtOrder ctOrder); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtPlatformService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtPlatformService.java new file mode 100644 index 0000000..37611dd --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtPlatformService.java @@ -0,0 +1,24 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtPlatform; + +import java.util.List; +import java.util.Map; + +/** + * 平台信息(CtPlatform)表服务接口 + * + * @author makejava + * @since 2022-06-23 10:37:44 + */ +public interface CtPlatformService extends IService { + + /** + * 返回存在的对应名称的平台信息名称 + * @param platNameList + * @return + */ + Map getNameList(List platNameList); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtRebotService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtRebotService.java new file mode 100644 index 0000000..b784caf --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtRebotService.java @@ -0,0 +1,63 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtRebot; +import me.zhengjie.service.vo.CtRebotListVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.data.convert.JodaTimeConverters; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 影刀设备-机器人信息(CtRebot)表服务接口 + * + * @author rch + * @since 2022-07-23 + */ +public interface CtRebotService extends IService { + + CtRebot getByAccountNameLock(String accountName); + + /** + * 分页查询 影刀机器人信息 + * @param page + * @param wr + * @return PageUtils + */ + PageUtils searchPageList(IPage page, Wrapper wr); + + /** + * excel导入机器人信息 + * @param file + * @param response + * @return Dto + */ + Dto importRebot(MultipartFile file, HttpServletResponse response) throws Exception; + + /** + * 获取所有机器人名称 + * @return LIST + */ + List getAccountNameList(); + + /** + * 获取所有uuid信息 + * @return LIST + */ + List getClientUuidList(); + + /** + * 根据id和老状态 修改新状态 + * @param id + * @param newStatus + * @param oldStatus + * @return + */ + Boolean updateNewStatusByOldStatus(Long id, Integer newStatus, Integer oldStatus); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtResponseOrderAddressService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtResponseOrderAddressService.java new file mode 100644 index 0000000..c639064 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtResponseOrderAddressService.java @@ -0,0 +1,17 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtResponseOrderAddress; +import org.springframework.stereotype.Service; + +/** + * 下注成功订单响应收货地址信息(CtResponseOrderAddress)表服务接口 + * + * @author rch + * @since 2022-07-01 + */ +@Service +public interface CtResponseOrderAddressService extends IService { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtResponseOrderProductService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtResponseOrderProductService.java new file mode 100644 index 0000000..956fb20 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtResponseOrderProductService.java @@ -0,0 +1,17 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtResponseOrderProduct; +import org.springframework.stereotype.Service; + +/** + * 下单订单响应产品信息(CtResponseOrderProduct)表服务接口 + * + * @author rch + * @since 2022-07-01 + */ +@Service +public interface CtResponseOrderProductService extends IService { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtResponseOrderService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtResponseOrderService.java new file mode 100644 index 0000000..99d8a84 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtResponseOrderService.java @@ -0,0 +1,17 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtResponseOrder; +import org.springframework.stereotype.Service; + +/** + * 下单成功响应订单商品信息(CtResponseOrder)表服务接口 + * + * @author rch + * @since 2022-07-01 + */ +@Service +public interface CtResponseOrderService extends IService { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/CtVpnService.java b/wjcy-common/src/main/java/me/zhengjie/service/CtVpnService.java new file mode 100644 index 0000000..d4327c2 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/CtVpnService.java @@ -0,0 +1,24 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtVpn; +import me.zhengjie.entity.CtVpnInfo; + +import java.util.List; + +/** + * VPN信息表(CtVpn)表服务接口 + * + * @author rch + * @since 2022-07-07 + */ +public interface CtVpnService extends IService { + + List getIpList(); + + /** + * 根据ip地址查询vpn信息(id、ip地址) + */ + List getVpnInfoByIp(List ipAddress); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/DhAddCarOrderService.java b/wjcy-common/src/main/java/me/zhengjie/service/DhAddCarOrderService.java new file mode 100644 index 0000000..861fc33 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/DhAddCarOrderService.java @@ -0,0 +1,41 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.DhAddCarOrder; +import me.zhengjie.service.vo.dhcarorder.DhAddCarOrderListVO; +import me.zhengjie.service.vo.dhcarorder.DhCarOrderParamsVO; +import me.zhengjie.utils.PageUtils; + +/** + * 敦煌-加购物车-订单(DhAddCarOrder)表服务接口 + * + * @author rch + * @since 2022-11-17 09:11:59 + */ +public interface DhAddCarOrderService extends IService { + + /** + * 加锁获取敦煌购物车抓单信息 + * @param valueOf + * @return + */ + DhAddCarOrder getByIdLock(Long valueOf); + + /** + * 分页查询 + * @param page + * @param ew + * @return + */ + PageUtils searchPageList(IPage page, Wrapper ew); + + /** + * 获取敦煌加购-好评影刀参数 + * @param valueOf + * @return + */ + DhCarOrderParamsVO getYdParams(Long valueOf); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/DhAddCarService.java b/wjcy-common/src/main/java/me/zhengjie/service/DhAddCarService.java new file mode 100644 index 0000000..59c02b5 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/DhAddCarService.java @@ -0,0 +1,49 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.DhAddCar; +import me.zhengjie.service.vo.dhaddcar.DhAddCarVO; +import me.zhengjie.service.vo.dhaddcar.DhAddCarListVO; +import me.zhengjie.service.vo.dhaddcar.DhAddCarYdParamsVO; +import me.zhengjie.utils.PageUtils; + +/** + * 敦煌加入购物车(DhAddCar)表服务接口 + * + * @author makejava + * @since 2022-11-17 09:11:55 + */ +public interface DhAddCarService extends IService { + + /** + * 分页查询 + * @param page + * @param ew + * @return + */ + PageUtils searchPageList(IPage page, Wrapper ew); + + /** + * 根据id获取加购信息 + * @param id + * @return + */ + DhAddCarVO getDetailById(Long id); + + /** + * 根据id加悲观锁查询 + * @param id + * @return + */ + DhAddCar getByIdLock(Long id); + + /** + * 拼接影刀参数 + * @param id + * @return + */ + DhAddCarYdParamsVO getAddCarYdParams(Long id); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/DhCarGoodsService.java b/wjcy-common/src/main/java/me/zhengjie/service/DhCarGoodsService.java new file mode 100644 index 0000000..7546ef4 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/DhCarGoodsService.java @@ -0,0 +1,15 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.DhCarGoods; + +/** + * 敦煌-加入购物车商品信息(DhCarGoods)表服务接口 + * + * @author makejava + * @since 2022-11-17 09:12:03 + */ +public interface DhCarGoodsService extends IService { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/FileUploadService.java b/wjcy-common/src/main/java/me/zhengjie/service/FileUploadService.java new file mode 100644 index 0000000..e7af6ee --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/FileUploadService.java @@ -0,0 +1,20 @@ +package me.zhengjie.service; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** + *

+ * 图片上传服务 + *

+ * + * @Author xx + * @Date 2021/7/26 + **/ +public interface FileUploadService { + + List uploadify(HttpServletRequest request, HttpServletResponse response) + throws IOException; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/LoginIpService.java b/wjcy-common/src/main/java/me/zhengjie/service/LoginIpService.java new file mode 100644 index 0000000..a0bfcad --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/LoginIpService.java @@ -0,0 +1,58 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.LoginIp; +import me.zhengjie.utils.PageUtils; + +import java.util.List; + +/** + * (LoginIp)表服务接口 + * + * @author zeng + * @since 2022-03-21 14:07:01 + */ +public interface LoginIpService extends IService { + + String LOGIN_IP_LIST = "LOGIN_IP_LIST"; + + /** + * 获取IP列表 + * @author: zeng + * @param iPage + */ + PageUtils getList(IPage iPage); + + /** + * 新增 + * @author: zeng + */ + boolean addIp(LoginIp ip); + + /** + * 查询所有有效白名单IP段 + * @return + */ + List getAll(); + + /** + * 编辑 + * @author: zeng + */ + boolean updateIp(LoginIp ip); + + /** + * 删除 + * @author: zeng + */ + boolean deleteIp(Integer id); + + /** + * 是否是白名单 + * @author: zeng + */ + boolean whiteListFlag(String ip); + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/SettingSiteService.java b/wjcy-common/src/main/java/me/zhengjie/service/SettingSiteService.java new file mode 100644 index 0000000..a3a2097 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/SettingSiteService.java @@ -0,0 +1,25 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.CtSettingSite; + +/** + * 站点配置(CtSettingSite)表服务接口 + * + * @author xxs + * @since 2021-11-17 + */ +public interface SettingSiteService extends IService { + + String getValue(String key); + + boolean saveOrUpdateByKey(String key, String value); + + /** + * Google认证器开关 + * @auth xxs + * @return + */ + Boolean getGooleAuthSwitch(); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/SysQuartzLogService.java b/wjcy-common/src/main/java/me/zhengjie/service/SysQuartzLogService.java new file mode 100644 index 0000000..0b56c21 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/SysQuartzLogService.java @@ -0,0 +1,21 @@ +package me.zhengjie.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.entity.SysQuartzJob; +import me.zhengjie.entity.SysQuartzLog; +import me.zhengjie.service.vo.SysQuartzLogListVO; +import me.zhengjie.utils.PageUtils; + +/** + * 定时任务(SysQuartzJob)表服务接口 + * + * @author rch + * @since 2022-07-20 + */ +public interface SysQuartzLogService extends IService { + + PageUtils searchPageList(IPage page, Wrapper wrapper); +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/YdQuartzService.java b/wjcy-common/src/main/java/me/zhengjie/service/YdQuartzService.java new file mode 100644 index 0000000..619bdf5 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/YdQuartzService.java @@ -0,0 +1,74 @@ +package me.zhengjie.service; + +import me.zhengjie.entity.quartz.JobQueryByUuidReturn; +import me.zhengjie.service.redission.LockCallBack; + +/** + * 影刀定时任务Service + * + * @author rch + * @since 2022-08-01 + */ +public interface YdQuartzService{ + + Object executeOnLock(String lockKey, long time, long timeout, LockCallBack callBack) throws Exception; + + public String exec(String str) throws Exception; + + + /** + * 刷单 任务执行逻辑 + * @param str + * @return + * @throws Exception + */ + public Boolean clickFarmExec(String str) throws Exception; + + /** + * 敦煌加购 任务执行逻辑 + * @param str + * @return + * @throws Exception + */ + public Boolean addCarExec(String str) throws Exception; + + + /** + * 敦煌-加购-抓单 + * @param str + * @return + * @throws Exception + */ + public Boolean catchOrderExec(String str) throws Exception; + + public JobQueryByUuidReturn queryJobUuid(String uuid, String accessKeyId, String accessKeySecret); + + /** + * 刷单任务-补录(有订单信息-支付失败) + * @param str + * @return + */ + Boolean clickFarmSuppleMentExec(String str) throws Exception; + + /** + * 敦煌 + * @param str + * @return + * @throws Exception + */ + public Object dhWellReceivedExec(String str) throws Exception; + /** + * 好评 + * @param str + * @return + */ + Object wellReceivedExec(String str) throws Exception; + + /** + * 浏览收藏 + * @param str + * @return + */ + Object browseTaskExec(String str) throws Exception; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtApplyServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtApplyServiceImpl.java new file mode 100644 index 0000000..c0b0190 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtApplyServiceImpl.java @@ -0,0 +1,44 @@ +package me.zhengjie.service.impl; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.CtApplyDao; +import me.zhengjie.entity.CtApply; +import me.zhengjie.service.CtApplyService; +import me.zhengjie.service.vo.CtApplyListVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 影刀应用信息(CtApply)表服务实现类 + * + * @author rch + * @since 2022-07-23 + */ +@Service +public class CtApplyServiceImpl extends ServiceImpl implements CtApplyService { + + @Resource + private CtApplyDao ctApplyDao; + + @Override + public PageUtils searchPageList(IPage page, Wrapper ew) { + ctApplyDao.searchPageList(page, ew); + return new PageUtils<>(page.getTotal(),page.getRecords()); + } + + @Override + public List getAllApplyName() { + return ctApplyDao.getAllApplyName(); + } + + @Override + public CtApply getApplyByTaskAndMethod(String taskName, String method) { + return ctApplyDao.getApplyByTaskAndMethod(taskName, method); + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtBrowseServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtBrowseServiceImpl.java new file mode 100644 index 0000000..2b7896d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtBrowseServiceImpl.java @@ -0,0 +1,44 @@ +package me.zhengjie.service.impl; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.CtBrowseDao; +import me.zhengjie.entity.CtBrowse; +import me.zhengjie.service.CtBrowseService; +import me.zhengjie.service.vo.CtBrowseDetailVO; +import me.zhengjie.service.vo.CtBrowseListVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 浏览收藏(CtBrowse)表服务实现类 + * + * @author rch + * @since 2022-11-04 09:45:33 + */ +@Service +public class CtBrowseServiceImpl extends ServiceImpl implements CtBrowseService { + + @Resource + private CtBrowseDao ctBrowseDao; + + @Override + public PageUtils searchPageList(IPage page, Wrapper ew) { + ctBrowseDao.searchPageList(page, ew); + return new PageUtils(page.getTotal(), page.getRecords()); + } + + @Override + public CtBrowse getByIdLock(Long id) { + return ctBrowseDao.getByIdLock(id); + } + + @Override + public CtBrowseDetailVO getBrowseDetailById(Long id) { + return ctBrowseDao.getBrowseDetailById(id); + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtBuyerServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtBuyerServiceImpl.java new file mode 100644 index 0000000..889a0ca --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtBuyerServiceImpl.java @@ -0,0 +1,69 @@ +package me.zhengjie.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.CtBuyerDao; +import me.zhengjie.entity.CtBuyer; +import me.zhengjie.service.CtBuyerService; +import me.zhengjie.service.vo.CtBuyerDetailVO; +import me.zhengjie.service.vo.CtBuyerListVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 买家表(CtBuyer)表服务实现类 + * + * @author rch + * @since 2022-06-22 + */ +@Service +public class CtBuyerServiceImpl extends ServiceImpl implements CtBuyerService { + + @Resource + private CtBuyerDao ctBuyerDao; + + @Override + public PageUtils searchPageList(IPage page, Wrapper ew) { + ctBuyerDao.searchPageList(page, ew); + return new PageUtils(page.getTotal(), page.getRecords()); + } + + @Override + public CtBuyerDetailVO getDetailById(Long id) { + return ctBuyerDao.getDetailById(id); + } + + @Override + public List getAllAccount(){ return ctBuyerDao.getAllAccount();} + + @Override + public String getPwdByName(String name) { + return ctBuyerDao.getPwdByName(name); + } + + @Override + public CtBuyer getBuyerOccupyStatusLock(String buyerName) { + return ctBuyerDao.getBuyerOccupyStatusLock(buyerName); + } + + @Override + public Map getBuyerList(List buyerAccountList) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("account", buyerAccountList); + + List ctBuyerList = list(queryWrapper); + if (ObjectUtil.isNotEmpty(ctBuyerList)) { + return ctBuyerList.stream().collect(Collectors.toMap(CtBuyer::getAccount, CtBuyer->CtBuyer)); + } + return null; + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtCardServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtCardServiceImpl.java new file mode 100644 index 0000000..e36521c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtCardServiceImpl.java @@ -0,0 +1,33 @@ +package me.zhengjie.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.CtCardDao; +import me.zhengjie.entity.CtCard; +import me.zhengjie.entity.CtCardInfo; +import me.zhengjie.service.CtCardService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 信用卡信息(CtCard)表服务实现类 + * + * @author rch + * @since 2022-07-07 + */ +@Service +public class CtCardServiceImpl extends ServiceImpl implements CtCardService { + + @Resource + private CtCardDao ctCardDao; + + @Override + public List getNumberList() { + return ctCardDao.getNumberList(); + } + + @Override + public List getCardInfoByNumber(List number){ return ctCardDao.getCardInfoByNumber(number);} +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtClickFarmingServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtClickFarmingServiceImpl.java new file mode 100644 index 0000000..ea01a9d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtClickFarmingServiceImpl.java @@ -0,0 +1,62 @@ +package me.zhengjie.service.impl; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.CtClickFarmingDao; +import me.zhengjie.entity.CtBuyerClickSuccess; +import me.zhengjie.entity.CtClickFarmYdParams; +import me.zhengjie.entity.CtClickFarming; +import me.zhengjie.service.CtClickFarmingService; +import me.zhengjie.service.vo.CtClickFarmEditDetailVO; +import me.zhengjie.service.vo.CtClickFarmingDetailVO; +import me.zhengjie.service.vo.CtClickFarmingVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 刷单Excel信息(CtClickFarming)表服务实现类 + * + * @author rch + * @since 2022-08-16 + */ +@Service +public class CtClickFarmingServiceImpl extends ServiceImpl implements CtClickFarmingService { + + @Resource + private CtClickFarmingDao ctClickFarmingDao; + @Override + public PageUtils searchPageList(IPage page, Wrapper ew) { + ctClickFarmingDao.searchPageList(page, ew); + return new PageUtils(page.getTotal(), page.getRecords()); + } + + @Override + public CtClickFarming getByIdLock(Long id) { + return ctClickFarmingDao.getByIdLock(id); + } + + @Override + public CtClickFarmEditDetailVO getEditDetailById(Long id) { + return ctClickFarmingDao.getEditDetailById(id); + } + + @Override + public CtClickFarmingDetailVO getDetailById(Long id) { + return ctClickFarmingDao.getDetailById(id); + } + + @Override + public List ruleGetCtBuyer(String buyerAccount, String country, String shopName) { + return ctClickFarmingDao.ruleGetCtBuyer(buyerAccount, country, shopName); + } + + @Override + public CtClickFarmYdParams getCtClickFarmYdParams(Long id) { + return ctClickFarmingDao.getCtClickFarmYdParams(id); + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtClickOrderServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtClickOrderServiceImpl.java new file mode 100644 index 0000000..1b0f3e1 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtClickOrderServiceImpl.java @@ -0,0 +1,90 @@ +package me.zhengjie.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.CtClickOrderDao; +import me.zhengjie.entity.CtClickFarming; +import me.zhengjie.entity.CtClickFarmingOrderInfo; +import me.zhengjie.entity.CtClickOrder; +import me.zhengjie.enums.ClickFarmingStatusEnum; +import me.zhengjie.service.CtClickFarmingService; +import me.zhengjie.service.CtClickOrderService; +import me.zhengjie.service.vo.CtClickOrderDetailVO; +import me.zhengjie.service.vo.CtClickOrderListVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 刷单-订单信息(CtClickOrder)表服务实现类 + * + * @author rch + * @since 2022-09-14 + */ +@Service +public class CtClickOrderServiceImpl extends ServiceImpl implements CtClickOrderService { + + @Resource + private CtClickOrderDao ctClickOrderDao; + @Resource + private CtClickFarmingService ctClickFarmingService; + + @Override + public List getOrderId(List importOrderIdList) { + List orderIdList = new ArrayList<>(); + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.in("order_id", importOrderIdList) + .select("order_id"); + List queryClickOrderIdList = list(queryWrapper); + if (ObjectUtil.isNotEmpty(queryClickOrderIdList)) { + orderIdList = queryClickOrderIdList.stream().map(q->q.getOrderId()).collect(Collectors.toList()); + } + return orderIdList; + } + + @Override + public PageUtils searchPageList(IPage page, Wrapper ew) { + ctClickOrderDao.searchPageList(page, ew); + return new PageUtils(page.getTotal(), page.getRecords()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean supplement(Long clickFarmingId, CtClickOrder ctClickOrder) { + Boolean saveBoolean = save(ctClickOrder); + if (!saveBoolean) { + return false; + } + Long ctOrderId = ctClickOrder.getId(); + CtClickFarming ctClickFarming = new CtClickFarming(); + ctClickFarming.setId(clickFarmingId); + ctClickFarming.setCtClickOrderId(ctOrderId); + ctClickFarming.setStatus(ClickFarmingStatusEnum.EXECUTION_SUCCESS.value()); + + return ctClickFarmingService.updateById(ctClickFarming); + } + + @Override + public CtClickFarmingOrderInfo getClickFarmOrderById(Long orderId) { + return ctClickOrderDao.getClickFarmOrderById(orderId); + } + + @Override + public CtClickOrder getByIdLock(Long id) { + return ctClickOrderDao.getByIdLock(id); + } + + @Override + public CtClickOrderDetailVO getClickOrderDetailById(Long id) { + return ctClickOrderDao.getClickOrderDetailById(id); + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtCompanyServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtCompanyServiceImpl.java new file mode 100644 index 0000000..e5948ac --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtCompanyServiceImpl.java @@ -0,0 +1,53 @@ +package me.zhengjie.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.CtCompanyDao; +import me.zhengjie.entity.CtCompany; +import me.zhengjie.entity.CtCompanyInfo; +import me.zhengjie.entity.CtPlatform; +import me.zhengjie.service.CtCompanyService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 公司信息(CtCompany)表服务实现类 + * + * @author makejava + * @since 2022-06-23 10:37:44 + */ +@Service +public class CtCompanyServiceImpl extends ServiceImpl implements CtCompanyService { + + @Resource + private CtCompanyDao ctCompanyDao; + + @Override + public List getByNmae(List name) { + return ctCompanyDao.getByName(name); + } + + @Override + public List getCompanyList() { + return ctCompanyDao.getCompanyList(); + } + + @Override + public Map getNameList(List platNameList) { + Map ctCompanyMap = new HashMap<>(16); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("name", platNameList).select("id", "name"); + List ctCompanyList = list(queryWrapper); + if (ObjectUtil.isNotEmpty(ctCompanyList)) { + ctCompanyMap = ctCompanyList.stream().collect(Collectors.toMap(CtCompany::getId, CtCompany::getName)); + } + return ctCompanyMap; + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtDhPayServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtDhPayServiceImpl.java new file mode 100644 index 0000000..bf25565 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtDhPayServiceImpl.java @@ -0,0 +1,100 @@ +package me.zhengjie.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.config.DhApiProperties; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dao.CtDhPayDao; +import me.zhengjie.entity.CtDhPay; +import me.zhengjie.entity.CtDhPayExport; +import me.zhengjie.enums.DhPayStatusEnum; +import me.zhengjie.enums.ExcelStatusEnum; +import me.zhengjie.service.CtBuyerService; +import me.zhengjie.service.CtDhPayService; +import me.zhengjie.service.vo.CtBuyerListVO; +import me.zhengjie.service.vo.CtDhPayListVO; +import me.zhengjie.service.vo.PayOrderVO; +import me.zhengjie.utils.HttpClientUtil; +import me.zhengjie.utils.PageUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 平台信息(CtDyPay)表服务实现类 + * + * @author rch + * @since 2022-07-28 + */ +@Service +public class CtDhPayServiceImpl extends ServiceImpl implements CtDhPayService { + + @Resource + private CtDhPayDao ctDhPayDao; + + @Resource + private CtBuyerService ctBuyerService; + + @Override + public PageUtils searchPageList(IPage page, Wrapper ew) { + ctDhPayDao.searchPageList(page, ew); + return new PageUtils(page.getTotal(), page.getRecords()); + } + + @Override + public void toPay() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("status", DhPayStatusEnum.TO_BE.value()); + List ctDhPayList = list(queryWrapper); + + // for 循环下单处理 + for (CtDhPay ctDhPay :ctDhPayList) { + payOrderApi(ctDhPay); + } + } + + @Override + public Boolean payOrderApi(CtDhPay ctDhPay) { + + // TODO 参数检验验证 + + String buyerName = ctDhPay.getBuyerName(); + String pwd = ctBuyerService.getPwdByName(buyerName); + if (ObjectUtil.isEmpty(pwd)) { + return false; + } + + Map params = new HashMap<>(16); + // 统一请求参数 + params.put("timestamp", System.currentTimeMillis()); + params.put("v", DhApiProperties.PAY_ORDER_V); + params.put("access_token", pwd); + params.put("method", DhApiProperties.PAY_ORDER_METHOD); + + // boby + params.put("orderNo", ctDhPay.getOrderId()); + + String responseStr = HttpClientUtil.doPostHttp(DhApiProperties.PAY_ORDER_URL, params); + PayOrderVO payOrderVO = JSONUtil.toBean(responseStr, PayOrderVO.class); + Boolean requestBoolean = false; + // 成功 修改订单状态 以及填充接口响应信息 + if (ObjectUtil.isNotEmpty(payOrderVO) && PublicConstant.RESPONSE_SUCCESS.equals(payOrderVO.getResult()) && PublicConstant.DH_REQUEST_SUCCESS_STATUS_CODE.equals(payOrderVO.getStatus().getCode())) { + requestBoolean = true; + } + + Integer status = requestBoolean ? DhPayStatusEnum.PAY_SUCCESS.value() : DhPayStatusEnum.PAY_FAIL.value(); + CtDhPay updateCtDhPay = new CtDhPay(); + updateCtDhPay.setId(ctDhPay.getId()); + updateCtDhPay.setResponse(JSONUtil.toJsonStr(payOrderVO)); + updateCtDhPay.setStatus(status); + return updateById(updateCtDhPay); + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtExcelImportInfoServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtExcelImportInfoServiceImpl.java new file mode 100644 index 0000000..0a86ff5 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtExcelImportInfoServiceImpl.java @@ -0,0 +1,174 @@ +package me.zhengjie.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.config.PropertiesConfig; +import me.zhengjie.config.SystemConfig; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dao.CtExcelImportInfoDao; +import me.zhengjie.entity.*; +import me.zhengjie.enums.ExcelInfoRequestTypeEnum; +import me.zhengjie.enums.ExcelStatusEnum; +import me.zhengjie.service.CtBuyerService; +import me.zhengjie.service.CtCompanyService; +import me.zhengjie.service.CtExcelImportInfoService; +import me.zhengjie.service.CtExcelService; +import me.zhengjie.utils.excel.ExcelUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Excel导入信息(CtExcelImportInfo)表服务实现类 + * + * @author rch + * @since 2022-06-23 + */ +@Slf4j +@Service +public class CtExcelImportInfoServiceImpl extends ServiceImpl implements CtExcelImportInfoService { + + @Resource + private CtExcelService ctExcelService; + @Resource + private CtCompanyService ctCompanyService; + @Resource + private CtBuyerService ctBuyerService; + @Resource + private PropertiesConfig propertiesConfig; + @Resource + private Snowflake snowflake; + + @Override + public void importExcel() throws IOException { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(CtExcel::getStatus, ExcelStatusEnum.TOBE.value()); + + List ctExcelList = ctExcelService.list(queryWrapper); + // 导入存储数据库业务逻辑 + if (ObjectUtil.isNotEmpty(ctExcelList)) { + + // TODO -判断公司和token 是否匹配 不匹配则导入失败 + + // 符合条件的往下走 + String errorUrlPath = saveExcel(ctExcelList); + LambdaQueryWrapper updateStatusQW = new LambdaQueryWrapper<>(); + List ctExcelIdList = ctExcelList.stream().map(CtExcel::getId).collect(Collectors.toList()); + updateStatusQW.in(CtExcel::getId, ctExcelIdList); + + int status = ObjectUtil.isEmpty(errorUrlPath) ? ExcelStatusEnum.SUCCESS.value() : ExcelStatusEnum.FAILE.value(); + // 不符合条件的 直接失败 + CtExcel updateCtExcel = new CtExcel(); + updateCtExcel.setErrorPath(errorUrlPath); + updateCtExcel.setStatus(status); + ctExcelService.update(updateCtExcel, updateStatusQW); + } + } + + /** + * 导入业务逻辑 + * @param ctExcelList + * @return + */ + public String saveExcel(List ctExcelList) throws IOException { + + String returnDataStr = null; + List excelImportInfoList = new ArrayList<>(); + + for (CtExcel ctExcel:ctExcelList) { + String platImageUrl = SystemConfig.IMG_PATH; + String pathUrl = ctExcel.getPath(); + String excelPathUrl = platImageUrl + pathUrl; + + // 读取文件 + File file = new File(excelPathUrl); + try { + List excelImportInfoTempList = ExcelUtils.readFile(file, CtExcelImportInfo.class); + if (ObjectUtil.isNotEmpty(excelImportInfoTempList)) { + excelImportInfoList.addAll(excelImportInfoTempList); + } + } catch (Exception exception) { + System.out.println(exception.getMessage()); + } + } + + // 存储mysql + if (ObjectUtil.isNotEmpty(excelImportInfoList)) { + + + List addCtExcelImportInfoList = new ArrayList<>(); + List errorCtExcelExportInfoList = new ArrayList<>(); + + List companyIdList = excelImportInfoList.stream().map(CtExcelImportInfo::getCompanyId).collect(Collectors.toList()); + QueryWrapper queryWrapperCompany = new QueryWrapper<>(); + queryWrapperCompany.in("id", companyIdList); + List ctCompanyList = ctCompanyService.list(queryWrapperCompany); + + List buyerIdList = excelImportInfoList.stream().map(CtExcelImportInfo::getTokenEnum).collect(Collectors.toList()); + QueryWrapper queryWrapperBuyer = new QueryWrapper<>(); + queryWrapperBuyer.in("id", buyerIdList); + List ctBuyerList = ctBuyerService.list(queryWrapperBuyer); + + // 新增订单编号 + for (CtExcelImportInfo ctExcelImportInfo:excelImportInfoList) { + CtExcelExportInfo ctExcelExportInfo = new CtExcelExportInfo(); + BeanUtil.copyProperties(ctExcelImportInfo, ctExcelExportInfo); + // TODO 检验Excel 导入的文件是否符合要求 符合要求导入 不符合要求则直接Excel错误信息导出 + StringBuffer errorStrBuf = new StringBuffer(); + if (ObjectUtil.isEmpty(ctCompanyList) + || ctCompanyList.stream().filter(c->c.getId().equals(ctExcelImportInfo.getCompanyId())).count() <= 0) { + errorStrBuf.append("公司信息不存在!"); + errorStrBuf.append(";"); + } + + if (ObjectUtil.isEmpty(ctBuyerList) + || ctBuyerList.stream().filter(c->c.getId().equals(ctExcelImportInfo.getTokenEnum())).count() <= 0) { + errorStrBuf.append("买家信息不存在!"); + errorStrBuf.append(";"); + } + + if (ObjectUtil.isNotEmpty(errorStrBuf)) { + ctExcelExportInfo.setError(errorStrBuf.toString()); + errorCtExcelExportInfoList.add(ctExcelExportInfo); + } else { + CtBuyerContactInfo ctBuyerContactInfo = new CtBuyerContactInfo(); + CtBuyer ctBuyer = ctBuyerList.stream().filter(c->c.getId().equals(ctExcelImportInfo.getTokenEnum())).findFirst().get(); + // 取出收款地址信息 + BeanUtil.copyProperties(ctBuyer, ctBuyerContactInfo); + + ctExcelImportInfo.setOrderNo(snowflake.nextIdStr()); + ctExcelImportInfo.setContactInfo(JSONUtil.toJsonStr(ctBuyerContactInfo)); + addCtExcelImportInfoList.add(ctExcelImportInfo); + } + } + + // TODO 不符合条件的 Excel 导出 返回导出excel url url = errorExcelUrl; + String filePath = propertiesConfig.getUploadImgPath().get(PublicConstant.EXPORT_EXCEL_FILE_TYPE); + String fileName = "下单信息导入异常信息表-" + snowflake.nextIdStr(); + if (ObjectUtil.isNotEmpty(errorCtExcelExportInfoList)) { + ExcelUtils.exportFile(SystemConfig.IMG_PATH + filePath, fileName, errorCtExcelExportInfoList); + returnDataStr = SystemConfig.FILE_VISIT_ADDR + filePath + fileName + ".xlsx"; + // returnDataStr = "http://localhost:8008/file" + filePath + fileName + ".xlsx"; + } + // 如何条件的导入 + if (ObjectUtil.isNotEmpty(addCtExcelImportInfoList)) { + saveBatch(addCtExcelImportInfoList); + } + } + return returnDataStr; + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtExcelServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtExcelServiceImpl.java new file mode 100644 index 0000000..6cfbb08 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtExcelServiceImpl.java @@ -0,0 +1,19 @@ +package me.zhengjie.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.CtExcelDao; +import me.zhengjie.entity.CtExcel; +import me.zhengjie.service.CtExcelService; +import org.springframework.stereotype.Service; + +/** + * Excel 导入信息(CtExcel)表服务实现类 + * + * @author makejava + * @since 2022-06-23 10:37:44 + */ +@Service +public class CtExcelServiceImpl extends ServiceImpl implements CtExcelService { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtOrderServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtOrderServiceImpl.java new file mode 100644 index 0000000..9fe1f5b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtOrderServiceImpl.java @@ -0,0 +1,196 @@ +package me.zhengjie.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.config.DhApiProperties; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dao.CtOrderDao; +import me.zhengjie.entity.*; +import me.zhengjie.enums.ExcelStatusEnum; +import me.zhengjie.service.*; +import me.zhengjie.service.vo.*; +import me.zhengjie.utils.HttpClientUtil; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * (CtOrder)表服务实现类 + * + * @author rch + * @since 2022-07-01 + */ +@Service +public class CtOrderServiceImpl extends ServiceImpl implements CtOrderService { + + @Resource + private CtExcelImportInfoService ctExcelImportInfoService; + @Resource + private CtResponseOrderService ctResponseOrderService; + @Resource + private CtResponseOrderAddressService ctResponseOrderAddressService; + @Resource + private CtResponseOrderProductService ctResponseOrderProductService; + @Resource + private CtBuyerService ctBuyerService; + + @Override + public void excelToOrder() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("status", ExcelStatusEnum.TOBE.value()); + List ctExcelImportInfoList = ctExcelImportInfoService.list(queryWrapper); + + for (CtExcelImportInfo ctExcelImportInfo:ctExcelImportInfoList) { + buyOrderApi(ctExcelImportInfo); + } + } + + @Transactional(rollbackFor = Exception.class) + public Boolean buyOrderApi(CtExcelImportInfo ctExcelImportInfo) { + + // TODO 请求参数解析 检验 -先不做 + + // 获取买家access_token + Long buyerId = ctExcelImportInfo.getTokenEnum(); + CtBuyer ctBuyer = ctBuyerService.getById(buyerId); + + Map params = new HashMap<>(); + // 统一请求参数 + params.put("timestamp", System.currentTimeMillis()); + params.put("v", DhApiProperties.BUY_ORDER_V); + params.put("access_token", ctBuyer.getPwd()); + params.put("method", DhApiProperties.BUY_ORDER_METHOD); + + // boby + params.put("fromDetailInfo", ctExcelImportInfo.getFromDetailInfo()); + String carList = ctExcelImportInfo.getCartList(); + String contacInfo = ctExcelImportInfo.getContactInfo(); + params.put("cartList", carList); + params.put("contactInfo", contacInfo); + + + String responseStr = HttpClientUtil.doPostHttp(DhApiProperties.BUY_ORDER_URL, params); + + // 请求响应转对象 + BuyOrderVO buyOrderVO = JSONUtil.toBean(responseStr, BuyOrderVO.class); + System.out.println("buyOrderVO: " + buyOrderVO.toString()); + + Boolean saveOrderBathResult = false; + // 业务逻辑处理 数据处理 + if (ObjectUtil.isNotEmpty(buyOrderVO) && PublicConstant.DH_REQUEST_SUCCESS_STATUS_CODE.equals(buyOrderVO.getStatus().getCode())) { + // 接口响应码以及响应信息 + OrderResponStatusVO orderResponStatus = buyOrderVO.getStatus(); + // 请求接口响应内容 + List OrderResponseList = buyOrderVO.getOrderList(); + + List orderList = new ArrayList<>(); + Long companyId = ctExcelImportInfo.getCompanyId(); + + for (OrderResponseVO orderResponseVO:OrderResponseList) { + CtOrder ctOrder = new CtOrder(); + ctOrder.setCompanyId(companyId); + ctOrder.setBuyerId(buyerId); + ctOrder.setBuyAccessToken(ctBuyer.getPwd()); + ctOrder.setExcelInfoId(ctExcelImportInfo.getId()); + ctOrder.setCtOrderNo(ctExcelImportInfo.getOrderNo()); + ctOrder.setOrderResponseStatus(JSONUtil.toJsonStr(orderResponStatus)); + + // ct_response_order + CtResponseOrder ctResponseOrder = new CtResponseOrder(); + BuyOrderResponseOrderVO buyOrderResponseOrderVO = orderResponseVO.getOrderInfo(); + BeanUtil.copyProperties(buyOrderResponseOrderVO, ctResponseOrder); + System.out.println("======ctResponseOrder:" + ctResponseOrder); + // order 特殊处理 对应响应的id + Long responseOrderId = buyOrderResponseOrderVO.getId(); + ctResponseOrder.setOrderId(responseOrderId); + ctResponseOrderService.save(ctResponseOrder); + Long saveResponseOrderId = ctResponseOrder.getId(); + ctOrder.setResponseOrderId(saveResponseOrderId); + ctOrder.setOrderNo(responseOrderId); + + // ct_response_address + CtResponseOrderAddress ctResponseOrderAddress = new CtResponseOrderAddress(); + BuyOrderResponseAddressVO buyOrderResponseAddress = orderResponseVO.getOrderContactInfo(); + BeanUtil.copyProperties(buyOrderResponseAddress, ctResponseOrderAddress); + System.out.println("======ctResponseOrderAddress:" + ctResponseOrderAddress); + ctResponseOrderAddressService.save(ctResponseOrderAddress); + Long responseOrderAddressId = ctResponseOrderAddress.getId(); + ctOrder.setResponseOrderAddressId(responseOrderAddressId); + + // ct_response_product + // TODO -这里商品响应是一个集合 这里目前看都是单个,先不考虑 + CtResponseOrderProduct ctResponseOrderProduct = new CtResponseOrderProduct(); + List buyOrderResponseProductList = orderResponseVO.getCartList(); + BeanUtil.copyProperties(buyOrderResponseProductList.get(0), ctResponseOrderProduct); + System.out.println("======ctResponseOrderProduct:" + ctResponseOrderProduct); + ctResponseOrderProductService.save(ctResponseOrderProduct); + Long responseproductId = ctResponseOrderProduct.getId(); + ctOrder.setResponseProductId(responseproductId); + + orderList.add(ctOrder); + } + + saveOrderBathResult = saveBatch(orderList); + } + + // 修改Excel状态 + Integer status = saveOrderBathResult ? ExcelStatusEnum.SUCCESS.value() : ExcelStatusEnum.FAILE.value(); + CtExcelImportInfo updateCtExcelImportInfo = new CtExcelImportInfo(); + updateCtExcelImportInfo.setId(ctExcelImportInfo.getId()); + updateCtExcelImportInfo.setStatus(status); + ctExcelImportInfoService.updateById(updateCtExcelImportInfo); + + return true; + } + + @Override + public void toPay() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("status", ExcelStatusEnum.TOBE.value()); + List ctOrderList = list(queryWrapper); + + for (CtOrder ctOrder:ctOrderList) { + payOrderApi(ctOrder); + } + } + + @Override + public Boolean payOrderApi(CtOrder ctOrder) { + + // TODO 参数检验验证 + + Map params = new HashMap<>(); + // 统一请求参数 + params.put("timestamp", System.currentTimeMillis()); + params.put("v", DhApiProperties.PAY_ORDER_V); + params.put("access_token", ctOrder.getBuyAccessToken()); + params.put("method", DhApiProperties.PAY_ORDER_METHOD); + + // boby + params.put("orderNo", ctOrder.getOrderNo()); + + String responseStr = HttpClientUtil.doPostHttp(DhApiProperties.PAY_ORDER_URL, params); + PayOrderVO payOrderVO = JSONUtil.toBean(responseStr, PayOrderVO.class); + Boolean requestBoolean = false; + // 成功 修改订单状态 以及填充接口响应信息 + if (ObjectUtil.isNotEmpty(payOrderVO) && PublicConstant.RESPONSE_SUCCESS.equals(payOrderVO.getResult()) && PublicConstant.DH_REQUEST_SUCCESS_STATUS_CODE.equals(payOrderVO.getStatus().getCode())) { + requestBoolean = true; + } + + Integer status = requestBoolean ? ExcelStatusEnum.SUCCESS.value() : ExcelStatusEnum.FAILE.value(); + CtOrder updateCtOrder = new CtOrder(); + updateCtOrder.setId(ctOrder.getId()); + updateCtOrder.setPayResponseStatus(JSONUtil.toJsonStr(payOrderVO)); + updateCtOrder.setStatus(status); + return updateById(updateCtOrder); + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtPlatformServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtPlatformServiceImpl.java new file mode 100644 index 0000000..b399b7b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtPlatformServiceImpl.java @@ -0,0 +1,37 @@ +package me.zhengjie.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.CtPlatformDao; +import me.zhengjie.entity.CtPlatform; +import me.zhengjie.service.CtPlatformService; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 平台信息(CtPlatform)表服务实现类 + * + * @author makejava + * @since 2022-06-23 10:37:44 + */ +@Service +public class CtPlatformServiceImpl extends ServiceImpl implements CtPlatformService { + + @Override + public Map getNameList(List platNameList) { + Map ctPlatformMap = new HashMap<>(16); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("name", platNameList).select("id", "name"); + List ctPlatformList = list(queryWrapper); + if (ObjectUtil.isNotEmpty(ctPlatformList)) { + ctPlatformMap = ctPlatformList.stream().collect(Collectors.toMap(CtPlatform::getId, CtPlatform::getName)); + } + return ctPlatformMap; + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtRebotServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtRebotServiceImpl.java new file mode 100644 index 0000000..93120c8 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtRebotServiceImpl.java @@ -0,0 +1,127 @@ +package me.zhengjie.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.config.PropertiesConfig; +import me.zhengjie.config.SystemConfig; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dao.CtRebotDao; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtRebot; +import me.zhengjie.entity.CtRebotExport; +import me.zhengjie.entity.CtRebotImport; +import me.zhengjie.service.CtRebotService; +import me.zhengjie.service.vo.CtRebotListVO; +import me.zhengjie.utils.PageUtils; +import me.zhengjie.utils.excel.ExcelUtils; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.List; + +/** + * 影刀设备-机器人信息(CtRebot)表服务实现类 + * + * @author rch + * @since 2022-07-23 + */ +@Service +public class CtRebotServiceImpl extends ServiceImpl implements CtRebotService { + + @Resource + private CtRebotDao ctRebotDao; + @Resource + private PropertiesConfig propertiesConfig; + @Resource + private Snowflake snowflake; + + @Override + public CtRebot getByAccountNameLock(String accountName) { + return ctRebotDao.getByAccountNameLock(accountName); + } + + @Override + public PageUtils searchPageList(IPage page, Wrapper ew) { + ctRebotDao.searchRebotList(page,ew); + return new PageUtils<>(page.getTotal(),page.getRecords()); + } + + @Override + public Dto importRebot(MultipartFile file, HttpServletResponse response)throws Exception { + List ctRebotImportList = ExcelUtils.readMultipartFile(file,CtRebotImport.class); + if(ObjectUtil.isEmpty(ctRebotImportList)){ + return Dto.returnResult(false); + } + + List addCtRebotList = new ArrayList<>(); + List ctRebotExportList = new ArrayList<>(); + List rebotNameList = getAccountNameList(); + List rebotUuidList = getClientUuidList(); + + for(CtRebotImport ctRebotImport : ctRebotImportList){ + CtRebotExport ctRebotExport = new CtRebotExport(); + BeanUtil.copyProperties(ctRebotImport,ctRebotExport); + + StringBuffer errorBuffer = new StringBuffer(); + String rowTips = ctRebotImport.getRowTips(); + if(ObjectUtil.isNotEmpty(rowTips)){ + errorBuffer.append(rowTips); + errorBuffer.append(";"); + } + if(rebotNameList.contains(ctRebotImport.getAccountName())){ + errorBuffer.append("已存在该名称对应的机器人信息"); + errorBuffer.append(";"); + } + if(rebotUuidList.contains(ctRebotImport.getRobotClientUuid())){ + errorBuffer.append("已存在该Uuid对应的机器人信息"); + errorBuffer.append(";"); + } + if(ObjectUtil.isNotEmpty(errorBuffer)){ + ctRebotExport.setError(errorBuffer.toString()); + ctRebotExportList.add(ctRebotExport); + }else{ + CtRebot ctRebot = new CtRebot(); + BeanUtil.copyProperties(ctRebotImport,ctRebot); + addCtRebotList.add(ctRebot); + } + } + + String returnDataStr = null; + String filePath = propertiesConfig.getUploadImgPath().get(PublicConstant.EXPORT_EXCEL_FILE_TYPE); + String fileName = "机器人导入异常信息表-" + snowflake.nextIdStr(); + if(ObjectUtil.isNotEmpty(ctRebotExportList)){ + ExcelUtils.exportFile(SystemConfig.IMG_PATH + filePath, fileName, ctRebotExportList); + returnDataStr = SystemConfig.FILE_VISIT_ADDR + filePath + fileName + ".xlsx"; + //returnDataStr = "http://localhost:8008/file" + filePath + fileName + ".xlsx"; + } + + if(ObjectUtil.isNotEmpty(addCtRebotList)){ + saveBatch(addCtRebotList); + } + + return Dto.returnResult(ObjectUtil.isEmpty(returnDataStr) ? true : returnDataStr); + } + + @Override + public List getAccountNameList() { + return ctRebotDao.getAccountNameList(); + } + + @Override + public List getClientUuidList() { + return ctRebotDao.getClientUuidList(); + } + + @Override + public Boolean updateNewStatusByOldStatus(Long id, Integer newStatus, Integer oldStatus) { + return ctRebotDao.updateNewStatusByOldStatus(id, newStatus, oldStatus); + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtResponseOrderAddressServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtResponseOrderAddressServiceImpl.java new file mode 100644 index 0000000..96ee9e6 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtResponseOrderAddressServiceImpl.java @@ -0,0 +1,19 @@ +package me.zhengjie.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.CtResponseOrderAddressDao; +import me.zhengjie.entity.CtResponseOrderAddress; +import me.zhengjie.service.CtResponseOrderAddressService; +import org.springframework.stereotype.Service; + +/** + * 下注成功订单响应收货地址信息(CtResponseOrderAddress)表服务实现类 + * + * @author rch + * @since 2022-07-01 + */ +@Service +public class CtResponseOrderAddressServiceImpl extends ServiceImpl implements CtResponseOrderAddressService { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtResponseOrderProductServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtResponseOrderProductServiceImpl.java new file mode 100644 index 0000000..9045753 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtResponseOrderProductServiceImpl.java @@ -0,0 +1,19 @@ +package me.zhengjie.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.CtResponseOrderProductDao; +import me.zhengjie.entity.CtResponseOrderProduct; +import me.zhengjie.service.CtResponseOrderProductService; +import org.springframework.stereotype.Service; + +/** + * 下单订单响应产品信息(CtResponseOrderProduct)表服务实现类 + * + * @author rch + * @since 2022-07-01 + */ +@Service +public class CtResponseOrderProductServiceImpl extends ServiceImpl implements CtResponseOrderProductService { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtResponseOrderServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtResponseOrderServiceImpl.java new file mode 100644 index 0000000..1aab77d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtResponseOrderServiceImpl.java @@ -0,0 +1,19 @@ +package me.zhengjie.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.CtResponseOrderDao; +import me.zhengjie.entity.CtResponseOrder; +import me.zhengjie.service.CtResponseOrderService; +import org.springframework.stereotype.Service; + +/** + * 下单成功响应订单商品信息(CtResponseOrder)表服务实现类 + * + * @author rch + * @since 2022-07-01 + */ +@Service +public class CtResponseOrderServiceImpl extends ServiceImpl implements CtResponseOrderService { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/CtVpnServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtVpnServiceImpl.java new file mode 100644 index 0000000..db2730a --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/CtVpnServiceImpl.java @@ -0,0 +1,31 @@ +package me.zhengjie.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.CtVpnDao; +import me.zhengjie.entity.CtVpn; +import me.zhengjie.entity.CtVpnInfo; +import me.zhengjie.service.CtVpnService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * VPN信息表(CtVpn)表服务实现类 + * + * @author rch + * @since 2022-07-07 + */ +@Service +public class CtVpnServiceImpl extends ServiceImpl implements CtVpnService { + + @Resource + private CtVpnDao ctVpnDao; + + @Override + public List getIpList() { return ctVpnDao.getIpList(); } + + @Override + public List getVpnInfoByIp(List ipAddress){ return ctVpnDao.getVpnInfoByIp(ipAddress);} +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/DhAddCarOrderServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/DhAddCarOrderServiceImpl.java new file mode 100644 index 0000000..3d9143b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/DhAddCarOrderServiceImpl.java @@ -0,0 +1,98 @@ +package me.zhengjie.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.DhAddCarOrderDao; +import me.zhengjie.dao.DhCarGoodsDao; +import me.zhengjie.entity.DhAddCarOrder; +import me.zhengjie.entity.DhCarGoods; +import me.zhengjie.enums.ParamsTypeEnum; +import me.zhengjie.service.DhAddCarOrderService; +import me.zhengjie.service.vo.dhaddcar.DhAddCarVO; +import me.zhengjie.service.vo.dhcargood.DhCarGoodKeyVO; +import me.zhengjie.service.vo.dhcargood.DhCarGoodLinkVO; +import me.zhengjie.service.vo.dhcarorder.DhAddCarOrderListVO; +import me.zhengjie.service.vo.dhcarorder.DhCarOrderParamsVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * 敦煌-加购物车-订单(DhAddCarOrder)表服务实现类 + * + * @author rch + * @since 2022-11-17 09:12:00 + */ +@Service +public class DhAddCarOrderServiceImpl extends ServiceImpl implements DhAddCarOrderService { + + @Resource + private DhAddCarOrderDao dhAddCarOrderDao; + + @Resource + private DhCarGoodsDao dhCarGoodsDao; + + @Override + public DhAddCarOrder getByIdLock(Long id) { + return dhAddCarOrderDao.getByIdLock(id); + } + + @Override + public PageUtils searchPageList(IPage page, Wrapper ew) { + dhAddCarOrderDao.searchPageList(page, ew); + return new PageUtils(page.getTotal(), page.getRecords()); + } + + @Override + public DhCarOrderParamsVO getYdParams(Long id) { + DhCarOrderParamsVO dhCarOrderParamsVO = dhAddCarOrderDao.getYdParams(id); + if (ObjectUtil.isEmpty(dhCarOrderParamsVO)) { + return dhCarOrderParamsVO; + } + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("params_type", dhCarOrderParamsVO.getParamsType()); + queryWrapper.in("id", Arrays.asList(dhCarOrderParamsVO.getCarGoodIds().split(","))); + List DhCarGoods = dhCarGoodsDao.selectList(queryWrapper); + if (ObjectUtil.isEmpty(DhCarGoods)) { + return dhCarOrderParamsVO; + } + + List carGoodKeyList = new ArrayList<>(); + List carGoodLinkList = new ArrayList<>(); + for (DhCarGoods dhCarGoods:DhCarGoods) { + if (ParamsTypeEnum.KEY_WORD.eqValue(dhCarOrderParamsVO.getParamsType())) { + + DhCarGoodKeyVO dhCarGoodKeyVO = new DhCarGoodKeyVO(); + BeanUtil.copyProperties(dhCarGoods, dhCarGoodKeyVO); + carGoodKeyList.add(dhCarGoodKeyVO); + } else if (ParamsTypeEnum.LINK.eqValue(dhCarOrderParamsVO.getParamsType())) { + + DhCarGoodLinkVO dhCarGoodLinkVO = new DhCarGoodLinkVO(); + BeanUtil.copyProperties(dhCarGoods, dhCarGoodLinkVO); + carGoodLinkList.add(dhCarGoodLinkVO); + } else { + continue; + } + } + + if (ObjectUtil.isNotEmpty(carGoodKeyList)) { + dhCarOrderParamsVO.setCarGoodKeys(carGoodKeyList); + } + + if (ObjectUtil.isNotEmpty(carGoodLinkList)) { + dhCarOrderParamsVO.setCarGoodLinks(carGoodLinkList); + } + return dhCarOrderParamsVO; + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/DhAddCarServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/DhAddCarServiceImpl.java new file mode 100644 index 0000000..9b45a16 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/DhAddCarServiceImpl.java @@ -0,0 +1,108 @@ +package me.zhengjie.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.DhAddCarDao; +import me.zhengjie.entity.DhAddCar; +import me.zhengjie.entity.DhCarGoods; +import me.zhengjie.enums.ParamsTypeEnum; +import me.zhengjie.service.DhAddCarService; +import me.zhengjie.service.DhCarGoodsService; +import me.zhengjie.service.vo.dhaddcar.DhAddCarListVO; +import me.zhengjie.service.vo.dhaddcar.DhAddCarVO; +import me.zhengjie.service.vo.dhaddcar.DhAddCarYdParamsVO; +import me.zhengjie.service.vo.dhcargood.DhCarGoodKeyVO; +import me.zhengjie.service.vo.dhcargood.DhCarGoodLinkVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * 敦煌加入购物车(DhAddCar)表服务实现类 + * + * @author rch + * @since 2022-11-17 09:11:56 + */ +@Service +public class DhAddCarServiceImpl extends ServiceImpl implements DhAddCarService { + + @Resource + private DhAddCarDao dhAddCarDao; + @Resource + private DhCarGoodsService dhCarGoodsService; + + @Override + public PageUtils searchPageList(IPage page, Wrapper ew) { + dhAddCarDao.searchPageList(page, ew); + return new PageUtils(page.getTotal(), page.getRecords()); + } + + @Override + public DhAddCarVO getDetailById(Long id) { + DhAddCarVO dhAddCarVO = dhAddCarDao.getDetailById(id); + if (ObjectUtil.isEmpty(dhAddCarVO)) { + return dhAddCarVO; + } + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("params_type", dhAddCarVO.getParamsType()); + queryWrapper.in("id", Arrays.asList(dhAddCarVO.getCarGoodIds().split(","))); + List DhCarGoods = dhCarGoodsService.list(queryWrapper); + if (ObjectUtil.isEmpty(DhCarGoods)) { + return dhAddCarVO; + } + + List carGoodKeyList = new ArrayList<>(); + List carGoodLinkList = new ArrayList<>(); + for (DhCarGoods dhCarGoods:DhCarGoods) { + if (ParamsTypeEnum.KEY_WORD.eqValue(dhAddCarVO.getParamsType())) { + + DhCarGoodKeyVO dhCarGoodKeyVO = new DhCarGoodKeyVO(); + BeanUtil.copyProperties(dhCarGoods, dhCarGoodKeyVO); + carGoodKeyList.add(dhCarGoodKeyVO); + } else if (ParamsTypeEnum.LINK.eqValue(dhAddCarVO.getParamsType())) { + + DhCarGoodLinkVO dhCarGoodLinkVO = new DhCarGoodLinkVO(); + BeanUtil.copyProperties(dhCarGoods, dhCarGoodLinkVO); + carGoodLinkList.add(dhCarGoodLinkVO); + } else { + continue; + } + } + + if (ObjectUtil.isNotEmpty(carGoodKeyList)) { + dhAddCarVO.setCarGoodKeys(carGoodKeyList); + } + + if (ObjectUtil.isNotEmpty(carGoodLinkList)) { + dhAddCarVO.setCarGoodLinks(carGoodLinkList); + } + return dhAddCarVO; + } + + @Override + public DhAddCar getByIdLock(Long id) { + return dhAddCarDao.getByIdLock(id); + } + + @Override + public DhAddCarYdParamsVO getAddCarYdParams(Long id) { + DhAddCarYdParamsVO dhAddCarYdParamsVO = new DhAddCarYdParamsVO(); + DhAddCarVO dhAddCarVO = getDetailById(id); + if (ObjectUtil.isEmpty(dhAddCarVO)) { + return dhAddCarYdParamsVO; + } + + BeanUtil.copyProperties(dhAddCarVO, dhAddCarYdParamsVO); + return dhAddCarYdParamsVO; + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/DhCarGoodsServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/DhCarGoodsServiceImpl.java new file mode 100644 index 0000000..f18256a --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/DhCarGoodsServiceImpl.java @@ -0,0 +1,19 @@ +package me.zhengjie.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.DhCarGoodsDao; +import me.zhengjie.entity.DhCarGoods; +import me.zhengjie.service.DhCarGoodsService; +import org.springframework.stereotype.Service; + +/** + * 敦煌-加入购物车商品信息(DhCarGoods)表服务实现类 + * + * @author makejava + * @since 2022-11-17 09:12:04 + */ +@Service +public class DhCarGoodsServiceImpl extends ServiceImpl implements DhCarGoodsService { + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/FileUploadServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/FileUploadServiceImpl.java new file mode 100644 index 0000000..37d22fa --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/FileUploadServiceImpl.java @@ -0,0 +1,130 @@ +package me.zhengjie.service.impl; + + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.config.PropertiesConfig; +import me.zhengjie.config.SystemConfig; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.service.FileUploadService; +import org.springframework.stereotype.Service; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static me.zhengjie.error.ErrorCodeEnum.UPLOAD_IMG_FORMAT_ERROR; +/** + *

+ * 图片上传服务 + *

+ * + * @Author xx + * @Date 2021/7/26 + **/ +@Slf4j +@Service +public class FileUploadServiceImpl implements FileUploadService { + + @Resource + private Snowflake snowflake; + @Resource + private PropertiesConfig config; + + @Override + public List uploadify(HttpServletRequest request, HttpServletResponse response) throws IOException { + response.setCharacterEncoding("utf-8"); + response.setContentType("application/json;charset=utf-8"); + response.setHeader("Cache-Control", "no-cache"); + Integer type = Convert.toInt(request.getParameter("type")); + + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map fileMap = multipartRequest.getFileMap(); + // 如果有传文件路径,则为替换文件, + String fileUrl = request.getParameter("fileUrl"); + + List returnStr = new ArrayList(); + if (ObjectUtil.isNotEmpty(fileUrl)) { + for (String key : fileMap.keySet()) { + MultipartFile multipartFile = fileMap.get(key); + isTrue(multipartFile,type); + // 文件覆盖 + File uploadFile = new File(SystemConfig.IMG_PATH + "/" + fileUrl); + + FileCopyUtils.copy(multipartFile.getBytes(), uploadFile); + returnStr.add(MapUtil.of("path", fileUrl)); + break; + } + }else { + for (String key : fileMap.keySet()) { + MultipartFile mf = fileMap.get(key); + isTrue(mf,type); + // 文件保存路径 + String filePath = config.getUploadImgPath().get(type); + filePath = filePath + LocalDate.now().toString().replaceAll("-","")+"/"; + + File file = new File(SystemConfig.IMG_PATH + filePath); + if (!file.exists()) { + file.mkdirs(); + } + // 文件名 + String fileEnd = mf.getOriginalFilename(); + fileEnd = fileEnd.substring(fileEnd.lastIndexOf(".")); + String newfileName = snowflake.nextIdStr() + fileEnd; + // 文件保存到本地 + File uploadFile = new File(file.getAbsolutePath() + "/" + newfileName); + FileCopyUtils.copy(mf.getBytes(), uploadFile); + String path = filePath + newfileName; + returnStr.add(MapUtil.of("path", path)); + } + } + + return returnStr; + } + + + /** + * 上传文件验证,如果验证不通过将抛出异常 + * + * @author: zeng + */ + private void isTrue(MultipartFile mf,Integer type) { + int maxFileSize = SystemConfig.MAX_FILE_SIZE; + if (type.equals(8)){ + maxFileSize = SystemConfig.VIDEO_MAX_FILE_SIZE; + } + if (mf.getSize()>(maxFileSize*1024*1024)){ + throw new BadRequestException(2005, "文件大小不超过于" + maxFileSize + "M"); + } + String fileEnd = mf.getOriginalFilename(); + fileEnd = fileEnd.substring(fileEnd.lastIndexOf(".")); + // 文件格式验证 + if (!imgFormat(fileEnd.substring(1))){ + UPLOAD_IMG_FORMAT_ERROR.setDesc(fileEnd+" 上传图片格式错误"); + throw new BadRequestException(UPLOAD_IMG_FORMAT_ERROR); + } + } + + + private boolean imgFormat(String fileEnd) { + for (String s : config.getSustainImgFormat()) { + if (s.equalsIgnoreCase(fileEnd)) { + return true; + } + } + return false; + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/LoginIpServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/LoginIpServiceImpl.java new file mode 100644 index 0000000..bf9256f --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/LoginIpServiceImpl.java @@ -0,0 +1,121 @@ +package me.zhengjie.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.RequiredArgsConstructor; +import me.zhengjie.dao.LoginIpDao; +import me.zhengjie.entity.LoginIp; +import me.zhengjie.service.LoginIpService; +import me.zhengjie.service.vo.LoginIpVO; +import me.zhengjie.utils.DateUtil; +import me.zhengjie.utils.LoginIpUtil; +import me.zhengjie.utils.PageUtils; +import me.zhengjie.utils.RedisUtils; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +/** + * (LoginIp)表服务实现类 + * + * @author zeng + * @since 2022-03-21 14:07:01 + */ +@Service +@RequiredArgsConstructor +public class LoginIpServiceImpl extends ServiceImpl implements LoginIpService { + + final RedisUtils redisUtils; + + @Override + public PageUtils getList(IPage iPage) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.orderByDesc(LoginIp::getId); + page(iPage, lqw); + ArrayList arrayList = new ArrayList(); + for (LoginIp record : iPage.getRecords()) { + LoginIpVO loginIpVO = new LoginIpVO(record); + arrayList.add(loginIpVO); + } + return new PageUtils(iPage.getTotal(), arrayList); + } + + @Override + public boolean addIp(LoginIp ip) { + if (save(ip)) { + redisUtils.lPush(LoginIpService.LOGIN_IP_LIST, ip); + return true; + } + return false; + } + + @Override + public List getAll() { + List list = redisUtils.lGet(LoginIpService.LOGIN_IP_LIST, 0, -1); + if (ObjectUtil.isEmpty(list)) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.ge(LoginIp::getVaildTime, DateUtil.getCurrentTime()).or(q->q.eq(LoginIp::getVaildTime,"")); + return list(lqw); + } + return list; + } + + @Override + public boolean updateIp(LoginIp ip) { + if (updateById(ip)) { + List list = getAll(); + for (LoginIp loginIp : list) { + if (loginIp.getId().equals(ip.getId())) { + redisUtils.lRemove(LoginIpService.LOGIN_IP_LIST, 1, loginIp); + break; + } + } + redisUtils.lPush(LoginIpService.LOGIN_IP_LIST, ip); + return true; + } + return false; + } + + @Override + public boolean deleteIp(Integer id) { + if (removeById(id)) { + List list = getAll(); + for (LoginIp loginIp : list) { + if (loginIp.getId().equals(id)) { + redisUtils.lRemove(LoginIpService.LOGIN_IP_LIST, 1, loginIp); + } + } + } + return false; + } + + @Override + public boolean whiteListFlag(String ip) { + List ipList = getAll(); + if (ObjectUtil.isNotEmpty(ipList)) { + boolean flag = false; + for (LoginIp loginIp : ipList) { + if (ObjectUtil.isNotEmpty(loginIp.getVaildTime())) { + LocalDateTime localDateTime = DateUtil.parseLocalDateTimeFormatyMdHms(loginIp.getVaildTime()); + if (localDateTime.isBefore(LocalDateTime.now())) { + // 失效 + redisUtils.lRemove(LoginIpService.LOGIN_IP_LIST, 1, loginIp); + continue; + } + } + if (LoginIpUtil.ipExistsInRange(ip, loginIp.getIpStart(), loginIp.getIpEnd())) { + return true; + } + } + return false; + } + return true; + } + + +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/SettingSiteServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/SettingSiteServiceImpl.java new file mode 100644 index 0000000..56538f3 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/SettingSiteServiceImpl.java @@ -0,0 +1,75 @@ +package me.zhengjie.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.dao.SettingSiteDao; +import me.zhengjie.entity.CtSettingSite; +import me.zhengjie.service.SettingSiteService; +import me.zhengjie.utils.RedisUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +import static me.zhengjie.constant.PublicConstant.CACHE_OVER_TIME; +import static me.zhengjie.constant.PublicConstant.SETTING_SITE_PREFIX; + +/** + * 站点配置(CtSettingSite)表服务实现类 + * + * @author makejava + * @since 2021-11-17 17:02:11 + */ +@Service +@Slf4j +public class SettingSiteServiceImpl extends ServiceImpl implements SettingSiteService { + @Resource + private RedisUtils redisUtils; + @Resource + private SettingSiteDao settingSiteDao; + + @Override + public String getValue(String key) { + String prefix = String.format(SETTING_SITE_PREFIX, key); + Object value = redisUtils.get(prefix); + + if (ObjectUtil.isNotEmpty(value)) { + return value.toString(); + } + String valueByKey = settingSiteDao.getValueByKey(key); + redisUtils.set(prefix, valueByKey, CACHE_OVER_TIME); + return valueByKey; + } + + @Override + public boolean saveOrUpdateByKey(String key, String value) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper(); + lqw.eq(CtSettingSite::getSettingKey, key); + boolean boo; + if (count(lqw) > 0) { + LambdaUpdateWrapper luw = new LambdaUpdateWrapper(); + luw.eq(CtSettingSite::getSettingKey, key); + luw.set(CtSettingSite::getSettingValue, value); + boo = update(luw); + }else { + CtSettingSite site = new CtSettingSite(); + site.setContent(""); + site.setSettingKey(key); + site.setSettingValue(value); + boo = save(site); + } + if (boo) { + String prefix = String.format(SETTING_SITE_PREFIX, key); + redisUtils.set(prefix, value, CACHE_OVER_TIME); + } + return boo; + } + + @Override + public Boolean getGooleAuthSwitch() { + return "1".equals(settingSiteDao.getValueByKey("googleAuth")) ? true : false; + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/SysQuartzJobServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/SysQuartzJobServiceImpl.java new file mode 100644 index 0000000..1975f7c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/SysQuartzJobServiceImpl.java @@ -0,0 +1,63 @@ +//package me.zhengjie.service.impl; +// +//import cn.hutool.core.bean.BeanUtil; +//import com.baomidou.mybatisplus.core.conditions.Wrapper; +//import com.baomidou.mybatisplus.core.metadata.IPage; +//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +//import lombok.RequiredArgsConstructor; +//import me.zhengjie.dao.SysQuartzJobDao; +//import me.zhengjie.entity.SysQuartzJob; +//import me.zhengjie.enums.TaskTypeEnum; +//import me.zhengjie.service.SysQuartzJobService; +//import me.zhengjie.service.vo.SysQuartzJobListVO; +//import me.zhengjie.utils.PageUtils; +//import me.zhengjie.utils.RedisUtils; +//import org.apache.logging.log4j.core.layout.SyslogLayout; +//import org.springframework.stereotype.Service; +// +//import javax.annotation.Resource; +// +///** +// * 定时任务(SysQuartzJob)表服务实现类 +// * +// * @author rch +// * @since 2022-07-20 +// */ +//@Service +//@RequiredArgsConstructor +//public class SysQuartzJobServiceImpl extends ServiceImpl implements SysQuartzJobService { +// +// @Resource +// private SysQuartzJobService sysQuartzJobService; +// @Resource +// private SysQuartzJobDao sysQuartzJobDao; +// +// private final QuartzJobRepository quartzJobRepository; +// private final QuartzLogRepository quartzLogRepository; +// private final QuartzManage quartzManage; +// private final RedisUtils redisUtils; +// +// @Override +// public PageUtils searchPageList(IPage page, Wrapper wrapper) { +// sysQuartzJobDao.searchPageList(page,wrapper); +// return new PageUtils(page.getTotal(),page.getRecords()); +// } +// +// @Override +// public boolean modifyJobStatus(Long jobId) { +// SysQuartzJob sysQuartzJobIsExist = sysQuartzJobService.getById(jobId); +// if(sysQuartzJobIsExist == null){ +// return false; +// }else{ +// SysQuartzJob sysQuartzJob = new SysQuartzJob(); +// BeanUtil.copyProperties(sysQuartzJobIsExist,sysQuartzJob); +// if(sysQuartzJob.getIsPause() == 0){ +// sysQuartzJob.setIsPause(1); +// }else{ +// sysQuartzJob.setIsPause(0); +// } +// return sysQuartzJobService.updateById(sysQuartzJob); +// } +// } +//} +// diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/SysQuartzLogServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/SysQuartzLogServiceImpl.java new file mode 100644 index 0000000..aac7886 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/SysQuartzLogServiceImpl.java @@ -0,0 +1,35 @@ +package me.zhengjie.service.impl; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhengjie.dao.SysQuartzJobDao; +import me.zhengjie.dao.SysQuartzLogDao; +import me.zhengjie.entity.SysQuartzJob; +import me.zhengjie.entity.SysQuartzLog; +import me.zhengjie.service.SysQuartzLogService; +import me.zhengjie.service.vo.SysQuartzLogListVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 定时任务(SysQuartzJob)表服务实现类 + * + * @author rch + * @since 2022-07-20 + */ +@Service +public class SysQuartzLogServiceImpl extends ServiceImpl implements SysQuartzLogService { + + @Resource + private SysQuartzLogDao sysQuartzLogDao; + + @Override + public PageUtils searchPageList(IPage page, Wrapper wrapper) { + sysQuartzLogDao.searchPageList(page, wrapper); + return new PageUtils(page.getTotal(), page.getRecords()); + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/impl/YdQuartzServiceImpl.java b/wjcy-common/src/main/java/me/zhengjie/service/impl/YdQuartzServiceImpl.java new file mode 100644 index 0000000..d0b54b9 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/impl/YdQuartzServiceImpl.java @@ -0,0 +1,464 @@ +package me.zhengjie.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.config.BeanFactory; +import me.zhengjie.constant.Constants; +import me.zhengjie.entity.*; +import me.zhengjie.entity.quartz.*; +import me.zhengjie.enums.*; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.service.*; +import me.zhengjie.service.redission.LockCallBack; +import me.zhengjie.utils.HttpClientUtil; +import me.zhengjie.utils.RedissonUtil; +import org.redisson.api.RLock; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * 影刀定时任务Service 实现类 + * + * @author rch + * @create 2022-08-01 + */ +@Service +@Slf4j +public class YdQuartzServiceImpl implements YdQuartzService { + + @Resource + private CtRebotService ctRebotService; + @Resource + private CtApplyService ctApplyService; + @Resource + private RedissonUtil redissonUtil; + @Resource + private CtClickFarmingService ctClickFarmingService; + @Resource + private CtBuyerService ctBuyerService; + @Resource + private CtClickOrderService ctClickOrderService; + @Resource + private DhAddCarOrderService dhAddCarOrderService; + @Resource + private DhAddCarService dhAddCarService; + @Resource + private CtBrowseService ctBrowseService; + + @Override + public Object executeOnLock(String lockKey, long time, long timeout, LockCallBack callBack) throws Exception { + RLock lock = redissonUtil.getRLock(lockKey); + String currentTime = me.zhengjie.utils.DateUtil.getCurrentTime(); + try { + log.info(currentTime + " 获取锁============= {}",lockKey); + if (lock.tryLock(time, timeout, TimeUnit.SECONDS)) { + System.out.println("run111 ====== lock success "); + return callBack.execute(true); + } else { + System.out.println("run111 ====== lock fail "); + throw new BadRequestException(" lock fail "); + } + } catch (Exception e) { + throw e; + } finally { + lock.unlock(); + log.info(currentTime+" 释放锁============= {}",lockKey); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public String exec(String str) throws Exception { + Boss boss = JSONUtil.toBean(str, Boss.class); + // 1.根据设备id获取设备信息 for update + CtRebot ctRebot = ctRebotService.getByAccountNameLock(boss.getAccountName()); + System.out.println(JSONUtil.toJsonStr(ctRebot)); + if (ObjectUtil.isEmpty(ctRebot) || !YesOrNoEnum.NO.eqValue(ctRebot.getStatus())) { + // 有问题 不执行 + log.info("机器人设备信息不存在,或者机器人状态不可用!"); + throw new BadRequestException("机器人设备信息不存在,或者机器人状态不可用!"); + } + + // TODO 这里需要根据应用获取 appKey appSecret信息 + CtApply ctApply = ctApplyService.getById(boss.getApplyId()); + if (ObjectUtil.isEmpty(ctApply) + || ObjectUtil.isEmpty(ctApply.getRobotUuid()) + || ObjectUtil.isEmpty(ctApply.getAccessKeyId()) + || ObjectUtil.isEmpty(ctApply.getAccessKeySecret())) { + log.info("影刀应用信息不存在,或者影刀应用信息异常!"); + throw new BadRequestException("影刀应用信息不存在,或者影刀应用信息异常!"); + } + + // 判断买家是否占用 + List paramList = boss.getParams().stream().filter(n->n.getName().equals("account")).collect(Collectors.toList()); + if (ObjectUtil.isEmpty(paramList)) { + throw new BadRequestException("买家信息不存在!"); + } + String buyerName = paramList.get(0).getValue(); + CtBuyer ctBuyer = ctBuyerService.getBuyerOccupyStatusLock(buyerName); + if (ObjectUtil.isEmpty(ctBuyer) || BuyerOccupyStatusEnum.OCCUPIED.value().equals(ctBuyer.getOccupyStatus())) { + throw new BadRequestException("买家信息不存在,或者已占用状态!"); + } + + boss.setRobotUuid(ctApply.getRobotUuid()); + // token + Map params = new HashMap<>(16); + params.put("accessKeyId", ctApply.getAccessKeyId()); + params.put("accessKeySecret", ctApply.getAccessKeySecret()); + SecreInfo secreInfo = JSONUtil.toBean(HttpClientUtil.getHttp(Constants.GET_SECRET, params), SecreInfo.class); + if (!secreInfo.getSuccess()) { + log.info("=========鉴权异常=========="); + throw new BadRequestException("请求影刀鉴权异常!"); + } + String token = secreInfo.getData().getAccessToken(); + System.out.println("====token===="); + Map headers = new HashMap<>(16); + headers.put("Accept", "application/json"); + headers.put("Content-Type", "application/json;charset=utf-8"); + headers.put("authorization", "Bearer " + token); + + // 判断是否在线 + RebotStatu rebotStatu = new RebotStatu(ctRebot.getRobotClientUuid(), ctRebot.getAccountName()); + String returnStr = HttpClientUtil.postJson(Constants.REBOT_STATU, headers, JSONUtil.toJsonStr(rebotStatu), "utf-8"); + RebotStatuReturn rebotStatuReturn = JSONUtil.toBean(returnStr, RebotStatuReturn.class); + // 状态 connected:已连接 idle:空闲 running:运行中 allocated:已分配 abnormal:异常 offline:离线 + if (RobotStatusEnum.OFFLINE.value().equals(rebotStatuReturn.getData().getStatus())) { + log.info("=======设备不在线====="); + throw new BadRequestException("设备不在线!"); + } else if (RobotStatusEnum.RUNNING.value().equals(rebotStatuReturn.getData().getStatus())) { + log.info("=======设备运行中====="); + throw new BadRequestException("设备运行中!"); + } else if (RobotStatusEnum.ALLOCATED.value().equals(rebotStatuReturn.getData().getStatus())) { + log.info("=======设备已分配====="); + throw new BadRequestException("设备已分配!"); + } else if (RobotStatusEnum.ABNORMAL.value().equals(rebotStatuReturn.getData().getStatus())) { + log.info("=======设备异常====="); + throw new BadRequestException("设备异常!"); + } + // 启动Job + String returnJobStr = null; + CtRebot updateCtRebot = new CtRebot(); + updateCtRebot.setId(ctRebot.getId()); + updateCtRebot.setStatus(YesOrNoEnum.YES.value()); + CtRebotService ctRebotService = BeanFactory.getBean(CtRebotService.class); + Boolean resultBoolean = ctRebotService.updateById(updateCtRebot); + if (resultBoolean) { + // 修改买家信息占用状态 + ctBuyer.setOccupyStatus(BuyerOccupyStatusEnum.OCCUPIED.value()); + if (ctBuyerService.updateById(ctBuyer)) { + returnJobStr = HttpClientUtil.postJson(Constants.STAT_JOB_URL, headers, JSONUtil.toJsonStr(boss), "utf-8"); + StartYdReturnInfo startYdReturnInfo = JSONUtil.toBean(returnJobStr, StartYdReturnInfo.class); + if (startYdReturnInfo.getSuccess()) { + log.info("run111 执行成功,返回结果为: {}" + returnJobStr); + } else { + throw new BadRequestException(startYdReturnInfo.getMsg()); + } + } else { + log.info("run111 执行成功。 但是修改设备状态失败----- 此处该预警"); + throw new BadRequestException("修改设备状态失败!"); + } + } else { + log.info("run111 执行成功。 但是修改设备状态失败----- 此处该预警"); + throw new BadRequestException("修改设备状态失败!"); + } + return returnJobStr; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean clickFarmExec(String str) throws Exception { + System.out.println("================================ClickFarmTask=========================4"); + // 只有真正发起了执行 状态才修改为执行中 回调后修改成功 或者失败 + // TODO 这里根据响应结果 修改平台状态 类型,根据boss里面的 执行中 别的任务如果想再执行这个刷单信息, 不允许执行。 执行前加锁查询, 带执行状态才可以往下走 + // 修改状态为 执行中。 + + Boss boss = JSONUtil.toBean(str, Boss.class); + List paramList = boss.getParams(); + // 获取ID + String id = paramList.stream().filter(p->p.getName().equals("id")).collect(Collectors.toList()).get(0).getValue(); + CtClickFarming ctClickFarming = ctClickFarmingService.getByIdLock(Long.valueOf(id)); + if (ClickFarmingStatusEnum.IN_EXECUTION.value().equals(ctClickFarming.getStatus())) { + throw new BadRequestException("该定时任务对应的刷单信息已经执行中状态,请检查后重试!"); + } + + if (ClickFarmingStatusEnum.EXECUTION_SUCCESS.value().equals(ctClickFarming.getStatus())) { + throw new BadRequestException("该定时任务对应的刷单信息已执行成功,请检查后重试!"); + } + + String returnStartJobStr = exec(str); + if (ObjectUtil.isEmpty(returnStartJobStr)) { + throw new BadRequestException("调用影刀启动任务失败! response:" + returnStartJobStr); + } + + YdStartReturn ydStartReturn = JSONUtil.toBean(returnStartJobStr, YdStartReturn.class); + if (!ydStartReturn.getSuccess()) { + throw new BadRequestException("调用影刀启动任务失败! response:" + returnStartJobStr); + } + + // 修改状态 带执行 - 》 执行中 + CtClickFarming updateCtClickFarming = new CtClickFarming(); + updateCtClickFarming.setId(ctClickFarming.getId()); + updateCtClickFarming.setStatus(ClickFarmingStatusEnum.IN_EXECUTION.value()); + return ctClickFarmingService.updateById(updateCtClickFarming); + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean addCarExec(String str) throws Exception { + System.out.println("================================ClickFarmTask=========================4"); + // 只有真正发起了执行 状态才修改为执行中 回调后修改成功 或者失败 + // TODO 这里根据响应结果 修改平台状态 类型,根据boss里面的 执行中 别的任务如果想再执行这个刷单信息, 不允许执行。 执行前加锁查询, 带执行状态才可以往下走 + // 修改状态为 执行中。 + + Boss boss = JSONUtil.toBean(str, Boss.class); + List paramList = boss.getParams(); + // 获取ID + String id = paramList.stream().filter(p->p.getName().equals("id")).collect(Collectors.toList()).get(0).getValue(); + DhAddCar dhAddCar = dhAddCarService.getByIdLock(Long.valueOf(id)); + if (!DhAddCarStatusEnum.TOBE_EXECUTION.value().equals(dhAddCar.getStatus()) && !DhAddCarStatusEnum.ADD_CARD_FAILE.value().equals(dhAddCar.getStatus())) { + throw new BadRequestException("该定时任务对应的敦煌加购必须带执行或执行失败,请检查后重试!"); + } + + if (DhAddCarStatusEnum.Add_CARD_SUCCESS.value().equals(dhAddCar.getStatus())) { + throw new BadRequestException("该定时任务对应的敦煌加购已执行成功,请检查后重试!"); + } + + String returnStartJobStr = exec(str); + if (ObjectUtil.isEmpty(returnStartJobStr)) { + throw new BadRequestException("调用影刀启动任务失败! response:" + returnStartJobStr); + } + + YdStartReturn ydStartReturn = JSONUtil.toBean(returnStartJobStr, YdStartReturn.class); + if (!ydStartReturn.getSuccess()) { + throw new BadRequestException("调用影刀启动任务失败! response:" + returnStartJobStr); + } + + // 修改状态 带执行 - 》 执行中 + DhAddCar updateDhAddCar = new DhAddCar(); + updateDhAddCar.setId(dhAddCar.getId()); + updateDhAddCar.setStatus(ClickFarmingStatusEnum.IN_EXECUTION.value()); + return dhAddCarService.updateById(updateDhAddCar); + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean catchOrderExec(String str) throws Exception { + System.out.println("================================catchOrderExec=========================4"); + // 只有真正发起了执行 状态才修改为执行中 回调后修改成功 或者失败 + // TODO 这里根据响应结果 修改平台状态 类型,根据boss里面的 执行中 别的任务如果想再执行这个刷单信息, 不允许执行。 执行前加锁查询, 带执行状态才可以往下走 + // 修改状态为 执行中。 + + Boss boss = JSONUtil.toBean(str, Boss.class); + List paramList = boss.getParams(); + // 获取ID + String id = paramList.stream().filter(p->p.getName().equals("id")).collect(Collectors.toList()).get(0).getValue(); + DhAddCar dhAddCar = dhAddCarService.getByIdLock(Long.valueOf(id)); + if (!DhAddCarStatusEnum.TO_BE_CATCH_ORDER.value().equals(dhAddCar.getStatus()) && !DhAddCarStatusEnum.CATCH_ORDER_FAILE.value().equals(dhAddCar.getStatus())) { + throw new BadRequestException("该定时任务对应的敦煌加购抓单必须是待抓单或者抓单失败状态!"); + } + + String returnStartJobStr = exec(str); + if (ObjectUtil.isEmpty(returnStartJobStr)) { + throw new BadRequestException("调用影刀启动任务失败! response:" + returnStartJobStr); + } + + YdStartReturn ydStartReturn = JSONUtil.toBean(returnStartJobStr, YdStartReturn.class); + if (!ydStartReturn.getSuccess()) { + throw new BadRequestException("调用影刀启动任务失败! response:" + returnStartJobStr); + } + + // 修改状态 带抓单/抓单失败 - 》 抓单中 + DhAddCar updateDhAddCar = new DhAddCar(); + updateDhAddCar.setId(dhAddCar.getId()); + updateDhAddCar.setStatus(DhAddCarStatusEnum.CATCH_ORDER_ING.value()); + return dhAddCarService.updateById(updateDhAddCar); + } + + + // TODO 这里查询任务结果然后返回, 在回调哪里 调用这个方法,然后解析参数, 入参 出参 和执行结果状态等。 + @Override + @Transactional(rollbackFor = Exception.class) + public JobQueryByUuidReturn queryJobUuid(String uuid, String accessKeyId, String accessKeySecret) { + // token + Map params = new HashMap<>(16); + params.put("accessKeyId", accessKeyId); + params.put("accessKeySecret", accessKeySecret); + String response = HttpClientUtil.getHttp(Constants.GET_SECRET, params); + log.error("鉴权请求结果:" +response); + SecreInfo secreInfo = JSONUtil.toBean(response, SecreInfo.class); + if (ObjectUtil.isEmpty(secreInfo) || !secreInfo.getSuccess()) { + log.info("=========鉴权异常=========="); + throw new BadRequestException("请求影刀鉴权异常!"); + } + String token = secreInfo.getData().getAccessToken(); + Map headers = new HashMap<>(16); + headers.put("Accept", "application/json"); + headers.put("Content-Type", "application/json;charset=utf-8"); + headers.put("authorization", "Bearer " + token); + + // 判断是否在线 + JobQueryByUuid jobQueryByUuid = new JobQueryByUuid(); + jobQueryByUuid.setJobUuid(uuid); + String returnStr = HttpClientUtil.postJson(Constants.QUERY_JOB_URL, headers, JSONUtil.toJsonStr(jobQueryByUuid), "utf-8"); + log.info("====returnStr====" + returnStr); + JobQueryByUuidReturn jobQueryByUuidReturn = JSONUtil.toBean(returnStr, JobQueryByUuidReturn.class); + + return jobQueryByUuidReturn; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean clickFarmSuppleMentExec(String str) throws Exception { + System.out.println("================================ClickFarmSuppleMentTask=========================4"); + // 只有真正发起了执行 状态才修改为执行中 回调后修改成功 或者失败 + // TODO 这里根据响应结果 修改平台状态 类型,根据boss里面的 执行中 别的任务如果想再执行这个刷单信息, 不允许执行。 执行前加锁查询, 带执行状态才可以往下走 + // 修改状态为 执行中。 + + Boss boss = JSONUtil.toBean(str, Boss.class); + List paramList = boss.getParams(); + // 获取ID + String id = paramList.stream().filter(p->p.getName().equals("id")).collect(Collectors.toList()).get(0).getValue(); + CtClickFarming ctClickFarming = ctClickFarmingService.getByIdLock(Long.valueOf(id)); + if (!ClickFarmingStatusEnum.AWAITING_PAYMENT.value().equals(ctClickFarming.getStatus())) { + throw new BadRequestException("仅待支付状态才允许补录,请检查后重试!"); + } + + String returnStartJobStr = exec(str); + if (ObjectUtil.isEmpty(returnStartJobStr)) { + throw new BadRequestException("调用影刀启动任务失败! response:" + returnStartJobStr); + } + + YdStartReturn ydStartReturn = JSONUtil.toBean(returnStartJobStr, YdStartReturn.class); + if (!ydStartReturn.getSuccess()) { + throw new BadRequestException("调用影刀启动任务失败! response:" + returnStartJobStr); + } + + // 修改状态 带执行 - 》 执行中 + CtClickFarming updateCtClickFarming = new CtClickFarming(); + updateCtClickFarming.setId(ctClickFarming.getId()); + updateCtClickFarming.setStatus(ClickFarmingStatusEnum.IN_EXECUTION.value()); + return ctClickFarmingService.updateById(updateCtClickFarming); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Object dhWellReceivedExec(String str) throws Exception { + System.out.println("================================WellReceivedExec=========================4"); + // 只有真正发起了执行 状态才修改为执行中 回调后修改成功 或者失败 + // 修改状态为 执行中。 + + Boss boss = JSONUtil.toBean(str, Boss.class); + List paramList = boss.getParams(); + // 获取ID + String id = paramList.stream().filter(p->p.getName().equals("id")).collect(Collectors.toList()).get(0).getValue(); + DhAddCarOrder dhAddCarOrder = dhAddCarOrderService.getByIdLock(Long.valueOf(id)); + if (ClickOrderStatusEnum.IN_EXECUTION.value().equals(dhAddCarOrder.getStatus())) { + throw new BadRequestException("该定时任务对应的敦煌加购好评信息已经执行中状态,请检查后重试!"); + } + + if (ClickFarmingStatusEnum.EXECUTION_SUCCESS.value().equals(dhAddCarOrder.getStatus())) { + throw new BadRequestException("该定时任务对应的敦煌加购好评信息已执行成功,请检查后重试!"); + } + + String returnStartJobStr = exec(str); + if (ObjectUtil.isEmpty(returnStartJobStr)) { + throw new BadRequestException("调用影刀启动任务失败! response:" + returnStartJobStr); + } + + YdStartReturn ydStartReturn = JSONUtil.toBean(returnStartJobStr, YdStartReturn.class); + if (!ydStartReturn.getSuccess()) { + throw new BadRequestException("调用影刀启动任务失败! response:" + returnStartJobStr); + } + + // 修改状态 带执行 - 》 执行中 + DhAddCarOrder updateDhAddCarOrder = new DhAddCarOrder(); + updateDhAddCarOrder.setId(dhAddCarOrder.getId()); + updateDhAddCarOrder.setStatus(ClickOrderStatusEnum.IN_EXECUTION.value()); + return dhAddCarOrderService.updateById(updateDhAddCarOrder); + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public Object wellReceivedExec(String str) throws Exception { + System.out.println("================================WellReceivedExec=========================4"); + // 只有真正发起了执行 状态才修改为执行中 回调后修改成功 或者失败 + // 修改状态为 执行中。 + + Boss boss = JSONUtil.toBean(str, Boss.class); + List paramList = boss.getParams(); + // 获取ID + String id = paramList.stream().filter(p->p.getName().equals("id")).collect(Collectors.toList()).get(0).getValue(); + CtClickOrder ctClickOrder = ctClickOrderService.getByIdLock(Long.valueOf(id)); + if (ClickOrderStatusEnum.IN_EXECUTION.value().equals(ctClickOrder.getStatus())) { + throw new BadRequestException("该定时任务对应的敦煌加购好评信息已经执行中状态,请检查后重试!"); + } + + if (ClickFarmingStatusEnum.EXECUTION_SUCCESS.value().equals(ctClickOrder.getStatus())) { + throw new BadRequestException("该定时任务对应的敦煌加购好评信息已执行成功,请检查后重试!"); + } + + String returnStartJobStr = exec(str); + if (ObjectUtil.isEmpty(returnStartJobStr)) { + throw new BadRequestException("调用影刀启动任务失败! response:" + returnStartJobStr); + } + + YdStartReturn ydStartReturn = JSONUtil.toBean(returnStartJobStr, YdStartReturn.class); + if (!ydStartReturn.getSuccess()) { + throw new BadRequestException("调用影刀启动任务失败! response:" + returnStartJobStr); + } + + // 修改状态 带执行 - 》 执行中 + CtClickOrder updateCtClickOrder = new CtClickOrder(); + updateCtClickOrder.setId(ctClickOrder.getId()); + updateCtClickOrder.setStatus(ClickOrderStatusEnum.IN_EXECUTION.value()); + return ctClickOrderService.updateById(updateCtClickOrder); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Object browseTaskExec(String str) throws Exception { + System.out.println("================================browseTaskExec=========================4"); + // 只有真正发起了执行 状态才修改为执行中 回调后修改成功 或者失败 + // 修改状态为 执行中。 + + Boss boss = JSONUtil.toBean(str, Boss.class); + List paramList = boss.getParams(); + // 获取ID + String id = paramList.stream().filter(p->p.getName().equals("id")).collect(Collectors.toList()).get(0).getValue(); + CtBrowse ctBrowse = ctBrowseService.getByIdLock(Long.valueOf(id)); + if (ClickOrderStatusEnum.IN_EXECUTION.value().equals(ctBrowse.getStatus())) { + throw new BadRequestException("该定时任务对应的订单信息已经执行中状态,请检查后重试!"); + } + + if (ClickFarmingStatusEnum.EXECUTION_SUCCESS.value().equals(ctBrowse.getStatus())) { + throw new BadRequestException("该定时任务对应的订单信息已执行成功,请检查后重试!"); + } + + String returnStartJobStr = exec(str); + if (ObjectUtil.isEmpty(returnStartJobStr)) { + throw new BadRequestException("调用影刀启动任务失败! response:" + returnStartJobStr); + } + + YdStartReturn ydStartReturn = JSONUtil.toBean(returnStartJobStr, YdStartReturn.class); + if (!ydStartReturn.getSuccess()) { + throw new BadRequestException("调用影刀启动任务失败! response:" + returnStartJobStr); + } + + // 修改状态 带执行 - 》 执行中 + CtBrowse updateCtBrowse = new CtBrowse(); + updateCtBrowse.setId(ctBrowse.getId()); + updateCtBrowse.setStatus(ClickOrderStatusEnum.IN_EXECUTION.value()); + return ctBrowseService.updateById(updateCtBrowse); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/redission/LockCallBack.java b/wjcy-common/src/main/java/me/zhengjie/service/redission/LockCallBack.java new file mode 100644 index 0000000..8d8b5ff --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/redission/LockCallBack.java @@ -0,0 +1,8 @@ +package me.zhengjie.service.redission; + +@FunctionalInterface +public interface LockCallBack { + + Object execute(T t); + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/AdminGoogleAuthInfoVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/AdminGoogleAuthInfoVO.java new file mode 100644 index 0000000..4e5973e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/AdminGoogleAuthInfoVO.java @@ -0,0 +1,31 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * Admin 秘钥信息 + *

+ * + * @author: rch + * @since: 2020-08-26 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class AdminGoogleAuthInfoVO { + + /** Google 总开关 */ + private Boolean gogoleAuthSwitch; + + /** 用户信息 */ + private String userName; + + /** 二维码url 信息 */ + private String qrBarCodeUrl; + + /** 明文秘钥 */ + private String secret; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/BuyOrderResponseAddressVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/BuyOrderResponseAddressVO.java new file mode 100644 index 0000000..2364b02 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/BuyOrderResponseAddressVO.java @@ -0,0 +1,39 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 下注成功订单响应收货地址信息(CtResponseOrderAddress)表实体类 + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BuyOrderResponseAddressVO { + + /** 地址1 */ + private String addressline1; + /** 国家 */ + private String country; + /** 州 */ + private String state; + /** 电话 */ + private String tel; + /** lastname */ + private String lastname; + /** 税号 */ + private String vatNumber; + /** 城市 */ + private String city; + /** 地址2 */ + private String addressline2; + /** firstname */ + private String firstname; + /** 邮政编码 */ + private String postalcode; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/BuyOrderResponseOrderVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/BuyOrderResponseOrderVO.java new file mode 100644 index 0000000..be0997d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/BuyOrderResponseOrderVO.java @@ -0,0 +1,54 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 下单成功响应订单商品信息(CtResponseOrder)表实体类 + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BuyOrderResponseOrderVO { + + private Long id; + /** 运费 */ + private Double shipCost; + /** 产品总价 */ + private Double totalPriceOfProduct; + /** 备货期 */ + private Double leadingTime; + /** 订单总价 */ + private Double orderTotal; + /** 卖家Id */ + private String supplierId; + /** 卖家店铺coupon */ + private Double couponOfSeller; + /** 运输方式 */ + private String shipType; + /** 订单优惠 */ + private Double orderSave; + /** 税费手续费 */ + private Double taxCharge; + /** 买家Id */ + private String buyerId; + /** 税费 */ + private Double tax; + /** 促销折扣 */ + private Double promoDiscount; + /** 订单号--这个要特殊处理这个是对应响应的id字段 */ + private Long orderId; + /** DHcoupon */ + private Double couponDiscount; + /** 下单站点 */ + private String siteId; + /** 创建时间 */ + private Date createTime; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/BuyOrderResponseProductVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/BuyOrderResponseProductVO.java new file mode 100644 index 0000000..5f603a5 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/BuyOrderResponseProductVO.java @@ -0,0 +1,81 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 下单订单响应产品信息(CtResponseOrderProduct)表实体类 + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BuyOrderResponseProductVO { + + /** 秒杀类型 */ + private String flashDeals; + /** 卖家设置价格 */ + private Double prodPriceOrg; + /** 产品skuId */ + private String skuId; + /** 购买数量 */ + private Integer cateDispId; + /** 商品总金额 */ + private Double amount; + /** 发布类目id */ + private String catePubId; + /** 促销折扣 */ + private Double promDis; + /** 产品单位名称 */ + private String measureName; + /** 短描 */ + private String shortDescription; + /** 卖家承诺运达天数 */ + private Integer promiseDays; + /** 备货国家 */ + private String stockin; + /** 产品图片(小图) */ + private String thumbnailImage; + /** 是否为样品 */ + private String isSample; + /** 最终运费 */ + private Double shipCost; + /** 卖家Id */ + private String supplierId; + /** 跨店满减金额 */ + private BigDecimal crossReduceAmount; + /** 产品itemcode */ + private Integer itemcode; + /** buyer选择的运输方式 */ + private String shipType; + /** 销售价格 */ + private Double originPrice; + /** 产品长描地址 */ + private String htmlUrl; + /** 产品图片(大图) */ + private String imageUrl; + /** 最终价格 */ + private Double price; + /** 产品URL */ + private String productUrl; + /** 备注 */ + private String remark; + /** lots */ + private Integer lots; + /** 产品名称 */ + private String productName; + /** 产品Id */ + private String productId; + /** 产品skumd5 */ + private String skuMd5; + /** 创建时间 */ + private Date createTime; + /** 产品单位Id */ + private String measureId; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/BuyOrderVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/BuyOrderVO.java new file mode 100644 index 0000000..37dd881 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/BuyOrderVO.java @@ -0,0 +1,24 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 订单下单API响应对象 + * + * @author rch + * @create 2022-06-27 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BuyOrderVO { + + /** 接口响应状态 响应码 响应内容等信息*/ + private OrderResponStatusVO status; + /** 接口响应订单信息 */ + private List orderList; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtApplyInfoVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtApplyInfoVO.java new file mode 100644 index 0000000..e1c57a1 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtApplyInfoVO.java @@ -0,0 +1,19 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 应用信息(ct_apply) VO + * @Author zhw + * @Date 2022-08-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtApplyInfoVO { + + private Long id; + private String name; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtApplyListVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtApplyListVO.java new file mode 100644 index 0000000..04270b8 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtApplyListVO.java @@ -0,0 +1,68 @@ +package me.zhengjie.service.vo; + + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 应用信息表(CtApply)表实体类 分页查询VO + * @author zhw + * @Data 2022-07-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("应用信息表") +public class CtApplyListVO { + + @ApiModelProperty(value = "id") + private Long id; + + @ApiModelProperty(value = "平台Id") + private Long platformId; + + @ApiModelProperty(value = "创建时间") + private String createdAt; + + @ApiModelProperty(value = "修改时间") + private String updatedAt; + + /** 操作人账号 */ + @ApiModelProperty(value = "操作人账号") + private String gmName; + + /** 应用名称 */ + @ApiModelProperty(value = "应用名称") + private String name; + + /** 任务名称 */ + @ApiModelProperty(value = "任务名称") + private String taskName; + + /** 方法名称 */ + @ApiModelProperty(value = "方法名称") + private String methodName; + + /** accessKeyID */ + @ApiModelProperty(value = "accessKeyID") + private String accessKeyId; + + /** accessKeySecret */ + @ApiModelProperty(value = "accessKeySecret") + private String accessKeySecret; + + /** 应用id */ + @ApiModelProperty(value = "应用id") + private String robotUuid; + + /** 备注 */ + @ApiModelProperty(value = "备注") + private String remark; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBrowseDetailVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBrowseDetailVO.java new file mode 100644 index 0000000..0a4b4ff --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBrowseDetailVO.java @@ -0,0 +1,73 @@ +package me.zhengjie.service.vo; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 收藏浏览信息表(CtCard)表实体类 详情Detail + * + * @author rch + * @since 2022-07-09 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("收藏浏览详情") +public class CtBrowseDetailVO { + + @ApiModelProperty(value = "id") + private Long id; + + @ApiModelProperty(value = "创建时间") + private String createdAt; + + @ApiModelProperty(value = "修改时间") + private String updatedAt; + + /** 操作人账号*/ + @ApiModelProperty(value = "操作人账号") + private String gmName; + + /** 买家ID */ + @ApiModelProperty(value = "买家ID") + private Long buyerId; + + /** 国家 */ + @ApiModelProperty(value = "国家") + private String country; + + /** 账号 */ + @ApiModelProperty(value = "账号") + private String account; + + /** 密码 */ + @ApiModelProperty(value = "密码") + private String pwd; + + /** vpn分享链接 */ + @ApiModelProperty(value = "vpn分享链接") + private String vpnShare; + + /** 收藏链接 */ + @ApiModelProperty(value = "收藏链接") + private String linkUrl; + + /** 状态描述 */ + @ApiModelProperty(value = "状态描述") + private String paymentResults; + + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + @ApiModelProperty(value = "状态 1.待执行 2.执行中 3.执行成功 4.执行失败") + private Integer status; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBrowseListVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBrowseListVO.java new file mode 100644 index 0000000..02d75fa --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBrowseListVO.java @@ -0,0 +1,63 @@ +package me.zhengjie.service.vo; + +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 浏览收藏(CtBrowse)表实体类 VO + * + * @author rch + * @since 2022-11-04 09:45:31 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("浏览收藏VO") +public class CtBrowseListVO extends Model { + /** 主键ID */ + @ApiModelProperty(value = "主键ID") + private Long id; + + /** 买家ID */ + @ApiModelProperty(value = "买家ID") + private Long buyerId; + + /** 国家 */ + @ApiModelProperty(value = "国家") + private String country; + + /** 账号 */ + @ApiModelProperty(value = "账号") + private String account; + + /** 收藏链接 */ + @ApiModelProperty(value = "收藏链接") + private String linkUrl; + + /** 创建时间 */ + @ApiModelProperty(value = "创建时间") + private Date createdAt; + + /** 修改时间 */ + @ApiModelProperty(value = "修改时间") + private Date updatedAt; + + /** 状态描述 */ + @ApiModelProperty(value = "状态描述") + private String paymentResults; + + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + @ApiModelProperty(value = "状态 1.待执行 2.执行中 3.执行成功 4.执行失败") + private Integer status; + + /** 操作人账号 */ + @ApiModelProperty(value = "操作人账号") + private String gmName; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBuyerClickFarmVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBuyerClickFarmVO.java new file mode 100644 index 0000000..21ff831 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBuyerClickFarmVO.java @@ -0,0 +1,103 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * 买家信息表(CtBuyer)表实体类 详情Detail -刷单信息模块使用 + * + * @author rch + * @since 2022-09-20 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtBuyerClickFarmVO { + + private Long id; + + /** 创建时间 */ + private String createdAt; + + /** 修改时间 */ + private String updatedAt; + + /** 昵称*/ + private String nickName; + + /** 账号*/ + private String account; + + /** 密码*/ + private String pwd; + + /** 平台名称 */ + private Integer platformId; + + /** 平台名称 */ + private String platformName; + + /** 平台名称 */ + private Integer companyId; + + /** 公司名称 */ + private String companyName; + + /** 操作人账号*/ + private String gmName; + + ////////////////////////////////////// 新增字段 + /** 国家 */ + private String contntryShort; + /** VPN_ID(导入excel里包含) */ + private Long vpnId; + private String ipAddress; + private String link; + + /** 信用卡ID */ + private Long cardId; + private String number; + private String pinNumber; + private String holderSurname; + private String holderName; + + /** 用户等级(导入默认内部账号) 1.普通 2.精品 3.压力 4.内部账号 */ + private Integer level; + /** 占用状态 1.已占用 2.未占用 */ + private Integer occupyStatus; + /** 占用账户 */ + private String occupyAccount; + /** 账户余额 */ + private BigDecimal balance; + /** 账户购买总金额 */ + private BigDecimal buyTotalMoney; + + /** 状态(导入默认正常) 1.待注册 2待验证 3.待完善 4.正常 5.异常 6.可用但已用 7.删除 */ + private Integer status; + + // ==================地址信息相关========================================begin + /** 地址1 */ + private String addressline1; + /** 国家 */ + private String country; + /** 州 */ + private String state; + /** 电话 */ + private String tel; + /** lastname */ + private String lastname; + /** 税号 */ + private String vatNumber; + /** 城市 */ + private String city; + /** 地址2 */ + private String addressline2; + /** firstname */ + private String firstname; + /** 邮政编码 */ + private String postalcode; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBuyerDetailVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBuyerDetailVO.java new file mode 100644 index 0000000..12f1baf --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBuyerDetailVO.java @@ -0,0 +1,162 @@ +package me.zhengjie.service.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * 买家信息表(CtBuyer)表实体类 详情Detail + * + * @author rch + * @since 2022-07-07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("买家详情") +public class CtBuyerDetailVO { + + @ApiModelProperty(value = "id") + private Long id; + + /** 创建时间 */ + @ApiModelProperty(value = "创建时间") + private String createdAt; + + /** 修改时间 */ + @ApiModelProperty(value = "修改时间") + private String updatedAt; + + /** 昵称 */ + @ApiModelProperty(value = "昵称") + private String nickName; + + /** 账号 */ + @ApiModelProperty(value = "账号") + private String account; + + /** 密码 */ + @ApiModelProperty(value = "密码") + private String pwd; + + /** 平台ID */ + @ApiModelProperty(value = "平台ID") + private Integer platformId; + + /** 平台名称 */ + @ApiModelProperty(value = "平台名称") + private String platformName; + + /** 公司ID */ + @ApiModelProperty(value = "公司ID") + private Integer companyId; + + /** 公司名称 */ + @ApiModelProperty(value = "公司名称") + private String companyName; + + /** 操作人账号*/ + @ApiModelProperty(value = "操作人账号") + private String gmName; + + ////////////////////////////////////// 新增字段 + /** 国家 */ + @ApiModelProperty(value = "国家") + private String contntryShort; + + /** VPN_ID(导入excel里包含) */ + @ApiModelProperty(value = "VPN_ID") + private Long vpnId; + + @ApiModelProperty(value = "Vpn-Ip") + private String ipAddress; + + @ApiModelProperty(value = "vpn分享链接") + private String vpn; + + /** 信用卡ID */ + @ApiModelProperty(value = "信用卡ID") + private Long cardId; + + @ApiModelProperty(value = "信用卡卡号") + private String number; + + @ApiModelProperty(value = "信用卡密码") + private String cardPwd; + + @ApiModelProperty(value = "信用卡姓氏") + private String holderSurname; + + @ApiModelProperty(value = "信用卡名称") + private String holderName; + + /** 用户等级(导入默认内部账号) 1.普通 2.精品 3.压力 4.内部账号 */ + @ApiModelProperty(value = "用户等级(导入默认内部账号) 1.普通 2.精品 3.压力 4.内部账号") + private Integer level; + + /** 占用状态 1.已占用 2.未占用 */ + @ApiModelProperty(value = "占用状态 1.已占用 2.未占用") + private Integer occupyStatus; + + /** 占用账户 */ + @ApiModelProperty(value = "占用账户") + private String occupyAccount; + + /** 账户余额 */ + @ApiModelProperty(value = "账户余额") + private BigDecimal balance; + + /** 账户购买总金额 */ + @ApiModelProperty(value = "账户购买总金额") + private BigDecimal buyTotalMoney; + + /** 状态(导入默认正常) 1.待注册 2待验证 3.待完善 4.正常 5.异常 6.可用但已用 7.删除 */ + @ApiModelProperty(value = "状态(导入默认正常) 1.待注册 2待验证 3.待完善 4.正常 5.异常 6.可用但已用 7.删除") + private Integer status; + + // ==================地址信息相关========================================begin + /** 地址1 */ + @ApiModelProperty(value = "地址1") + private String addressline1; + + /** 国家 */ + @ApiModelProperty(value = "国家") + private String country; + + /** 州 */ + @ApiModelProperty(value = "州") + private String state; + + /** 电话 */ + @ApiModelProperty(value = "电话") + private String tel; + + /** lastname */ + @ApiModelProperty(value = "lastname") + private String lastname; + + /** 税号 */ + @ApiModelProperty(value = "税号") + private String vatNumber; + + /** 城市 */ + @ApiModelProperty(value = "城市") + private String city; + + /** 地址2 */ + @ApiModelProperty(value = "地址2") + private String addressline2; + + /** firstname */ + @ApiModelProperty(value = "firstname") + private String firstname; + + /** 邮政编码 */ + @ApiModelProperty(value = "邮政编码") + private String postalcode; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBuyerListVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBuyerListVO.java new file mode 100644 index 0000000..b6a7f57 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBuyerListVO.java @@ -0,0 +1,111 @@ +package me.zhengjie.service.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 买家信息表(CtBuyer)表实体类 分页查询Detail + * + * @author rch + * @since 2022-07-07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel +public class CtBuyerListVO { + + @ApiModelProperty(value = "Id") + private Long id; + + /** 创建时间 */ + @ApiModelProperty(value = "创建时间") + private String createdAt; + + /** 修改时间 */ + @ApiModelProperty(value = "修改时间") + private String updatedAt; + + /** 昵称 */ + @ApiModelProperty(value = "昵称") + private String nickName; + + /** 账号 */ + @ApiModelProperty(value = "账号") + private String account; + + /** 密码 */ + @ApiModelProperty(value = "密码") + private String pwd; + + /** 平台id */ + @ApiModelProperty(value = "平台id") + private Integer platformId; + + /** 平台名称 */ + @ApiModelProperty(value = "平台名称") + private String platformName; + + /** 公司id */ + @ApiModelProperty(value = "公司id") + private Long companyId; + + /** 公司名称 */ + @ApiModelProperty(value = "公司名称") + private String companyName; + + /** 操作人账号*/ + @ApiModelProperty(value = "操作人账号") + private String gmName; + + ////////////////////////////////////// 新增字段 + /** 国家 */ + @ApiModelProperty(value = "国家") + private String contntryShort; + + /** VPN_ID(导入excel里包含) */ + @ApiModelProperty(value = "VPN_ID") + private Long vpnId; + + @ApiModelProperty(value = "Vpn-Ip") + private String ipAddress; + + @ApiModelProperty(value = "vpn分享链接") + private String vpn; + + /** 信用卡ID */ + @ApiModelProperty(value = "信用卡ID") + private Long cardId; + + @ApiModelProperty(value = "信用卡卡号") + private String number; + + @ApiModelProperty(value = "信用卡密码") + private String cardPwd; + + @ApiModelProperty(value = "信用卡姓氏") + private String holderSurname; + + @ApiModelProperty(value = "信用卡名称") + private String holderName; + + /** 状态(导入默认正常) 1.待注册 2待验证 3.待完善 4.正常 5.异常 6.可用但已用 7.删除 */ + @ApiModelProperty(value = "状态(导入默认正常) 1.待注册 2待验证 3.待完善 4.正常 5.异常 6.可用但已用 7.删除") + private Integer status; + + /** 地址1 */ + @ApiModelProperty(value = "地址1") + private String addressline1; + + /** 国家 */ + @ApiModelProperty(value = "国家") + private String country; + + /** 州 */ + @ApiModelProperty(value = "州") + private String state; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBuyerVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBuyerVO.java new file mode 100644 index 0000000..efa7e74 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtBuyerVO.java @@ -0,0 +1,47 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 买家信息表(CtBuyer)表实体类 + * + * @author rch + * @since 2022-06-22 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtBuyerVO { + + private Long id; + + /** 创建时间 */ + private String createdAt; + + /** 修改时间 */ + private String updatedAt; + + /** 昵称*/ + private String nickName; + + /** 账号*/ + private String account; + + /** 密码*/ + private String pwd; + + /** 平台id */ + private Integer platformId; + + /** 平台名称 */ + private String platformName; + + /** 公司id */ + private Long companyId; + + /** 操作人账号*/ + private String gmName; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtCardDetailVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtCardDetailVO.java new file mode 100644 index 0000000..270a99b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtCardDetailVO.java @@ -0,0 +1,125 @@ +package me.zhengjie.service.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 信用卡信息表(CtCard)表实体类 详情Detail + * + * @author rch + * @since 2022-07-09 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("信用卡详情") +public class CtCardDetailVO { + + @ApiModelProperty(value = "Id") + private Long id; + + @ApiModelProperty(value = "创建时间") + private String createdAt; + + @ApiModelProperty(value = "修改时间") + private String updatedAt; + + /** 操作人账号*/ + @ApiModelProperty(value = "操作人账号") + private String gmName; + + /** 父ID */ + @ApiModelProperty(value = "父ID") + private Long parentId; + + /** 卡号 */ + @ApiModelProperty(value = "卡号") + private String number; + +// /** PIN码 */ +// @ApiModelProperty(value = "PIN码") +// private String pinNumber; + + /** 持卡人姓氏 */ + @ApiModelProperty(value = "持卡人姓氏") + private String holderSurname; + + /** 持卡人名称 */ + @ApiModelProperty(value = "持卡人名称") + private String holderName; + + /** 有效期 */ + @ApiModelProperty(value = "有效期") + private Date termOfValidity; + + /** 余额 */ + @ApiModelProperty(value = "余额") + private BigDecimal balance; + + /** 累计消费 */ + @ApiModelProperty(value = "累计消费") + private BigDecimal sumConsume; + + /** 开卡日期 */ + @ApiModelProperty(value = "开卡日期") + private Date openDate; + + /** 所属国家 */ + @ApiModelProperty(value = "所属国家") + private String contntryShort; + + /** 信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡 */ + @ApiModelProperty(value = "信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡") + private Integer type; + + /** 所属厂商:1.AmzKeys 2.Airwallex */ + @ApiModelProperty(value = "所属厂商:1.AmzKeys 2.Airwallex") + private Integer cardDealer; + + /** 身份证号 */ + @ApiModelProperty(value = "身份证号") + private String idNumber; + + /** 省份 */ + @ApiModelProperty(value = "省份") + private String province; + + /** 城市 */ + @ApiModelProperty(value = "城市") + private String country; + + /** 地址 */ + @ApiModelProperty(value = "地址") + private String address; + + /** 手机号 */ + @ApiModelProperty(value = "手机号") + private String phone; + + /** 邮箱 */ + @ApiModelProperty(value = "邮箱") + private String email; + + /** 登陆账号 */ + @ApiModelProperty(value = "登陆账号") + private String account; + + /** 密码 */ + @ApiModelProperty(value = "密码") + private String pwd; + + /** 状态:1.正常、2.异常、3.已删除 */ + @ApiModelProperty(value = "状态:1.正常、2.异常、3.已删除") + private Integer status; + + /** 备注 */ + @ApiModelProperty(value = "备注") + private String remarks; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtCardListVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtCardListVO.java new file mode 100644 index 0000000..fd2225f --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtCardListVO.java @@ -0,0 +1,72 @@ +package me.zhengjie.service.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * 买家信息表(CtCard)表实体类 分页查询Detail + * + * @author rch + * @since 2022-07-09 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel +public class CtCardListVO { + + @ApiModelProperty(value = "Id") + private Long id; + + @ApiModelProperty(value = "创建时间") + private String createdAt; + + @ApiModelProperty(value = "修改时间") + private String updatedAt; + + /** 操作人账号*/ + @ApiModelProperty(value = "操作人账号") + private String gmName; + + /** 卡号 */ + @ApiModelProperty(value = "卡号") + private String number; + + /** PIN码 */ + @ApiModelProperty(value = "PIN码") + private String pinNumber; + + /** 持卡人姓氏 */ + @ApiModelProperty(value = "持卡人姓氏") + private String holderSurname; + + /** 持卡人名称 */ + @ApiModelProperty(value = "持卡人名称") + private String holderName; + + /** 余额 */ + @ApiModelProperty(value = "余额") + private BigDecimal balance; + + /** 累计消费 */ + @ApiModelProperty(value = "累计消费") + private BigDecimal sumConsume; + + /** 信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡 */ + @ApiModelProperty(value = "信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡") + private Integer type; + + /** 所属厂商:1.AmzKeys 2.Airwallex */ + @ApiModelProperty(value = "所属厂商:1.AmzKeys 2.Airwallex") + private Integer cardDealer; + + /** 状态:1.正常、2.异常、3.已删除 */ + @ApiModelProperty(value = "状态:1.正常、2.异常、3.已删除") + private Integer status; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickFarmEditDetailVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickFarmEditDetailVO.java new file mode 100644 index 0000000..c789a85 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickFarmEditDetailVO.java @@ -0,0 +1,63 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 刷单Excel信息(CtClickFarming)表实体类 - 修改详情 + * + * @author rch + * @since 2022-08-16 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickFarmEditDetailVO { + + private Long id; + /** 关联刷单订单ID */ + private Long ctClickOrderId; + /** 买家id */ + private Long buyerId; + /** 买家名称 */ + private String buyerName; + /** 刷单类型 */ + private Integer type; + /** 刷单类型 */ + private Integer paramsType; + /** 店铺名称 */ + private String shopName; + /** 关键词 */ + private String keyWord; + /** 标题 */ + private String title; + /** 链接 */ + private String link; + /** 数量 */ + private Integer number; + /** 规格 */ + private String specification; + /** 颜色 */ + private String color; + /** item */ + private String item; + private String exchange; + /** 执行结果 */ + private String response; + /** 支付订单ID */ + private String payOrderId; + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + private Integer status; + /** 留言 */ + private String amessage; + /** 创建时间 */ + private Date createdAt; + /** 修改时间 */ + private Date updatedAt; + /** 操作人账号 */ + private String gmName; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickFarmingDetailVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickFarmingDetailVO.java new file mode 100644 index 0000000..eacd156 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickFarmingDetailVO.java @@ -0,0 +1,98 @@ +package me.zhengjie.service.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + * 刷单Excel信息(CtClickFarming)表实体类 + * + * @author rch + * @since 2022-08-16 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("刷单详情") +public class CtClickFarmingDetailVO { + + @ApiModelProperty(value = "id") + private Long id; + + @ApiModelProperty(value = "买家名称") + private String buyerName; + + /** 商品属性类型 */ + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接", required = true, allowableValues = "1,2") + private Integer paramsType; + + /** 店铺名称 */ + @ApiModelProperty(value = "店铺名称") + private String shopName; + + /** 关键词 */ + @ApiModelProperty(value = "关键词") + private String keyWord; + + /** 标题 */ + @ApiModelProperty(value = "标题") + private String title; + + /** 链接 */ + @ApiModelProperty(value = "链接") + private String link; + + /** 数量 */ + @ApiModelProperty(value = "数量") + private Integer number; + + /** 规格 */ + @ApiModelProperty(value = "规格") + private String specification; + + /** 颜色 */ + @ApiModelProperty(value = "颜色") + private String color; + + /** item */ + @ApiModelProperty(value = "item") + private String item; + + @ApiModelProperty(value = "优惠劵") + private String exchange; + + /** 执行结果 */ + @ApiModelProperty(value = "执行结果") + private String response; + + /** 支付订单ID */ + @ApiModelProperty(value = "支付订单ID") + private String payOrderId; + + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 5.代付款 6.支付成功后失败 */ + @ApiModelProperty(value = "状态 1.待执行 2.执行中 3.执行成功 4.执行失败 5.代付款 6.支付成功后失败", allowableValues = "1,2,3,4,5,6") + private Integer status; + + /** 留言 */ + @ApiModelProperty(value = "留言") + private String amessage; + + /** 创建时间 */ + @ApiModelProperty(value = "创建时间") + private Date createdAt; + + /** 修改时间 */ + @ApiModelProperty(value = "修改时间") + private Date updatedAt; + + /** 操作人账号 */ + @ApiModelProperty(value = "操作人账号") + private String gmName; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickFarmingVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickFarmingVO.java new file mode 100644 index 0000000..44a409e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickFarmingVO.java @@ -0,0 +1,59 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 刷单Excel信息(CtClickFarming)表实体类 + * + * @author rch + * @since 2022-08-16 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickFarmingVO { + + private Long id; + /** 关联刷单订单ID */ + private Long ctClickOrderId; + /** 刷单类型 */ + private Integer paramsType; + /** 国家 */ + private String country; + /** 账号 */ + private String account; + /** 店铺名称 */ + private String shopName; + /** 关键词 */ + private String keyWord; + /** 标题 */ + private String title; + /** 链接 */ + private String link; + /** 数量 */ + private Integer number; + /** 规格 */ + private String specification; + /** 颜色 */ + private String color; + /** item */ + private String item; + private String exchange; + /** 执行结果 */ + private String response; + /** 支付订单ID */ + private String payOrderId; + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + private Integer status; + /** 创建时间 */ + private Date createdAt; + /** 修改时间 */ + private Date updatedAt; + /** 操作人账号 */ + private String gmName; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickOrderDetailVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickOrderDetailVO.java new file mode 100644 index 0000000..1fbf249 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickOrderDetailVO.java @@ -0,0 +1,48 @@ +package me.zhengjie.service.vo; + +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + +/** + * 刷单-订单信息(CtClickOrder)表实体类 + * + * @author rch + * @since 2022-09-14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickOrderDetailVO extends Model { + private Long id; + private String createdAt; + private String updatedAt; + /** 操作人账号*/ + private String gmName; + /** 公司ID */ + private Long companyId; + /** 状态描述 */ + private String paymentResults; + /** 购买数量 */ + private String pricesNumber; + /** 总金额 */ + private String amount; + /** 店铺名称 */ + private String shop; + /** 订单id */ + private String orderId; + /** 商品名称 */ + private String shopName; + /** 时间 */ + private String orderDate; + /** 评论 */ + private String comment; + /** 图片路径 */ + private String paths; + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + private Integer status; + /** 执行结果 */ + private String response; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickOrderListVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickOrderListVO.java new file mode 100644 index 0000000..f99a5b8 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtClickOrderListVO.java @@ -0,0 +1,45 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.utils.excel.ExcelExport; + +/** + * 实体类 分页查询Detail + * + * @author rch + * @since 2022-09-27 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtClickOrderListVO { + + private Long id; + private String createdAt; + private String updatedAt; + /** 公司ID */ + private Long companyId; + /** 类型 1.刷单 2.导入 */ + private Integer type; + /** 公司Name */ + private String companyName; + /** 账号 */ + private String account; + /** 密码 */ + private String pwd; + /** 总金额 */ + private String amount; + /** 店铺名称 */ + private String shop; + /** 订单id */ + private String orderId; + /** 评论 */ + private String comment; + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + private Integer status; + /** 执行结果 */ + private String response; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtCompanyInfoVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtCompanyInfoVO.java new file mode 100644 index 0000000..6f1db4b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtCompanyInfoVO.java @@ -0,0 +1,23 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 公司信息(CtPlatform)表实体类 VO + * + * @author rch + * @since 2022-07-07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtCompanyInfoVO { + + private Long id; + + /** 名称 */ + private String name; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtCompanyVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtCompanyVO.java new file mode 100644 index 0000000..c13e35d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtCompanyVO.java @@ -0,0 +1,35 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 公司信息(CtCompany)表实体类 VO + * + * @author rch + * @since 2022-06-28 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtCompanyVO { + + private Long id; + private String createdAt; + private String updatedAt; + /** 名称 */ + private String name; + /** 地址 */ + private String address; + /** 电话 */ + private String phone; + /** 商户码(公司调用api公司唯一标识) */ + private String number; + /** 商户token(公司调用api公司token身份标识) */ + private String token; + + /** 操作人账号*/ + private String gmName; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtDhPayDetailVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtDhPayDetailVO.java new file mode 100644 index 0000000..d6f4e98 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtDhPayDetailVO.java @@ -0,0 +1,40 @@ +package me.zhengjie.service.vo; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 买家信息表(CtDhPay)表实体类 详情Detail + * + * @author rch + * @since 2022-07-28 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtDhPayDetailVO { + + private Long id; + private String createdAt; + private String updatedAt; + /** 操作人账号*/ + private String gmName; + + /** 买家名称 */ + private String buyerName; + /** 支付订单ID(敦煌的) */ + private String orderId; + /** 请求响应详情 */ + private String response; + /** 状态 0.待处理 1.支付成功 2.支付失败 */ + private Integer status; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtDhPayListVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtDhPayListVO.java new file mode 100644 index 0000000..778ea07 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtDhPayListVO.java @@ -0,0 +1,36 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 买家信息表(CtDhPay)表实体类 分页查询Detail + * + * @author rch + * @since 2022-07-07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtDhPayListVO { + + private Long id; + /** 买家名称 */ + private String buyerName; + /** 支付订单ID(敦煌的) */ + private String orderId; + /** 请求响应详情 */ + private String response; + /** 状态 0.待处理 1.支付成功 2.支付失败 */ + private Integer status; + /** 创建时间 */ + private Date createdAt; + /** 修改时间 */ + private Date updatedAt; + /** 操作人账号 */ + private String gmName; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtExcelImportInfoVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtExcelImportInfoVO.java new file mode 100644 index 0000000..c20eda1 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtExcelImportInfoVO.java @@ -0,0 +1,42 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * ExcelImportInfo 导入信息(CtExcel)表实体类 VO + * + * @author rch + * @since 2022-06-27 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtExcelImportInfoVO { + + private Long id; + private String createdAt; + private String updatedAt; + + /** 公司主键 */ + private Long companyId; + + /** 鉴权枚举 */ + private Integer tokenEnum; + + /** 订单来源 */ + private String fromDetailInfo; + + /** 状态 状态 1.待处理 2.处理成功 3.处理失败 */ + private Integer status; + + /** 产品信息-JSON */ + private String cartList; + + /** 订单收货地址-JSON */ + private String contactInfo; + + /** 操作人账号*/ + private String gmName; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtExcelVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtExcelVO.java new file mode 100644 index 0000000..802664b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtExcelVO.java @@ -0,0 +1,31 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Excel 导入信息(CtExcel)表实体类 VO + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtExcelVO { + + private Long id; + private String createdAt; + private String updatedAt; + /** 备注 */ + private String remarks; + /** excel路径 */ + private String path; + private String errorPath; + /** 状态1.待处理 2.已处理 */ + private Integer status; + + /** 操作人账号*/ + private String gmName; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtOrderVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtOrderVO.java new file mode 100644 index 0000000..2fe99ae --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtOrderVO.java @@ -0,0 +1,44 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * (CtOrder)表实体类 VO + * + * @author rch + * @since 2022-07-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtOrderVO { + + private Long id; + private String createdAt; + private String updatedAt; + /** 公司Id */ + private Long companyId; + /** ExcelId 信息 */ + private Long excelInfoId; + /** 买家buy_access_token */ + private String buyAccessToken; + /** 我们平台订单编号 */ + private String ctOrderNo; + /** 订单号,下单成功响应的订单号(冗余字段 下单成功响应订单信息里有) */ + private Long orderNo; + /** 下单成功响应的产品id( a,b,c 格式) (响应字段很多,先少些几个) */ + private Long responseProductId; + /** 下单成功响应的订单地址id(响应字段很多,先少些几个) */ + private Long responseOrderAddressId; + /** 下单成功响应的订单信息 (响应字段很多,先少些几个) */ + private Long responseOrderId; + /** 响应码信息 */ + private OrderResponStatusVO orderResponseStatus; + /** 响应码信息 */ + private PayOrderVO payOrderVO; + /** 状态 1.待支付(下单成功) 2.支付成功 3.支付失败*/ + private Integer status; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtPlatformInfoVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtPlatformInfoVO.java new file mode 100644 index 0000000..6086629 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtPlatformInfoVO.java @@ -0,0 +1,23 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 平台信息(CtPlatform)表实体类 VO + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtPlatformInfoVO { + + private Long id; + + /** 名称 */ + private String name; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtPlatformVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtPlatformVO.java new file mode 100644 index 0000000..6562b7b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtPlatformVO.java @@ -0,0 +1,29 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 平台信息(CtPlatform)表实体类 VO + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtPlatformVO { + + private Long id; + private String createdAt; + private String updatedAt; + /** 名称 */ + private String name; + /** 地址 */ + private String address; + /** 电话 */ + private String phone; + private String gmName; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtRebotListVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtRebotListVO.java new file mode 100644 index 0000000..02edb77 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtRebotListVO.java @@ -0,0 +1,37 @@ +package me.zhengjie.service.vo; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 影刀机器人 分页查询VO + * + * @Author zhw + * @Date 2022-07-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtRebotListVO { + + + private Long id; + + private String createdAt; + + private String updatedAt; + /** 操作人账号*/ + private String gmName; + + /** 机器人账号 */ + private String accountName; + /** 机器人Uuid信息 */ + private String robotClientUuid; + /** 状态 0.未占用 1.已占用 */ + private Integer status; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtVpnInfoVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtVpnInfoVO.java new file mode 100644 index 0000000..3241d22 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtVpnInfoVO.java @@ -0,0 +1,16 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtVpnInfoVO { + + private Long id; + + /** 名称 */ + private String name; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/CtVpnVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtVpnVO.java new file mode 100644 index 0000000..a95a195 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/CtVpnVO.java @@ -0,0 +1,42 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtVpnVO { + + private Long id; + /** 创建时间*/ + private String createdAt; + /** 修改时间*/ + private String updatedAt; + /** 操作人账号*/ + private String gmName; + + /** 所属国家简称 */ + private String contntryShort; + /** IP地址 */ + private String ipAddress; + /** 父ip地址 */ + private String parentIpAddress; + /** 端口 */ + private Integer port; + /** 名称 */ + private String name; + /** 密码 */ + private String pwd; + /** VPS类型 1.传统 */ + private Integer vpsType; + /** 经销商 1.V2 */ + private Integer dealer; + /** mac地址 */ + private String mac; + /** 链接 */ + private String link; + /** 经销商 1.可用 2.禁用 */ + private Integer status; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/GoogleAuthInfoVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/GoogleAuthInfoVO.java new file mode 100644 index 0000000..e99241f --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/GoogleAuthInfoVO.java @@ -0,0 +1,27 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * 秘钥信息 + *

+ * + * @author: rch + * @since: 2020-08-26 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class GoogleAuthInfoVO { + /** 用户信息 */ + private String userName; + + /** 二维码url 信息 */ + private String qrBarCodeUrl; + + /** 明文秘钥 */ + private String secret; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/LoginIpVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/LoginIpVO.java new file mode 100644 index 0000000..80b4c10 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/LoginIpVO.java @@ -0,0 +1,57 @@ +package me.zhengjie.service.vo; + +import cn.hutool.core.util.ObjectUtil; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.entity.LoginIp; +import me.zhengjie.utils.DateUtil; + +import java.time.LocalDateTime; + +/* + * + * @Description + * @Date 2022/3/21 + * @Author zeng + */ +@Data +@NoArgsConstructor +public class LoginIpVO extends LoginIp { + + // 状态 1:正常 0:失效 + private Integer status; + + + public String getIp() { + StringBuffer sbf = new StringBuffer(getIpStart()); + if (sbf.length() > 0) { + sbf.append("~"); + } + sbf.append(getIpEnd()); + return sbf.toString(); + } + + public Integer getStatus() { + if (ObjectUtil.isNotEmpty(getVaildTime())) { + LocalDateTime localDateTime = DateUtil.parseLocalDateTimeFormatyMdHms(getVaildTime()); + if (localDateTime.isBefore(LocalDateTime.now())) { + return 0; + } + return 1; + } + return 1; + } + + public LoginIpVO(LoginIp loginIp) { + setId(loginIp.getId()); + setIpStart(loginIp.getIpStart()); + setIpEnd(loginIp.getIpEnd()); + setCreatedAt(loginIp.getCreatedAt()); + setUpdatedAt(loginIp.getUpdatedAt()); + setGmName(loginIp.getGmName()); + setRemark(loginIp.getRemark()); + setVaildTime(loginIp.getVaildTime()); + } + + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/OrderResponStatusVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/OrderResponStatusVO.java new file mode 100644 index 0000000..73ed2c5 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/OrderResponStatusVO.java @@ -0,0 +1,21 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 订单下单模块响应Status对象VO + * + * @author rch + * @create 2022-06-27 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class OrderResponStatusVO { + private String code; + private String message; + private String solution; + private OrderResponSubErrorVO subErrors; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/OrderResponSubErrorVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/OrderResponSubErrorVO.java new file mode 100644 index 0000000..fcf8b58 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/OrderResponSubErrorVO.java @@ -0,0 +1,19 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 敦煌接口响应SubError + * + * @author rch + * @create 2022-06-27 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class OrderResponSubErrorVO { + private String code; + private String message; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/OrderResponseVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/OrderResponseVO.java new file mode 100644 index 0000000..7c69e07 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/OrderResponseVO.java @@ -0,0 +1,28 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 敦煌订单下单响应订单信息 + * + * @author rch + * @create 2022-06-27 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class OrderResponseVO { + + /** 接口响应订单信息 订单信息 */ + private BuyOrderResponseOrderVO orderInfo; + + /** 接口响应订单信息 订单产品信息 */ + private List cartList; + + /** 接口响应订单信息 订单收件地址信息 */ + private BuyOrderResponseAddressVO orderContactInfo; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/PayOrderVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/PayOrderVO.java new file mode 100644 index 0000000..d623fdc --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/PayOrderVO.java @@ -0,0 +1,23 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 支付下单API响应对象 + * + * @author rch + * @create 2022-06-27 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PayOrderVO { + + /** 接口响应状态 响应码 响应内容等信息*/ + private OrderResponStatusVO status; + /** 接口响应订单信息 */ + private String result; + private String message; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/SettingSiteVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/SettingSiteVO.java new file mode 100644 index 0000000..afa4d11 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/SettingSiteVO.java @@ -0,0 +1,31 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 站点配置(SettingSiteVO)表 响应类 + * + * @author zeng + * @since 2020-07-13 10:07:39 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SettingSiteVO { + + private Long id; + + /** 设置KEY */ + private String settingKey; + + /** 设置value */ + private String settingValue; + + /** 中文描述 */ + private String content; + + /** 单位 */ + private String unit; +} \ No newline at end of file diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/SysQuartzJobListVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/SysQuartzJobListVO.java new file mode 100644 index 0000000..282b4a6 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/SysQuartzJobListVO.java @@ -0,0 +1,40 @@ +package me.zhengjie.service.vo; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 影刀任务表(sys_quartz_job)表实体类 分页查询VO + * @author zhw + * @since 2022-07-21 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SysQuartzJobListVO { + + /** 任务ID */ + private Long jobId; + /** 任务名称 */ + private String jobName; + /** Spring Bean名称 */ + private String beanName; + /** 方法名称 */ + private String methodName; + /** 参数 */ + private String params; + /** cron 表达式 */ + private String cronExpression; + /** 状态:1暂停、0启用 */ + private Integer isPause; + /** 备注 */ + private String description; + /** 创建时间 */ + private String createTime; + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/SysQuartzLogListVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/SysQuartzLogListVO.java new file mode 100644 index 0000000..8b79777 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/SysQuartzLogListVO.java @@ -0,0 +1,47 @@ +package me.zhengjie.service.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.sql.Timestamp; + +/** + * 买家信息表(sys_quartz_log)表实体类 分页查询Detail + * + * @author rch + * @since 2022-07-09 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SysQuartzLogListVO { + + private Long logId; + /** bean名称 */ + private String beanName; + /** 任务名称 */ + private String jobName; + /** 方法名称 */ + private String methodName; + + /** 参数 */ + private String params; + + /** cron表达式 */ + private String cronExpression; + + /** 状态 */ + private Integer isSuccess; + + /** 异常详情 */ + private String exceptionDetail; + + /** 执行耗时 */ + private Long time; + + /** 创建时间 */ + private Timestamp createTime; +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/dhaddcar/DhAddCarListVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/dhaddcar/DhAddCarListVO.java new file mode 100644 index 0000000..b8ea1ec --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/dhaddcar/DhAddCarListVO.java @@ -0,0 +1,80 @@ +package me.zhengjie.service.vo.dhaddcar; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + * 敦煌加购信息 DTO + * + * @author rch + * @create 2022-11-17 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("敦煌加购信息") +public class DhAddCarListVO { + + /** ID */ + @ApiModelProperty(value = "ID", required = true) + private Long id; + + /** 商品属性类型:1.关键词 2.链接 */ + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接", required = true, allowableValues = "1,2") + private Integer paramsType; + + /** 买家ID */ + @ApiModelProperty(value = "买家ID", required = true) + private Integer buyerId; + + /** 账号 */ + @ApiModelProperty(value = "账号") + private String account; + + /** 公司名称 */ + @ApiModelProperty(value = "公司名称") + private String companyName; + + /** 国家 */ + @ApiModelProperty(value = "国家") + private String country; + + /** 加购物车商品ids */ + @ApiModelProperty(value = "加购物车商品ids") + private String carGoodIds; + + /** 执行结果 */ + @ApiModelProperty(value = "执行结果") + private String response; + + /** 状态 1.待执行 2.执行中 3.加购成功 4.加购失败 5.下单成功 6.支付成功 7.抓单成功 8.抓单失败 */ + @ApiModelProperty(value = "状态 1.待执行 2.执行中 3.加购成功 4.加购失败 5.下单成功 6.支付成功 7.抓单成功 8.抓单失败") + private Integer status; + + /** 创建时间 */ + @ApiModelProperty(value = "创建时间") + private Date createdAt; + + /** 修改时间 */ + @ApiModelProperty(value = "修改时间") + private Date updatedAt; + + /** 操作人账号 */ + @ApiModelProperty(value = "操作人账号") + private String gmName; + +// /** 加购物车商品ids */ +// @ApiModelProperty(value = "加购物车商品ids") +// private List carGoodKeys; +// +// /** 加购物车商品ids */ +// @ApiModelProperty(value = "加购物车商品ids") +// private List carGoodLinks; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/dhaddcar/DhAddCarVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/dhaddcar/DhAddCarVO.java new file mode 100644 index 0000000..1db1917 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/dhaddcar/DhAddCarVO.java @@ -0,0 +1,65 @@ +package me.zhengjie.service.vo.dhaddcar; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.service.vo.dhcargood.DhCarGoodKeyVO; +import me.zhengjie.service.vo.dhcargood.DhCarGoodLinkVO; + +import java.util.List; + +/** + * 敦煌加购Exit信息 DTO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("修改敦煌加购信息回显") +public class DhAddCarVO { + + /** ID */ + @ApiModelProperty(value = "ID", required = true) + private Long id; + + /** 商品属性类型:1.关键词 2.链接 */ + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接") + private Integer paramsType; + @ApiModelProperty(value = "公司名称", required = true) + private String companyName; + /** 买家ID */ + @ApiModelProperty(value = "买家ID", required = true) + private Integer buyerId; + /** 买家账号 */ + @ApiModelProperty(value = "买家账号", required = true) + private String account; + /** 国家 */ + @ApiModelProperty(value = "国家", required = true) + private String country; + /** 密码 */ + @ApiModelProperty(value = "密码", required = true) + private String pwd; + /** vpn分享链接 */ + private String vpnShare; + + /** 加购物车商品ids */ + @ApiModelProperty(value = "加购物车商品ids") + private String carGoodIds; + + /** 加购物车商品ids */ + @ApiModelProperty(value = "加购物车商品ids") + private List carGoodKeys; + + /** 加购物车商品ids */ + @ApiModelProperty(value = "加购物车商品ids") + private List carGoodLinks; + + /** 状态 1.待执行 2.执行中 3.加购成功 4.加购失败 5.下单成功 6.支付成功 7.抓单成功 8.抓单失败 */ + @ApiModelProperty(value = "状态 1.待执行 2.执行中 3.加购成功 4.加购失败 5.下单成功 6.支付成功 7.抓单成功 8.抓单失败") + private Integer status; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/dhaddcar/DhAddCarYdParamsVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/dhaddcar/DhAddCarYdParamsVO.java new file mode 100644 index 0000000..acd8943 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/dhaddcar/DhAddCarYdParamsVO.java @@ -0,0 +1,56 @@ +package me.zhengjie.service.vo.dhaddcar; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.service.vo.dhcargood.DhCarGoodKeyVO; +import me.zhengjie.service.vo.dhcargood.DhCarGoodLinkVO; + +import java.util.List; + +/** + * 敦煌加购 影刀参数信息 DTO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("修改敦煌加购信息回显") +public class DhAddCarYdParamsVO { + + /** ID */ + @ApiModelProperty(value = "ID", required = true) + private Long id; + + /** 商品属性类型:1.关键词 2.链接 */ + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接") + private Integer paramsType; + + /** 买家账号 */ + @ApiModelProperty(value = "买家账号", required = true) + private String account; + + /** 国家 */ + @ApiModelProperty(value = "国家", required = true) + private String country; + + /** 密码 */ + @ApiModelProperty(value = "密码", required = true) + private String pwd; + + /** vpn分享链接 */ + private String vpnShare; + + /** 加购物车商品ids */ + @ApiModelProperty(value = "加购物车商品ids") + private List carGoodKeys; + + /** 加购物车商品ids */ + @ApiModelProperty(value = "加购物车商品ids") + private List carGoodLinks; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/dhcargood/DhCarGoodKeyVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/dhcargood/DhCarGoodKeyVO.java new file mode 100644 index 0000000..3c8a789 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/dhcargood/DhCarGoodKeyVO.java @@ -0,0 +1,76 @@ +package me.zhengjie.service.vo.dhcargood; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Null; + +/** + * 敦煌-加购商品(根据关键词) VO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("敦煌-加购商品(根据关键词)") +public class DhCarGoodKeyVO { + + /** ID */ + @ApiModelProperty(value = "ID", required = true) + private Long id; + + /** 商品属性类型:1.关键词 2.链接 */ + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接", required = true, allowableValues = "1,2") + private Integer paramsType; + + /** 店铺名称 */ + @ApiModelProperty(value = "NotBlank", required = true) + private String shopName; + + /** 关键词 */ + @ApiModelProperty(value = "关键词", required = true) + private String keyWord; + + /** 标题 */ + @ApiModelProperty(value = "标题", required = true) + private String title; + + /** 数量 */ + @ApiModelProperty(value = "数量", required = true) + private Integer number; + + /** 规格 */ + @ApiModelProperty(value = "规格") + private String specification; + + /** 颜色 */ + @ApiModelProperty(value = "颜色") + private String color; + + /** item */ + @ApiModelProperty(value = "item", required = true) + private String item; + + /** 最小价格区间 */ + @ApiModelProperty(value = "最小价格区间") + private String sectionMin; + + /** 最大价格区间 */ + @ApiModelProperty(value = "最大价格区间") + private String sectionMax; + + /** 评论 */ + @ApiModelProperty(value = "评论") + private String comment; + + /** 图片url */ + @ApiModelProperty(value = "图片url") + private String paths; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/dhcargood/DhCarGoodLinkVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/dhcargood/DhCarGoodLinkVO.java new file mode 100644 index 0000000..0a6005e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/dhcargood/DhCarGoodLinkVO.java @@ -0,0 +1,56 @@ +package me.zhengjie.service.vo.dhcargood; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Null; + +/** + * 敦煌-加购商品(根据链接) VO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("敦煌-加购商品(根据链接)") +public class DhCarGoodLinkVO { + + /** ID */ + @ApiModelProperty(value = "ID", required = true) + private Long id; + + /** 商品属性类型:1.关键词 2.链接 */ + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接", required = true, allowableValues = "1,2") + private Integer paramsType; + + /** 链接 */ + @ApiModelProperty(value = "链接", required = true) + private String link; + + /** 数量 */ + @ApiModelProperty(value = "数量", required = true) + private Integer number; + + /** 规格 */ + @ApiModelProperty(value = "规格", required = true) + private String specification; + + /** 颜色 */ + @ApiModelProperty(value = "颜色", required = true) + private String color; + + /** 评论 */ + @ApiModelProperty(value = "评论") + private String comment; + + /** 图片url */ + @ApiModelProperty(value = "图片url") + private String paths; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/dhcarorder/DhAddCarOrderListVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/dhcarorder/DhAddCarOrderListVO.java new file mode 100644 index 0000000..c8920e4 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/dhcarorder/DhAddCarOrderListVO.java @@ -0,0 +1,62 @@ +package me.zhengjie.service.vo.dhcarorder; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 敦煌加购订单信息 DTO + * + * @author rch + * @create 2022-12-01 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("敦煌加购信息") +public class DhAddCarOrderListVO { + + @ApiModelProperty(value = "ID") + private Long id; + @ApiModelProperty(value = "创建时间") + private String createdAt; + @ApiModelProperty(value = "修改时间") + private String updatedAt; + /** 操作人账号*/ + @ApiModelProperty(value = "操作人") + private String gmName; + + /** 1.导入 2.刷单 */ + @ApiModelProperty(value = "类型 1.导入 2.刷单") + private Integer type; + /** 关联敦煌加购的id */ + @ApiModelProperty(value = "关联敦煌加购的id") + private Long addCarId; + /** 总金额 */ + @ApiModelProperty(value = "总金额") + private String amount; + /** 状态描述 */ + @ApiModelProperty(value = "状态描述") + private String paymentResults; + /** 店铺名称 */ + @ApiModelProperty(value = "店铺名称") + private String shop; + /** 订单id */ + @ApiModelProperty(value = "订单id") + private String orderId; + /** 时间 */ + @ApiModelProperty(value = "订单时间") + private String orderDate; + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + @ApiModelProperty(value = "状态 1.待执行 2.执行中 3.执行成功 4.执行失败") + private Integer status; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/service/vo/dhcarorder/DhCarOrderParamsVO.java b/wjcy-common/src/main/java/me/zhengjie/service/vo/dhcarorder/DhCarOrderParamsVO.java new file mode 100644 index 0000000..ad98173 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/service/vo/dhcarorder/DhCarOrderParamsVO.java @@ -0,0 +1,59 @@ +package me.zhengjie.service.vo.dhcarorder; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.service.vo.dhcargood.DhCarGoodKeyVO; +import me.zhengjie.service.vo.dhcargood.DhCarGoodLinkVO; + +import java.util.List; + +/** + * 敦煌加购好评-影刀参数 + * + * @author rch + * @create 2022-12-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DhCarOrderParamsVO { + /** ID */ + @ApiModelProperty(value = "ID", required = true) + private Long id; + + /** 商品属性类型:1.关键词 2.链接 */ + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接") + private Integer paramsType; + + /** 买家账号 */ + @ApiModelProperty(value = "买家账号", required = true) + private String account; + + /** 国家 */ + @ApiModelProperty(value = "国家", required = true) + private String country; + + /** 密码 */ + @ApiModelProperty(value = "密码", required = true) + private String pwd; + + /** vpn分享链接 */ + private String vpnShare; + + /** 订单ID */ + private String orderId; + + /** 加购物车商品ids */ + @ApiModelProperty(value = "加购物车商品ids") + private String carGoodIds; + + /** 加购物车商品ids */ + @ApiModelProperty(value = "加购物车商品ids") + private List carGoodKeys; + + /** 加购物车商品ids */ + @ApiModelProperty(value = "加购物车商品ids") + private List carGoodLinks; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/CacheKey.java b/wjcy-common/src/main/java/me/zhengjie/utils/CacheKey.java new file mode 100644 index 0000000..7485713 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/CacheKey.java @@ -0,0 +1,58 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +/** + * @author: liaojinlong + * @date: 2020/6/11 15:49 + * @apiNote: 关于缓存的Key集合 + */ +public interface CacheKey { + + /** + * 用户 + */ + String USER_ID = "user::id:"; + /** + * 数据 + */ + String DATA_USER = "data::user:"; + /** + * 菜单 + */ + String MENU_ID = "menu::id:"; + String MENU_USER = "menu::user:"; + /** + * 角色授权 + */ + String ROLE_AUTH = "role::auth:"; + /** + * 角色信息 + */ + String ROLE_ID = "role::id:"; + /** + * 部门 + */ + String DEPT_ID = "dept::id:"; + /** + * 岗位 + */ + String JOB_ID = "job::id:"; + /** + * 数据字典 + */ + String DICT_NAME = "dict::name:"; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/CallBack.java b/wjcy-common/src/main/java/me/zhengjie/utils/CallBack.java new file mode 100644 index 0000000..9b10812 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/CallBack.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.zhengjie.utils; + +/** + * @author: liaojinlong + * @date: 2020/6/9 17:02 + * @since: 1.0 + * @see {@link SpringContextHolder} + * 针对某些初始化方法,在SpringContextHolder 初始化前时,
+ * 可提交一个 提交回调任务。
+ * 在SpringContextHolder 初始化后,进行回调使用 + */ + +public interface CallBack { + /** + * 回调执行方法 + */ + void executor(); + + /** + * 本回调任务名称 + * @return / + */ + default String getCallBackName() { + return Thread.currentThread().getId() + ":" + this.getClass().getName(); + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/CheckPwdValidator.java b/wjcy-common/src/main/java/me/zhengjie/utils/CheckPwdValidator.java new file mode 100644 index 0000000..2f10dca --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/CheckPwdValidator.java @@ -0,0 +1,35 @@ +package me.zhengjie.utils; + +import cn.hutool.core.util.ObjectUtil; +import me.zhengjie.annotation.CheckPwd; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.regex.Pattern; + +/* + * + * @Description + * @Date 2022/3/21 + * @Author zeng + */ +public class CheckPwdValidator implements ConstraintValidator { + + private CheckPwd checkPwd; + + public static final String p = "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[~@#$%\\*-\\+=:,\\\\?\\[\\]\\{}]).{16,64}$"; + + + @Override + public void initialize(CheckPwd constraintAnnotation) { + this.checkPwd = constraintAnnotation; + } + + @Override + public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { + if (ObjectUtil.isEmpty(value)) { + return true; + } + return Pattern.matches(p, value); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/CloseUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/CloseUtil.java new file mode 100644 index 0000000..98d375b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/CloseUtil.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import java.io.Closeable; + +/** + * @author Zheng Jie + * @website https://el-admin.vip + * @description 用于关闭各种连接,缺啥补啥 + * @date 2021-03-05 + **/ +public class CloseUtil { + + public static void close(Closeable closeable) { + if (null != closeable) { + try { + closeable.close(); + } catch (Exception e) { + // 静默关闭 + } + } + } + + public static void close(AutoCloseable closeable) { + if (null != closeable) { + try { + closeable.close(); + } catch (Exception e) { + // 静默关闭 + } + } + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/CronUtils.java b/wjcy-common/src/main/java/me/zhengjie/utils/CronUtils.java new file mode 100644 index 0000000..14728f8 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/CronUtils.java @@ -0,0 +1,49 @@ +package me.zhengjie.utils; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * 时间日期转cron工具类 + * Spring Task是Quartz的弱版,Quartz支持年份,而Spring Task不支持。Spring Task是6位, + * Quartz可以7位,本代码是基于hutool工具的表达式,是可以支持Quartz。 + * @author rch + * @create 2022-10-06 + */ +public class CronUtils { + + + /** + * 仅一次 + * @param dateStr + * @return + */ + public static String onlyOnce(String dateStr) { + LocalDateTime time = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + String cronStr = time.format(DateTimeFormatter.ofPattern("ss mm HH dd MM ? yyyy")); + return cronStr; + } + + /** + * 每天 + * @param timeStr + * @return + */ + public static String everyDay(String timeStr) { + LocalDateTime time = LocalDateTime.parse(timeStr, DateTimeFormatter.ofPattern("HH:mm:ss")); + String cronStr = time.format(DateTimeFormatter.ofPattern("ss mm HH dd * * ?")); + return cronStr; + } + + + /** + * 每周 + * @param timeStr + * @return + */ + public static String everyWeek(String timeStr, String week) { + LocalDateTime time = LocalDateTime.parse(timeStr, DateTimeFormatter.ofPattern("HH:mm:ss")); + String cronStr = time.format(DateTimeFormatter.ofPattern("ss mm HH ? * " + week)); + return cronStr; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/DateTimeValidator.java b/wjcy-common/src/main/java/me/zhengjie/utils/DateTimeValidator.java new file mode 100644 index 0000000..1d22b75 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/DateTimeValidator.java @@ -0,0 +1,46 @@ +package me.zhengjie.utils; + + +import cn.hutool.core.util.ObjectUtil; +import me.zhengjie.annotation.DateTime; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.text.SimpleDateFormat; +/** + *

+ * 日期格式效验 + *

+ * + * @Author xx + * @Date 2021/7/27 + **/ +public class DateTimeValidator implements ConstraintValidator { + private DateTime dateTime; + + @Override + public void initialize(DateTime dateTime) { + this.dateTime = dateTime; + } + + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + if (ObjectUtil.isEmpty(value)) { + return true; + } + String format = dateTime.format(); + + if (value.length() != format.length()) { + return false; + } + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); + + try { + simpleDateFormat.parse(value); + } catch (Exception e) { + return false; + } + return true; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/DateUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/DateUtil.java new file mode 100644 index 0000000..3df2210 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/DateUtil.java @@ -0,0 +1,555 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.zhengjie.utils; + +import cn.hutool.core.util.ObjectUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.util.*; + +/** + * @author: liaojinlong + * @date: 2020/6/11 16:28 + * @apiNote: JDK 8 新日期类 格式化与字符串转换 工具类 + */ +public class DateUtil { + + private static final Logger LOGGER = LoggerFactory.getLogger(DateUtil.class); + + public static final DateTimeFormatter DFY_MD_HMS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + public static final DateTimeFormatter DFY_MD = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + + /** + * + * 判断某个时间是否在某个时间段内 + * @ xxs + * @param date 待比较的时间 + * @param format 时间格式,eg("HH:mm") + * @param startTimeStr 时间范围的开始时间,eg("06:00") + * @param endTimeStr 时间范围的结束时间,eg("22:00") + * + * */ + public static Boolean isBelong(Date date, String format, String startTimeStr, String endTimeStr){ + //设置日期格式 + SimpleDateFormat df = new SimpleDateFormat(format); + Date beginTime = null; + Date endTime = null; + try { + date = df.parse(df.format(date)); + beginTime = df.parse(startTimeStr); + endTime = df.parse(endTimeStr); + } catch (Exception e) { + e.printStackTrace(); + } + + return belongCalendar(date, beginTime, endTime); + } + + + + /** + * 判断时间是否在时间段内 + * @xxs + * @param nowTime + * @param beginTime + * @param endTime + * @return + */ + public static boolean belongCalendar(Date nowTime, Date beginTime, Date endTime) { + Calendar date = Calendar.getInstance(); + date.setTime(nowTime); + + Calendar begin = Calendar.getInstance(); + begin.setTime(beginTime); + + Calendar end = Calendar.getInstance(); + end.setTime(endTime); + + if (date.after(begin) && date.before(end)) { + return true; + } else { + return false; + } + } + + /** + * 比较两日期格式大小(最新的时间靠前) + * 1: time1time2 + * 0: time1=time2 + * null time1 or time2 日期格式错误 + * + * @param time1 yyyy-MM-dd HH:mm:ss + * @param time2 yyyy-MM-dd HH:mm:ss + * @return + */ + public static Integer compareDate(String time1, String time2) { + try { + LocalDateTime t1 = parseLocalDateTimeFormatyMdHms(time1); + LocalDateTime t2 = parseLocalDateTimeFormatyMdHms(time2); + Long timeStamp1 = getTimeStamp(t1); + Long timeStamp2 = getTimeStamp(t2); + if (timeStamp1 < timeStamp2) { + return 1; + } + if (timeStamp1 > timeStamp2) { + return -1; + } + if (timeStamp1.equals(timeStamp2)) { + return 0; + } + } catch (Exception e) {} + return null; + } + + /** + * 获得指定日期的前一天 + * + * @param specifiedDay + * @return + * @throws Exception + */ + public static String getSpecifiedDayBefore(String specifiedDay) { + Calendar c = Calendar.getInstance(); + Date date = null; + try { + date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay); + } catch (ParseException e) { + e.printStackTrace(); + } + c.setTime(date); + int day = c.get(Calendar.DATE); + c.set(Calendar.DATE, day - 1); + + String dayBefore = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime()); + return dayBefore; + } + + /** + * 获取今日查询时间 + * + * @return + */ + public static Map getTodayDate(String time) { + Map map = new HashMap(16); + map.put("stime", time + " 00:00:00"); + map.put("etime", time + " 23:59:59"); + return map; + } + + + /** + * 根据发送时间获取有效截止时间 + * + * @param sendTime yyyy-MM-dd HH:mm:ss + * @param days 有效天数 + * @return + */ + public static LocalDate getExpiryDate(String sendTime, Integer days) { + if (ObjectUtil.isEmpty(sendTime)) { + sendTime = getCurrentTime(); + } + return LocalDate.parse(sendTime, DFY_MD_HMS) + .plusDays(days); + } + + /** + * 将年月日时分秒的各种转为cron表达式 + * + * @param time + * @return + */ + public static String toCronString(String time) { + LocalDateTime dateTime = LocalDateTime.parse(time, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + return dateTime.getSecond() + " " + dateTime.getMinute() + " " + dateTime.getHour() + " " + + dateTime.getDayOfMonth() + " " + dateTime.getMonthValue() + " ? " + dateTime.getYear(); + } + + /** + * 获取当时时间 yyyy-MM-dd HH:mm:ss格式 + * + * @return + */ + public static String getCurrentTime() { + return localDateTimeFormatyMdHms(LocalDateTime.now()); + } + + /** + * 获取系统当前时间 + * + * @return 系统当前时间(年月日) + */ + public static String getCurrentDateHalf() { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + String date = simpleDateFormat.format(new Date()); + return date; + } + /** + * 获取系统未来某天的日期 + * + * @return 系统昨天时间(年月日) + */ + public static String getFutrueDateHalf(Integer day) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + String date = simpleDateFormat.format(new Date()); + Calendar calendar = new GregorianCalendar(); + calendar.setTime(new Date()); + calendar.add(Calendar.DATE, day); + return simpleDateFormat.format(calendar.getTime()); + } + /** + * 获取系统前12小时时间 + * + * @return 系统前12小时时间(年月日) + */ + public static String getCurrentTimeBeforeTwHour() { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String date = simpleDateFormat.format(new Date()); + Calendar calendar = new GregorianCalendar(); + calendar.setTime(new Date()); + calendar.add(Calendar.HOUR, -12); + return simpleDateFormat.format(calendar.getTime()); + } + /** + * 获取系统昨天时间 + * + * @return 系统昨天时间(年月日) + */ + public static String getYesterDateHalf() { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + String date = simpleDateFormat.format(new Date()); + Calendar calendar = new GregorianCalendar(); + calendar.setTime(new Date()); + calendar.add(Calendar.DATE, -1); + return simpleDateFormat.format(calendar.getTime()); + } + /** + * 获取系统昨天时间 + * + * @return 系统昨天时间(年月日) + */ + public static String getAgoDateHalf(int i) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + String date = simpleDateFormat.format(new Date()); + Calendar calendar = new GregorianCalendar(); + calendar.setTime(new Date()); + calendar.add(Calendar.DATE, -i); + return simpleDateFormat.format(calendar.getTime()); + } + /** + * 获取系统昨天时间 + * + * @return 系统昨天时间(年月日) + */ + public static String getWeekAgoDateHalf() { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + String date = simpleDateFormat.format(new Date()); + Calendar calendar = new GregorianCalendar(); + calendar.setTime(new Date()); + calendar.add(Calendar.DATE, -7); + return simpleDateFormat.format(calendar.getTime()); + } + /** + * 获取当时时间+10min yyyy-MM-dd HH:mm:ss格式 + * + * @return + */ + public static String getCurrentTimeAddTenMin() { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String date = simpleDateFormat.format(new Date()); + Calendar calendar = new GregorianCalendar(); + calendar.setTime(new Date()); + calendar.add(Calendar.MINUTE, 10); + return simpleDateFormat.format(calendar.getTime()); + } + + /**获取后两分钟 + * @param startTime + * @return + */ + public static String getLaterTimeAddTwoMin(String startTime){ + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Calendar calendar = new GregorianCalendar(); + try { + + calendar.setTime(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(startTime)); + calendar.add(Calendar.MINUTE, 2); + } catch (Exception exception) { + LOGGER.error(exception.getMessage()); + } + return simpleDateFormat.format(calendar.getTime()); + } + /**获取前一天 + * @param startTime + * @return + */ + public static String getAgoTimeAddDay(String startTime){ + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Calendar calendar = new GregorianCalendar(); + try { + + calendar.setTime(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(startTime)); + calendar.add(Calendar.HOUR, -24); + } catch (Exception exception) { + LOGGER.error(exception.getMessage()); + } + return simpleDateFormat.format(calendar.getTime()); + } + /**获取后一天 + * @param startTime + * @return + */ + public static String getLaterTimeAddDay(String startTime){ + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Calendar calendar = new GregorianCalendar(); + try { + + calendar.setTime(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(startTime)); + calendar.add(Calendar.HOUR, 24); + } catch (Exception exception) { + LOGGER.error(exception.getMessage()); + } + return simpleDateFormat.format(calendar.getTime()); + } + /** 获取前十分钟 时间 + * @param startTime + * @return + */ + public static String getEarlyTimeAddTenMin(String startTime){ + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Calendar calendar = new GregorianCalendar(); + try { + + calendar.setTime(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(startTime)); + calendar.add(Calendar.MINUTE, -10); + } catch (Exception exception) { + LOGGER.error(exception.getMessage()); + } + return simpleDateFormat.format(calendar.getTime()); + } + + /** + * LocalDateTime 转时间戳 + * + * @param localDateTime / + * @return / + */ + public static Long getTimeStamp(LocalDateTime localDateTime) { + return localDateTime.atZone(ZoneId.systemDefault()).toEpochSecond(); + } + + /** + * 时间戳转LocalDateTime + * + * @param timeStamp / + * @return / + */ + public static LocalDateTime fromTimeStamp(Long timeStamp) { + return LocalDateTime.ofEpochSecond(timeStamp, 0, OffsetDateTime.now().getOffset()); + } + + /** + * LocalDateTime 转 Date + * Jdk8 后 不推荐使用 {@link Date} Date + * + * @param localDateTime / + * @return / + */ + public static Date toDate(LocalDateTime localDateTime) { + return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); + } + + /** + * LocalDate 转 Date + * Jdk8 后 不推荐使用 {@link Date} Date + * + * @param localDate / + * @return / + */ + public static Date toDate(LocalDate localDate) { + return toDate(localDate.atTime(LocalTime.now(ZoneId.systemDefault()))); + } + + + /** + * Date转 LocalDateTime + * Jdk8 后 不推荐使用 {@link Date} Date + * + * @param date / + * @return / + */ + public static LocalDateTime toLocalDateTime(Date date) { + return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); + } + + /** + * 日期 格式化 + * + * @param localDateTime / + * @param patten / + * @return / + */ + public static String localDateTimeFormat(LocalDateTime localDateTime, String patten) { + DateTimeFormatter df = DateTimeFormatter.ofPattern(patten); + return df.format(localDateTime); + } + + /** + * 日期 格式化 + * + * @param localDateTime / + * @param df / + * @return / + */ + public static String localDateTimeFormat(LocalDateTime localDateTime, DateTimeFormatter df) { + return df.format(localDateTime); + } + + /** + * 日期格式化 yyyy-MM-dd HH:mm:ss + * + * @param localDateTime / + * @return / + */ + public static String localDateTimeFormatyMdHms(LocalDateTime localDateTime) { + return DFY_MD_HMS.format(localDateTime); + } + + /** + * 日期格式化 yyyy-MM-dd + * + * @param localDateTime / + * @return / + */ + public String localDateTimeFormatyMd(LocalDateTime localDateTime) { + return DFY_MD.format(localDateTime); + } + + /** + * 字符串转 LocalDateTime ,字符串格式 yyyy-MM-dd + * + * @param localDateTime / + * @return / + */ + public static LocalDateTime parseLocalDateTimeFormat(String localDateTime, String pattern) { + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern); + return LocalDateTime.from(dateTimeFormatter.parse(localDateTime)); + } + + /** + * 字符串转 LocalDateTime ,字符串格式 yyyy-MM-dd + * + * @param localDateTime / + * @return / + */ + public static LocalDateTime parseLocalDateTimeFormat(String localDateTime, DateTimeFormatter dateTimeFormatter) { + return LocalDateTime.from(dateTimeFormatter.parse(localDateTime)); + } + + /** + * 字符串转 LocalDateTime ,字符串格式 yyyy-MM-dd HH:mm:ss + * + * @param localDateTime / + * @return / + */ + public static LocalDateTime parseLocalDateTimeFormatyMdHms(String localDateTime) { + return LocalDateTime.from(DFY_MD_HMS.parse(localDateTime)); + } + + /** + * 字符串转 LocalDate ,字符串格式 yyyy-MM-dd + * @param localDate + * @return + */ + public static LocalDate parseLocalDateFormatyMd(String localDate) { + return LocalDate.from(DFY_MD.parse(localDate)); + } + + /** + * 生成指定时间之前相聚 指定秒的一个时间并返回 + * 时间格式默认常规 年月日 时分秒: 2020-12-07 10:18:25 + * @param endTime + * @param min 相聚多少秒 + * @param max + * @return + */ + public static String getRandmo(String endTime, Integer min, Integer max) { + + if (min > max) { + return null; + } + + try { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); + Date endTimeDate = format.parse(endTime); + Random random = new Random(); + long time = random.nextInt(max - min + 1) + min; + Date newDate = new Date(endTimeDate .getTime() - time * 1000); + return format.format(newDate); + }catch (Exception exception) { + return null; + } + } + + /** + * @Description: 获取当天日期再查询日期区间的第几个位置,起始位置从0开始算 + * @Author: zeng + * @param stime + * @param etime + * @return: java.lang.Integer + */ + public static Long getDifferenceDayCount(String stime,String etime) { + if (!ObjectUtil.isAllNotEmpty(stime, etime)) { + return null; + } + LocalDate sLocalDate = parseLocalDateTimeFormatyMdHms(stime).toLocalDate(); + LocalDate eLocalDate = parseLocalDateTimeFormatyMdHms(etime).toLocalDate(); + + return Math.abs(eLocalDate.toEpochDay() - sLocalDate.toEpochDay())+1; + } + + + public static String getHour(long dt) { + //秒数 +// Integer dt = Integer.parseInt(date) ; + if (dt < 3600) { + return Math.round(dt / 60) + "分钟"; + } + int hour = Math.round(dt / 3600); + int minute = Math.round((dt - (hour * 3600)) / 60); + long s = dt - (hour == 0 ? 0 : hour * 3600) - (minute == 0 ? 0 : minute * 60); + return hour == 0 ? "" : hour + "小时" + (minute == 0 ? "" : minute + "分钟") + (s == 0 ? "" : s + "秒"); + + //分钟 +// Integer dt = Integer.parseInt(date) ; +// if (dt < 60) return dt + "分钟"; +// int hour = Math.round(dt / 60); +// int minute = Math.round(dt - (hour * 60)); +// return hour + "小时" + (minute == 0 ? "" : minute + "分钟"); + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/ElAdminConstant.java b/wjcy-common/src/main/java/me/zhengjie/utils/ElAdminConstant.java new file mode 100644 index 0000000..08f9c3c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/ElAdminConstant.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +/** + * 常用静态常量 + * + * @author Zheng Jie + * @date 2018-12-26 + */ +public class ElAdminConstant { + + /** + * 用于IP定位转换 + */ + public static final String REGION = "内网IP|内网IP"; + /** + * win 系统 + */ + public static final String WIN = "win"; + + /** + * mac 系统 + */ + public static final String MAC = "mac"; + + /** + * 常用接口 + */ + public static class Url { + // IP归属地查询 + public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp?ip=%s&json=true"; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/EmptyAttributeFiler.java b/wjcy-common/src/main/java/me/zhengjie/utils/EmptyAttributeFiler.java new file mode 100644 index 0000000..c7fdd93 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/EmptyAttributeFiler.java @@ -0,0 +1,76 @@ +package me.zhengjie.utils; + + +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; + +import java.lang.reflect.Field; +import java.util.List; +/** + *

+ * 将数据为空或空字符串的过滤为null(MyBatis 会将空字符串的值也持久化到数据库中) + *

+ * + * @Author xx + * @Date 2021/7/19 + **/ +@Slf4j +public class EmptyAttributeFiler { + + /** + * 判断list的所有元素是否都为null + * @param list + * @return + */ + public static boolean isEmpty(List list) { + if (ObjectUtil.isEmpty(list)) { + return true; + } + for (Object o : list) { + if (ObjectUtil.isNotEmpty(o)) { + return false; + } + } + return true; + } + + public static T emptyAttributeFiler(T obj) { + Class clazz = obj.getClass(); + Field[] fields = clazz.getDeclaredFields(); + try { + for (Field field : fields) { + field.setAccessible(true); + if (ObjectUtil.isEmpty(field.get(obj))) { + field.set(obj, null); + } + } + } catch (Exception e) { + log.error("过滤值为空属性失败:" + e.getMessage(), e); + } + return obj; + } + + public static String emptyAttributeFilerToString(Object obj) { + Class clazz = obj.getClass(); + Field[] fields = clazz.getDeclaredFields(); + StringBuffer sbf = new StringBuffer("{"); + try { + int i = 0; + for (Field field : fields) { + field.setAccessible(true); + if (ObjectUtil.isNotEmpty(field.get(obj))) { + if (i != 0) { + sbf.append(","+field.getName() + ":" + field.get(obj)); + continue; + } + sbf.append(field.getName() + ":" + field.get(obj)); + i++; + } + } + } catch (Exception e) { + log.error("过滤值为空属性失败:" + e.getMessage(), e); + } + sbf.append("}"); + return sbf.toString().length()==2?"":sbf.toString(); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/EncryptUtils.java b/wjcy-common/src/main/java/me/zhengjie/utils/EncryptUtils.java new file mode 100644 index 0000000..4f334aa --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/EncryptUtils.java @@ -0,0 +1,100 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESKeySpec; +import javax.crypto.spec.IvParameterSpec; +import java.nio.charset.StandardCharsets; + +/** + * 加密 + * @author Zheng Jie + * @date 2018-11-23 + */ + +public class EncryptUtils { + + private static final String STR_PARAM = "Passw0rd"; + + private static Cipher cipher; + + private static final IvParameterSpec IV = new IvParameterSpec(STR_PARAM.getBytes(StandardCharsets.UTF_8)); + + private static DESKeySpec getDesKeySpec(String source) throws Exception { + if (source == null || source.length() == 0){ + return null; + } + cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); + String strKey = "Passw0rd"; + return new DESKeySpec(strKey.getBytes(StandardCharsets.UTF_8)); + } + + /** + * 对称加密 + */ + public static String desEncrypt(String source) throws Exception { + DESKeySpec desKeySpec = getDesKeySpec(source); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + SecretKey secretKey = keyFactory.generateSecret(desKeySpec); + cipher.init(Cipher.ENCRYPT_MODE, secretKey, IV); + return byte2hex( + cipher.doFinal(source.getBytes(StandardCharsets.UTF_8))).toUpperCase(); + } + + /** + * 对称解密 + */ + public static String desDecrypt(String source) throws Exception { + byte[] src = hex2byte(source.getBytes(StandardCharsets.UTF_8)); + DESKeySpec desKeySpec = getDesKeySpec(source); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + SecretKey secretKey = keyFactory.generateSecret(desKeySpec); + cipher.init(Cipher.DECRYPT_MODE, secretKey, IV); + byte[] retByte = cipher.doFinal(src); + return new String(retByte); + } + + private static String byte2hex(byte[] inStr) { + String stmp; + StringBuilder out = new StringBuilder(inStr.length * 2); + for (byte b : inStr) { + stmp = Integer.toHexString(b & 0xFF); + if (stmp.length() == 1) { + // 如果是0至F的单位字符串,则添加0 + out.append("0").append(stmp); + } else { + out.append(stmp); + } + } + return out.toString(); + } + + private static byte[] hex2byte(byte[] b) { + int size = 2; + if ((b.length % size) != 0){ + throw new IllegalArgumentException("长度不是偶数"); + } + byte[] b2 = new byte[b.length / 2]; + for (int n = 0; n < b.length; n += size) { + String item = new String(b, n, 2); + b2[n / 2] = (byte) Integer.parseInt(item, 16); + } + return b2; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/FileUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/FileUtil.java new file mode 100644 index 0000000..e8577d0 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/FileUtil.java @@ -0,0 +1,351 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.poi.excel.BigExcelWriter; +import cn.hutool.poi.excel.ExcelUtil; +import me.zhengjie.exception.BadRequestException; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.security.MessageDigest; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * File工具类,扩展 hutool 工具包 + * + * @author Zheng Jie + * @date 2018-12-27 + */ +public class FileUtil extends cn.hutool.core.io.FileUtil { + + private static final Logger log = LoggerFactory.getLogger(FileUtil.class); + + /** + * 系统临时目录 + *
+ * windows 包含路径分割符,但Linux 不包含, + * 在windows \\==\ 前提下, + * 为安全起见 同意拼装 路径分割符, + *
+     *       java.io.tmpdir
+     *       windows : C:\Users/xxx\AppData\Local\Temp\
+     *       linux: /temp
+     * 
+ */ + public static final String SYS_TEM_DIR = System.getProperty("java.io.tmpdir") + File.separator; + /** + * 定义GB的计算常量 + */ + private static final int GB = 1024 * 1024 * 1024; + /** + * 定义MB的计算常量 + */ + private static final int MB = 1024 * 1024; + /** + * 定义KB的计算常量 + */ + private static final int KB = 1024; + + /** + * 格式化小数 + */ + private static final DecimalFormat DF = new DecimalFormat("0.00"); + + public static final String IMAGE = "图片"; + public static final String TXT = "文档"; + public static final String MUSIC = "音乐"; + public static final String VIDEO = "视频"; + public static final String OTHER = "其他"; + + + /** + * MultipartFile转File + */ + public static File toFile(MultipartFile multipartFile) { + // 获取文件名 + String fileName = multipartFile.getOriginalFilename(); + // 获取文件后缀 + String prefix = "." + getExtensionName(fileName); + File file = null; + try { + // 用uuid作为文件名,防止生成的临时文件重复 + file = new File(SYS_TEM_DIR + IdUtil.simpleUUID() + prefix); + // MultipartFile to File + multipartFile.transferTo(file); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + return file; + } + + /** + * 获取文件扩展名,不带 . + */ + public static String getExtensionName(String filename) { + if ((filename != null) && (filename.length() > 0)) { + int dot = filename.lastIndexOf('.'); + if ((dot > -1) && (dot < (filename.length() - 1))) { + return filename.substring(dot + 1); + } + } + return filename; + } + + /** + * Java文件操作 获取不带扩展名的文件名 + */ + public static String getFileNameNoEx(String filename) { + if ((filename != null) && (filename.length() > 0)) { + int dot = filename.lastIndexOf('.'); + if ((dot > -1) && (dot < (filename.length()))) { + return filename.substring(0, dot); + } + } + return filename; + } + + /** + * 文件大小转换 + */ + public static String getSize(long size) { + String resultSize; + if (size / GB >= 1) { + //如果当前Byte的值大于等于1GB + resultSize = DF.format(size / (float) GB) + "GB "; + } else if (size / MB >= 1) { + //如果当前Byte的值大于等于1MB + resultSize = DF.format(size / (float) MB) + "MB "; + } else if (size / KB >= 1) { + //如果当前Byte的值大于等于1KB + resultSize = DF.format(size / (float) KB) + "KB "; + } else { + resultSize = size + "B "; + } + return resultSize; + } + + /** + * inputStream 转 File + */ + public static File inputStreamToFile(InputStream ins, String name){ + File file = new File(SYS_TEM_DIR + name); + if (file.exists()) { + return file; + } + OutputStream os = null; + try { + os = new FileOutputStream(file); + int bytesRead; + int len = 8192; + byte[] buffer = new byte[len]; + while ((bytesRead = ins.read(buffer, 0, len)) != -1) { + os.write(buffer, 0, bytesRead); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + CloseUtil.close(os); + CloseUtil.close(ins); + } + return file; + } + + /** + * 将文件名解析成文件的上传路径 + */ + public static File upload(MultipartFile file, String filePath) { + Date date = new Date(); + SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssS"); + String name = getFileNameNoEx(file.getOriginalFilename()); + String suffix = getExtensionName(file.getOriginalFilename()); + String nowStr = "-" + format.format(date); + try { + String fileName = name + nowStr + "." + suffix; + String path = filePath + fileName; + // getCanonicalFile 可解析正确各种路径 + File dest = new File(path).getCanonicalFile(); + // 检测是否存在目录 + if (!dest.getParentFile().exists()) { + if (!dest.getParentFile().mkdirs()) { + System.out.println("was not successful."); + } + } + // 文件写入 + file.transferTo(dest); + return dest; + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return null; + } + + /** + * 导出excel + */ + public static void downloadExcel(List> list, HttpServletResponse response) throws IOException { + String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx"; + File file = new File(tempPath); + BigExcelWriter writer = ExcelUtil.getBigWriter(file); + // 一次性写出内容,使用默认样式,强制输出标题 + writer.write(list, true); + //response为HttpServletResponse对象 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); + //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码 + response.setHeader("Content-Disposition", "attachment;filename=file.xlsx"); + ServletOutputStream out = response.getOutputStream(); + // 终止后删除临时文件 + file.deleteOnExit(); + writer.flush(out, true); + //此处记得关闭输出Servlet流 + IoUtil.close(out); + } + + public static String getFileType(String type) { + String documents = "txt doc pdf ppt pps xlsx xls docx"; + String music = "mp3 wav wma mpa ram ra aac aif m4a"; + String video = "avi mpg mpe mpeg asf wmv mov qt rm mp4 flv m4v webm ogv ogg"; + String image = "bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg"; + if (image.contains(type)) { + return IMAGE; + } else if (documents.contains(type)) { + return TXT; + } else if (music.contains(type)) { + return MUSIC; + } else if (video.contains(type)) { + return VIDEO; + } else { + return OTHER; + } + } + + public static void checkSize(long maxSize, long size) { + // 1M + int len = 1024 * 1024; + if (size > (maxSize * len)) { + throw new BadRequestException("文件超出规定大小"); + } + } + + /** + * 判断两个文件是否相同 + */ + public static boolean check(File file1, File file2) { + String img1Md5 = getMd5(file1); + String img2Md5 = getMd5(file2); + if(img1Md5 != null){ + return img1Md5.equals(img2Md5); + } + return false; + } + + /** + * 判断两个文件是否相同 + */ + public static boolean check(String file1Md5, String file2Md5) { + return file1Md5.equals(file2Md5); + } + + private static byte[] getByte(File file) { + // 得到文件长度 + byte[] b = new byte[(int) file.length()]; + InputStream in = null; + try { + in = new FileInputStream(file); + try { + System.out.println(in.read(b)); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } finally { + CloseUtil.close(in); + } + return b; + } + + private static String getMd5(byte[] bytes) { + // 16进制字符 + char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + try { + MessageDigest mdTemp = MessageDigest.getInstance("MD5"); + mdTemp.update(bytes); + byte[] md = mdTemp.digest(); + int j = md.length; + char[] str = new char[j * 2]; + int k = 0; + // 移位 输出字符串 + for (byte byte0 : md) { + str[k++] = hexDigits[byte0 >>> 4 & 0xf]; + str[k++] = hexDigits[byte0 & 0xf]; + } + return new String(str); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return null; + } + + /** + * 下载文件 + * + * @param request / + * @param response / + * @param file / + */ + public static void downloadFile(HttpServletRequest request, HttpServletResponse response, File file, boolean deleteOnExit) { + response.setCharacterEncoding(request.getCharacterEncoding()); + response.setContentType("application/octet-stream"); + FileInputStream fis = null; + try { + fis = new FileInputStream(file); + response.setHeader("Content-Disposition", "attachment; filename=" + file.getName()); + IOUtils.copy(fis, response.getOutputStream()); + response.flushBuffer(); + } catch (Exception e) { + log.error(e.getMessage(), e); + } finally { + if (fis != null) { + try { + fis.close(); + if (deleteOnExit) { + file.deleteOnExit(); + } + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } + } + } + + public static String getMd5(File file) { + return getMd5(getByte(file)); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/HexUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/HexUtil.java new file mode 100644 index 0000000..96cf5d5 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/HexUtil.java @@ -0,0 +1,51 @@ +package me.zhengjie.utils; + +import cn.hutool.core.util.ObjectUtil; +import static jodd.util.CharUtil.HEX_CHARS; +/** + *

+ * dy登录加密校验 + *

+ * + * @Author xx + * @Date 2021/7/21 + **/ +public class HexUtil { + + public static String toHexString(byte[] bArr, int i, int i2) { + if (bArr == null) { + throw new NullPointerException("bytes is null"); + } else if (i < 0 || i + i2 > bArr.length) { + throw new IndexOutOfBoundsException(); + } else { + int i3 = i2 * 2; + char[] cArr = new char[i3]; + int i4 = 0; + for (int i5 = 0; i5 < i2; i5++) { + int i6 = bArr[i5 + i] & 255; + int i7 = i4 + 1; + cArr[i4] = HEX_CHARS[i6 >> 4]; + i4 = i7 + 1; + cArr[i7] = HEX_CHARS[i6 & 15]; + } + return new String(cArr, 0, i3); + } + } + + + public static String encryptWithXor(String str) { + try { + if (ObjectUtil.isEmpty(str)) { + return null; + } + byte[] bytes = str.getBytes("UTF-8"); + for (int i = 0; i < bytes.length; i++) { + bytes[i] = (byte) (bytes[i] ^ 5); + } + return toHexString(bytes, 0, bytes.length); + } catch (Exception unused) { + return str; + } + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/HttpClientUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/HttpClientUtil.java new file mode 100644 index 0000000..618c216 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/HttpClientUtil.java @@ -0,0 +1,356 @@ +package me.zhengjie.utils; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +/** + * @author rch + * @date 2022-06-22 + */ +@Slf4j +public class HttpClientUtil { + + public static String postJson(String url, String body, String charset) { + + String result = null; + if (null == charset) { + charset = "UTF-8"; + } + CloseableHttpClient httpClient = null; + HttpPost httpPost = null; + try { + httpClient = HttpConnectionManager.getInstance().getHttpClient(); + httpPost = new HttpPost(url); + + // 设置连接超时,设置读取超时 + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(3000) + .setSocketTimeout(3000) + .build(); + httpPost.setConfig(requestConfig); + + httpPost.setHeader("Accept", "application/json"); + httpPost.setHeader("Content-Type", "application/json;charset=utf-8"); + + // 设置参数 + StringEntity se = new StringEntity(body, "UTF-8"); + httpPost.setEntity(se); + HttpResponse response = httpClient.execute(httpPost); + if (response != null) { + HttpEntity resEntity = response.getEntity(); + if (resEntity != null) { + result = EntityUtils.toString(resEntity, charset); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + log.error(ex.getMessage()); + } + + return result; + } + + + public static String postJson(String url, Map heards, String body, String charset) { + + String result = null; + if (null == charset) { + charset = "UTF-8"; + } + CloseableHttpClient httpClient = null; + HttpPost httpPost = null; + try { + httpClient = HttpConnectionManager.getInstance().getHttpClient(); + httpPost = new HttpPost(url); + + // 设置连接超时,设置读取超时 + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(3000) + .setSocketTimeout(3000) + .build(); + httpPost.setConfig(requestConfig); + + for (Map.Entry heard:heards.entrySet()) { + httpPost.setHeader(heard.getKey(), heard.getValue().toString()); + } + + // 设置参数 + StringEntity se = new StringEntity(body, "UTF-8"); + httpPost.setEntity(se); + HttpResponse response = httpClient.execute(httpPost); + if (response != null) { + HttpEntity resEntity = response.getEntity(); + if (resEntity != null) { + result = EntityUtils.toString(resEntity, charset); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + log.error(ex.getMessage()); + } + + return result; + } + + + /** + * 发送 POST 请求(HTTP),K-V形式 + * + * @param apiUrl + * API接口URL + * @param params + * 参数map + * @return + */ + public static String doPostHttp(String apiUrl, Map params) { + CloseableHttpClient httpClient = HttpClients.createDefault(); + String httpStr = null; + HttpPost httpPost = new HttpPost(apiUrl); + CloseableHttpResponse response = null; + + try { + // 设置连接超时,设置读取超时 + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(10000) + .setSocketTimeout(10000) + .build(); + httpPost.setConfig(requestConfig); + httpPost.setHeader("Accept", "application/json"); + httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded"); + + List pairList = new ArrayList<>(params.size()); + for (Entry entry : params.entrySet()) { + NameValuePair pair = new BasicNameValuePair(entry.getKey(), Convert.toStr(entry.getValue())); + pairList.add(pair); + } + httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8"))); + response = httpClient.execute(httpPost); +// System.out.println("http==response.toString():" + response.toString()); + HttpEntity entity = response.getEntity(); + httpStr = EntityUtils.toString(entity, "UTF-8"); + } catch (IOException e) { + e.printStackTrace(); + log.error(e.getMessage()); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + } catch (IOException e) { + e.printStackTrace(); + log.error(e.getMessage()); + } + } + } + return httpStr; + } + + /** + * 发送 GET 请求(HTTP),K-V形式 + * + * @param apiUrl + * API接口URL + * @param params + * 参数map + * @return + */ + public static String getHttp(String apiUrl,Map params){ + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = ""; + try { + String url = apiUrl; + if(MapUtil.isNotEmpty(params)){ + String paramsStr = ""; + for (String key : params.keySet()) { + if(ObjectUtil.isNotEmpty(params.get(key))){ + if(StrUtil.isNotEmpty(paramsStr)){ + paramsStr += "&" + key + "=" + params.get(key); + }else{ + paramsStr += key + "=" + params.get(key); + } + } + } + if(StrUtil.isNotEmpty(paramsStr)){ + url += "?" + paramsStr; + } + } + httpClient = HttpClients.createDefault(); + System.out.println("url:" + url); + HttpGet httpGet = new HttpGet(url); + // 设置连接超时,设置读取超时 + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(5000) + .setSocketTimeout(5000) + .build(); + httpGet.setConfig(requestConfig); + response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + result = EntityUtils.toString(entity, "UTF-8"); + } catch (IOException e) { + e.printStackTrace(); + log.error(e.getMessage()); + } finally { + if (response != null) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + log.error(e.getMessage()); + } + } + if (httpClient != null) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + log.error(e.getMessage()); + } + } + } + return result; + } + + + + /** + * 发送 GET 请求(HTTP) + * + * @param apiUrl + * API接口URL + * @return + */ + public static String getUrlHttp(String apiUrl){ + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = ""; + try { + String url = apiUrl; + httpClient = HttpClients.createDefault(); + System.out.println("url:" + url); + HttpGet httpGet = new HttpGet(url); + // 设置连接超时,设置读取超时 + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(5000) + .setSocketTimeout(5000) + .build(); + httpGet.setConfig(requestConfig); + response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + result = EntityUtils.toString(entity, "UTF-8"); + } catch (IOException e) { + e.printStackTrace(); + log.error(e.getMessage()); + } finally { + if (response != null) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + log.error(e.getMessage()); + } + } + if (httpClient != null) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + log.error(e.getMessage()); + } + } + } + return result; + } + + /** + * 发送 POST 请求(HTTP),K-V形式 + * + * @param apiUrl + * API接口URL + * @param params + * 参数map + * @return + */ + public static String postHttp(String apiUrl,Map params){ + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = ""; + try { + String url = apiUrl; + httpClient = HttpClients.createDefault(); + HttpPost httpPost = new HttpPost(url); + // 设置连接超时,设置读取超时 + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(5000) + .setSocketTimeout(5000) + .build(); + httpPost.setConfig(requestConfig); + if(MapUtil.isNotEmpty(params)){ + StringEntity se = new StringEntity(JSONUtil.toJsonStr(params), "UTF-8"); + se.setContentType("application/json"); + httpPost.setEntity(se); + } + response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + result = EntityUtils.toString(entity, "UTF-8"); + } catch (IOException e) { + e.printStackTrace(); + log.error(e.getMessage()); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + } catch (IOException e) { + e.printStackTrace(); + log.error(e.getMessage()); + } + } + if (httpClient != null) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + log.error(e.getMessage()); + } + } + } + return result; + } + + + public static void main(String[] args) { + String url = "http://kjw.utest6.com/forcol/a"; + Map params = new HashMap<>(16); + params.put("page",1); + params.put("pageSize",10000); + params.put("beginTime","2022-04-01 21:00:00"); + + String result = postHttp(url,params); + System.out.println(result); + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/HttpConnectionManager.java b/wjcy-common/src/main/java/me/zhengjie/utils/HttpConnectionManager.java new file mode 100644 index 0000000..85dc9c8 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/HttpConnectionManager.java @@ -0,0 +1,57 @@ +package me.zhengjie.utils; + + +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.LayeredConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.springframework.stereotype.Component; + +import javax.net.ssl.SSLContext; +import java.security.NoSuchAlgorithmException; + +@Component +public class HttpConnectionManager { + + private PoolingHttpClientConnectionManager cm = null; + + private static HttpConnectionManager connectionManager; + + public static HttpConnectionManager getInstance() { + if (connectionManager == null) { + synchronized (HttpConnectionManager.class) { + if (connectionManager == null) { + connectionManager = new HttpConnectionManager(); + connectionManager.init(); + } + } + } + return connectionManager; + } + + private void init() { + LayeredConnectionSocketFactory sslsf = null; + try { + sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault()); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + Registry socketFactoryRegistry = RegistryBuilder. create() + .register("https", sslsf).register("http", new PlainConnectionSocketFactory()).build(); + cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + cm.setMaxTotal(200); + cm.setDefaultMaxPerRoute(20); + } + + public CloseableHttpClient getHttpClient() { + CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build(); + + return httpClient; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/JsonDealUtils.java b/wjcy-common/src/main/java/me/zhengjie/utils/JsonDealUtils.java new file mode 100644 index 0000000..ecf2793 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/JsonDealUtils.java @@ -0,0 +1,54 @@ +package me.zhengjie.utils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; + +import java.util.Iterator; +import java.util.Set; + +/** + * 递归去除Json字符串空值(key和value) + * + * @author rch + * @create 2022-06-27 + */ +public class JsonDealUtils { + + public static JSONObject getNoNullValue(String json) { + JSONObject objTem=JSON.parseObject(json); + JSONObject objRel=JSON.parseObject(json); + return deal(objTem,objRel); + } + + private static JSONObject deal(JSONObject objTem,JSONObject objRel) { + Set keySet = objTem.keySet(); + Iterator iterator = keySet.iterator(); + while(iterator.hasNext()) { + String temp = iterator.next(); + Object objR = objTem.get(temp); + if(temp==null||"".equals(temp)||"null".equals(temp)) { + objRel.remove(temp); + continue; + } + if(objR==null||"".equals(objR.toString())||"null".equals(objR.toString())||"[]".equals(objR.toString())||"{}".equals(objR.toString())) { + objRel.remove(temp); + continue; + } + if(objR instanceof JSONObject) { + JSONObject j=(JSONObject)objR; + JSONObject object2 = (JSONObject)objRel.get(temp); + deal(j,object2); + continue; + } + if(objR instanceof JSONArray) { + JSONArray jsonArray = objTem.getJSONArray(temp); + JSONArray jsonArray2 = objRel.getJSONArray(temp); + for(int i=0;i + * MD5工具类 + *

+ * + * @author: rch + * @since: 2020-12-03 + */ + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class MD5Util { + + /** * 生成16位小写md5加密字符串 * @param sourceStr * @return */ + public static String MD5ToLow16(String sourceStr) { + try { + // 获得MD5摘要算法的 MessageDigest对象 + StringBuffer buf = getMD5StringBuffer(sourceStr); + return buf.toString().substring(8, 24).toLowerCase();// 16位加密 + // return buf.toString();// 32位加密 + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** * 生成16位大写md5加密字符串 * @param sourceStr * @return */ + public static String MD5ToUpp16(String sourceStr) { + try { + // 获得MD5摘要算法的 MessageDigest对象 + StringBuffer buf = getMD5StringBuffer(sourceStr); + return buf.toString().substring(8, 24).toUpperCase();// 16位加密 + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** * 生成32位小写md5加密字符串 * @param sourceStr * @return */ + public static String MD5ToLow32(String sourceStr) { + try { + // 获得MD5摘要算法的 MessageDigest对象 + StringBuffer buf = getMD5StringBuffer(sourceStr); + return buf.toString().toLowerCase();// 32位加密 + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** * 生成32位大写md5加密字符串 * @param sourceStr * @return */ + public static String MD5ToUpp32(String sourceStr) { + try { + StringBuffer buf = getMD5StringBuffer(sourceStr); + + return buf.toString().toUpperCase();// 32位加密 + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** * 将字符串MD5加密 * @param sourceStr * @return * @throws NoSuchAlgorithmException */ + private static StringBuffer getMD5StringBuffer(String sourceStr) throws NoSuchAlgorithmException { + // 获得MD5摘要算法的 MessageDigest对象 + MessageDigest mdInst = MessageDigest.getInstance("MD5"); + // 使用指定的字节更新摘要 + mdInst.update(sourceStr.getBytes()); + // 获得密文 + byte[] md = mdInst.digest(); + // 把密文转换成十六进制的字符串形式 + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < md.length; i++) { + int tmp = md[i]; + if (tmp < 0){ + tmp += 256; + } + if (tmp < 16){ + buf.append("0"); + } + buf.append(Integer.toHexString(tmp)); + } + return buf; + } + + public static String md5(String str) { + try { + MessageDigest md5 = MessageDigest.getInstance("MD5"); + md5.update((str).getBytes("UTF-8")); + byte b[] = md5.digest(); + + int i; + StringBuffer buf = new StringBuffer(""); + + for (int offset = 0; offset < b.length; offset++) { + i = b[offset]; + if (i < 0) { + i += 256; + } + if (i < 16) { + buf.append("0"); + } + buf.append(Integer.toHexString(i)); + } + return buf.toString(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public static void main(String[] args) { +// String str = "1"; +// System.out.println(str); +// System.out.println(MD5ToLow16(str)); +// System.out.println(MD5ToLow32(str)); +// System.out.println(MD5ToUpp16(str)); +// System.out.println(MD5ToUpp32(str)); + String ttt = "sportsCe7vS3j1ziPHwfDDffJ3ivX34Z1cb2S1133687017471620710415600000004www.sportstatus.comzhU33255"; + System.out.println(md5(ttt)); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/OrderGetIndexUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/OrderGetIndexUtil.java new file mode 100644 index 0000000..8bce737 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/OrderGetIndexUtil.java @@ -0,0 +1,63 @@ +package me.zhengjie.utils; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + *

+ * --顺序访问 + * 第几次访问 % 钱包池中有几个排序钱包 得到 当前应该取钱包池中钱包的索引 实现顺序访问。 + *

+ * + * @author: rch + * @date: 2021-09-25 + */ +public class OrderGetIndexUtil { + + private static Map concurrentHashMap = new ConcurrentHashMap<>(16); + + /** + * @param merId 商家id + * @return 指定钱包池中当前该取钱包id 下标索引 + */ + public static int getIncrement(Long merId, Integer walletType, Integer passType) { + + String keyStr = merId + "-" + walletType + "-" + passType; + AtomicInteger atomicInteger = new AtomicInteger(0); + + Integer current; + int next; + do { + current = concurrentHashMap.get(keyStr); + current = current != null ? current : 0; + atomicInteger = new AtomicInteger(current); + next = current >= 2147483647 ? 0 : current+1; + + }while (!atomicInteger.compareAndSet(current, next)); + + concurrentHashMap.put(keyStr, next); + System.out.println("------------第几次访问:次数next="+next); + return next; + } + + public static void main(String[] args) { + for (int i = 0; i < 10; i++) { + if (i % 5 == 0) { + System.out.println("0==" + getIncrement(1L, 1, 1)); + } else if (i % 5 == 1) { + System.out.println("1==" + getIncrement(1L, 2, 1)); + } else if (i % 5 == 2) { + System.out.println("2==" + getIncrement(2L, 1, 1)); + } else if (i % 5 == 3) { + System.out.println("2==" + getIncrement(2L, 2,1)); + } else if (i % 5 == 4) { + System.out.println("3==" + getIncrement(2L, 3,1)); + } else { + System.out.println("!2=" + getIncrement(11L, 3, 1)); + } + } + + System.out.println("2==" + getIncrement(2L, 1, 1)); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/PageUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/PageUtil.java new file mode 100644 index 0000000..44db68d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/PageUtil.java @@ -0,0 +1,63 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import org.springframework.data.domain.Page; +import java.util.*; + +/** + * 分页工具 + * @author Zheng Jie + * @date 2018-12-10 + */ +public class PageUtil extends cn.hutool.core.util.PageUtil { + + /** + * List 分页 + */ + public static List toPage(int page, int size , List list) { + int fromIndex = page * size; + int toIndex = page * size + size; + if(fromIndex > list.size()){ + return new ArrayList(); + } else if(toIndex >= list.size()) { + return list.subList(fromIndex,list.size()); + } else { + return list.subList(fromIndex,toIndex); + } + } + + /** + * Page 数据处理,预防redis反序列化报错 + */ + public static Map toPage(Page page) { + Map map = new LinkedHashMap<>(2); + map.put("content",page.getContent()); + map.put("totalElements",page.getTotalElements()); + return map; + } + + /** + * 自定义分页 + */ + public static Map toPage(Object object, Object totalElements) { + Map map = new LinkedHashMap<>(2); + map.put("content",object); + map.put("totalElements",totalElements); + return map; + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/PageUtils.java b/wjcy-common/src/main/java/me/zhengjie/utils/PageUtils.java new file mode 100644 index 0000000..cbf8730 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/PageUtils.java @@ -0,0 +1,55 @@ +package me.zhengjie.utils; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.Data; + +import java.util.Collections; +import java.util.List; +/** + *

+ * 分页查询工具类 + *

+ * + * @Author xx + * @Date 2021/7/19 + **/ +@Data +public class PageUtils { + /** + * 总记录数 + */ + private Long total; + /** + * 查询结果 + */ + private List list; + + public PageUtils() { + + } + + public PageUtils(Long total, List list) { + this.total = total; + this.list = list; + } + + public PageUtils(Page page) { + this.total = page.getTotal(); + this.list = page.getRecords(); + } + + public Long getTotal() { + if (ObjectUtil.isNull(total)|| EmptyAttributeFiler.isEmpty(list)) { + return 0L; + } + return total; + } + + public List getList() { + if (EmptyAttributeFiler.isEmpty(list)) { + return Collections.emptyList(); + } + return list; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/PopularizeUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/PopularizeUtil.java new file mode 100644 index 0000000..ebb422e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/PopularizeUtil.java @@ -0,0 +1,49 @@ +package me.zhengjie.utils; + +import cn.hutool.core.lang.UUID; + + +/** + * 推广码生成 工具类 + * + * @author: e + * @since: 2022/01/19 + */ +public class PopularizeUtil { + + public static String[] chars = new String[] { "a", "b", "c", "d", "e", "f", + "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", + "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", + "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", + "W", "X", "Y", "Z" }; + + /** + * 创建推广码 + * @return + */ + public static String createPromoCode(){ + return generateShortUuid().toUpperCase(); + //return RandomUtil.randomString(8).toUpperCase(); + } + + + public static String generateShortUuid() { + StringBuffer shortBuffer = new StringBuffer(); + String uuid = UUID.randomUUID().toString().replace("-", ""); + for (int i = 0; i < 8; i++) { + String str = uuid.substring(i * 4, i * 4 + 4); + int x = Integer.parseInt(str, 16); + shortBuffer.append(chars[x % 0x3E]); + } + return shortBuffer.toString(); + + } + + public static void main(String[] args) { + + + } + + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/PropertiesUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/PropertiesUtil.java new file mode 100644 index 0000000..3dab51b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/PropertiesUtil.java @@ -0,0 +1,62 @@ +package me.zhengjie.utils; + +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.config.SystemConfig; + +import java.io.*; +import java.util.Properties; + +/* + * + * @Description 读取多语言文本工具类 + * @Date 2021/12/16 + * @Author zeng + */ +@Slf4j +public class PropertiesUtil { + + public static String getByCode(Integer code, String language) { + FileInputStream fis = null; + InputStreamReader isr = null; + BufferedReader br = null; + try { + File file = new File(SystemConfig.LANGUAGE_PATH); + if (file.exists()) { + for (File listFile : file.listFiles()) { + if (listFile.getName().contains(language + ".properties")) { + Properties properties = new Properties(); + fis = new FileInputStream(listFile); + isr = new InputStreamReader(fis, "UTF-8"); + BufferedReader bf = new BufferedReader(isr); + properties.load(bf); + return properties.getProperty(code.toString()); + } + } + } + + } catch (FileNotFoundException e) { + log.error("文件不存在=========================="); + } catch (IOException e) { + log.error("文件读取异常=========================="); + }finally { + try { + if (ObjectUtil.isNotNull(br)) { + br.close(); + } + if (ObjectUtil.isNotNull(isr)) { + isr.close(); + } + if (ObjectUtil.isNotNull(fis)){ + fis.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + } + log.error("=============读取多语言文本失败================== code:{} language:{}", code, language); + return null; + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/QueryHelp.java b/wjcy-common/src/main/java/me/zhengjie/utils/QueryHelp.java new file mode 100644 index 0000000..69cb5e2 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/QueryHelp.java @@ -0,0 +1,208 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.DataPermission; +import me.zhengjie.annotation.Query; +import javax.persistence.criteria.*; +import java.lang.reflect.Field; +import java.util.*; + +/** + * @author Zheng Jie + * @date 2019-6-4 14:59:48 + */ +@Slf4j +@SuppressWarnings({"unchecked","all"}) +public class QueryHelp { + + public static Predicate getPredicate(Root root, Q query, CriteriaBuilder cb) { + List list = new ArrayList<>(); + if(query == null){ + return cb.and(list.toArray(new Predicate[0])); + } + // 数据权限验证 + DataPermission permission = query.getClass().getAnnotation(DataPermission.class); + if(permission != null){ + // 获取数据权限 + List dataScopes = SecurityUtils.getCurrentUserDataScope(); + if(CollectionUtil.isNotEmpty(dataScopes)){ + if(StringUtils.isNotBlank(permission.joinName()) && StringUtils.isNotBlank(permission.fieldName())) { + Join join = root.join(permission.joinName(), JoinType.LEFT); + list.add(getExpression(permission.fieldName(),join, root).in(dataScopes)); + } else if (StringUtils.isBlank(permission.joinName()) && StringUtils.isNotBlank(permission.fieldName())) { + list.add(getExpression(permission.fieldName(),null, root).in(dataScopes)); + } + } + } + try { + List fields = getAllFields(query.getClass(), new ArrayList<>()); + for (Field field : fields) { + boolean accessible = field.isAccessible(); + // 设置对象的访问权限,保证对private的属性的访 + field.setAccessible(true); + Query q = field.getAnnotation(Query.class); + if (q != null) { + String propName = q.propName(); + String joinName = q.joinName(); + String blurry = q.blurry(); + String attributeName = isBlank(propName) ? field.getName() : propName; + Class fieldType = field.getType(); + Object val = field.get(query); + if (ObjectUtil.isNull(val) || "".equals(val)) { + continue; + } + Join join = null; + // 模糊多字段 + if (ObjectUtil.isNotEmpty(blurry)) { + String[] blurrys = blurry.split(","); + List orPredicate = new ArrayList<>(); + for (String s : blurrys) { + orPredicate.add(cb.like(root.get(s) + .as(String.class), "%" + val.toString() + "%")); + } + Predicate[] p = new Predicate[orPredicate.size()]; + list.add(cb.or(orPredicate.toArray(p))); + continue; + } + if (ObjectUtil.isNotEmpty(joinName)) { + String[] joinNames = joinName.split(">"); + for (String name : joinNames) { + switch (q.join()) { + case LEFT: + if(ObjectUtil.isNotNull(join) && ObjectUtil.isNotNull(val)){ + join = join.join(name, JoinType.LEFT); + } else { + join = root.join(name, JoinType.LEFT); + } + break; + case RIGHT: + if(ObjectUtil.isNotNull(join) && ObjectUtil.isNotNull(val)){ + join = join.join(name, JoinType.RIGHT); + } else { + join = root.join(name, JoinType.RIGHT); + } + break; + case INNER: + if(ObjectUtil.isNotNull(join) && ObjectUtil.isNotNull(val)){ + join = join.join(name, JoinType.INNER); + } else { + join = root.join(name, JoinType.INNER); + } + break; + default: break; + } + } + } + switch (q.type()) { + case EQUAL: + list.add(cb.equal(getExpression(attributeName,join,root) + .as((Class) fieldType),val)); + break; + case GREATER_THAN: + list.add(cb.greaterThanOrEqualTo(getExpression(attributeName,join,root) + .as((Class) fieldType), (Comparable) val)); + break; + case LESS_THAN: + list.add(cb.lessThanOrEqualTo(getExpression(attributeName,join,root) + .as((Class) fieldType), (Comparable) val)); + break; + case LESS_THAN_NQ: + list.add(cb.lessThan(getExpression(attributeName,join,root) + .as((Class) fieldType), (Comparable) val)); + break; + case INNER_LIKE: + list.add(cb.like(getExpression(attributeName,join,root) + .as(String.class), "%" + val.toString() + "%")); + break; + case LEFT_LIKE: + list.add(cb.like(getExpression(attributeName,join,root) + .as(String.class), "%" + val.toString())); + break; + case RIGHT_LIKE: + list.add(cb.like(getExpression(attributeName,join,root) + .as(String.class), val.toString() + "%")); + break; + case IN: + if (CollUtil.isNotEmpty((Collection)val)) { + list.add(getExpression(attributeName,join,root).in((Collection) val)); + } + break; + case NOT_IN: + if (CollUtil.isNotEmpty((Collection)val)) { + list.add(getExpression(attributeName,join,root).in((Collection) val).not()); + } + break; + case NOT_EQUAL: + list.add(cb.notEqual(getExpression(attributeName,join,root), val)); + break; + case NOT_NULL: + list.add(cb.isNotNull(getExpression(attributeName,join,root))); + break; + case IS_NULL: + list.add(cb.isNull(getExpression(attributeName,join,root))); + break; + case BETWEEN: + List between = new ArrayList<>((List)val); + list.add(cb.between(getExpression(attributeName, join, root).as((Class) between.get(0).getClass()), + (Comparable) between.get(0), (Comparable) between.get(1))); + break; + default: break; + } + } + field.setAccessible(accessible); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + } + int size = list.size(); + return cb.and(list.toArray(new Predicate[size])); + } + + @SuppressWarnings("unchecked") + private static Expression getExpression(String attributeName, Join join, Root root) { + if (ObjectUtil.isNotEmpty(join)) { + return join.get(attributeName); + } else { + return root.get(attributeName); + } + } + + private static boolean isBlank(final CharSequence cs) { + int strLen; + if (cs == null || (strLen = cs.length()) == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + if (!Character.isWhitespace(cs.charAt(i))) { + return false; + } + } + return true; + } + + public static List getAllFields(Class clazz, List fields) { + if (clazz != null) { + fields.addAll(Arrays.asList(clazz.getDeclaredFields())); + getAllFields(clazz.getSuperclass(), fields); + } + return fields; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/RedisUtils.java b/wjcy-common/src/main/java/me/zhengjie/utils/RedisUtils.java new file mode 100644 index 0000000..c633b81 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/RedisUtils.java @@ -0,0 +1,903 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.*; +import org.springframework.data.redis.support.atomic.RedisAtomicLong; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * @author / + */ +@Component +@SuppressWarnings({"unchecked", "all"}) +public class RedisUtils { + private static final Logger log = LoggerFactory.getLogger(RedisUtils.class); + private RedisTemplate redisTemplate; + @Value("${jwt.online-key}") + private String onlineKey; + + public static String LOGIN_FAIL_COUNT = "LOGIN_FAIL_COUNT:%s"; + public static String BLOCKED_ACCOUNT = "BLOCKED_ACCOUNT:%s"; + + public RedisUtils(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + */ + public boolean expire(String key, long time) { + try { + if (time > 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + return true; + } + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + * @param timeUnit 单位 + */ + public boolean expire(String key, long time, TimeUnit timeUnit) { + try { + if (time > 0) { + redisTemplate.expire(key, time, timeUnit); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + return true; + } + + /** + * 根据 key 获取过期时间 + * + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(Object key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 查找匹配key + * + * @param pattern key + * @return / + */ + public List scan(String pattern) { + ScanOptions options = ScanOptions.scanOptions().match(pattern).build(); + RedisConnectionFactory factory = redisTemplate.getConnectionFactory(); + RedisConnection rc = Objects.requireNonNull(factory).getConnection(); + Cursor cursor = rc.scan(options); + List result = new ArrayList<>(); + while (cursor.hasNext()) { + result.add(new String(cursor.next())); + } + try { + RedisConnectionUtils.releaseConnection(rc, factory); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return result; + } + + /** + * 分页查询 key + * + * @param patternKey key + * @param page 页码 + * @param size 每页数目 + * @return / + */ + public List findKeysForPage(String patternKey, int page, int size) { + ScanOptions options = ScanOptions.scanOptions().match(patternKey).build(); + RedisConnectionFactory factory = redisTemplate.getConnectionFactory(); + RedisConnection rc = Objects.requireNonNull(factory).getConnection(); + Cursor cursor = rc.scan(options); + List result = new ArrayList<>(size); + int tmpIndex = 0; + int fromIndex = page * size; + int toIndex = page * size + size; + while (cursor.hasNext()) { + if (tmpIndex >= fromIndex && tmpIndex < toIndex) { + result.add(new String(cursor.next())); + tmpIndex++; + continue; + } + // 获取到满足条件的数据后,就可以退出了 + if (tmpIndex >= toIndex) { + break; + } + tmpIndex++; + cursor.next(); + } + try { + RedisConnectionUtils.releaseConnection(rc, factory); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return result; + } + + /** + * 判断key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + return redisTemplate.hasKey(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + public void del(String... keys) { + if (keys != null && keys.length > 0) { + if (keys.length == 1) { + boolean result = redisTemplate.delete(keys[0]); + log.debug("--------------------------------------------"); + log.debug(new StringBuilder("删除缓存:").append(keys[0]).append(",结果:").append(result).toString()); + log.debug("--------------------------------------------"); + } else { + Set keySet = new HashSet<>(); + for (String key : keys) { + keySet.addAll(redisTemplate.keys(key)); + } + long count = redisTemplate.delete(keySet); + log.debug("--------------------------------------------"); + log.debug("成功删除缓存:" + keySet.toString()); + log.debug("缓存删除数量:" + count + "个"); + log.debug("--------------------------------------------"); + } + } + } + + /** + * setIfAbsent 如果key 不存在则 set value 并返回true + * 否则返回false; + * @param key + * @param value + * @return + */ + public Boolean setIfAbsent(String key, String value) { + + try { + return redisTemplate.opsForValue().setIfAbsent(key, value); + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + // ============================String============================= + + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public Object get(String key) { + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + /** + * 批量获取 + * + * @param keys + * @return + */ + public List multiGet(List keys) { + Object obj = redisTemplate.opsForValue().multiGet(Collections.singleton(keys)); + return null; + } + + /** + * 普通缓存放入 + * + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String key, Object value) { + try { + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间 + * @param timeUnit 类型 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time, TimeUnit timeUnit) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, timeUnit); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + // ================================Map================================= + + /** + * HashGet + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return 值 + */ + public Object hget(String key, String item) { + return redisTemplate.opsForHash().get(key, item); + } + + /** + * 获取hashKey对应的所有键值 + * + * @param key 键 + * @return 对应的多个键值 + */ + public Map hmget(String key) { + return redisTemplate.opsForHash().entries(key); + + } + + /** + * HashSet + * + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + public boolean hmset(String key, Map map) { + try { + redisTemplate.opsForHash().putAll(key, map); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * HashSet 并设置时间 + * + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + public boolean hmset(String key, Map map, long time) { + try { + redisTemplate.opsForHash().putAll(key, map); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value) { + try { + redisTemplate.opsForHash().put(key, item, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value, long time) { + try { + redisTemplate.opsForHash().put(key, item, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 删除hash表中的值 + * + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + public void hdel(String key, Object... item) { + redisTemplate.opsForHash().delete(key, item); + } + + /** + * 判断hash表中是否有该项的值 + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + return redisTemplate.opsForHash().hasKey(key, item); + } + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * + * @param key 键 + * @param item 项 + * @param by 要增加几(大于0) + * @return + */ + public double hincr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, by); + } + + /** + * 自增 + * @param key + * @param liveTime 单位秒 + * @return + */ + public Long incrAndExpire(String key, long liveTime) { + RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); + Long increment = entityIdCounter.getAndIncrement(); + + if ((null == increment || increment.longValue() == 0) && liveTime > 0) {//初始设置过期时间 + entityIdCounter.expire(liveTime, TimeUnit.SECONDS); + } + + return Long.valueOf(StrUtil.toString(get(key))); + } + + /** + * hash递减 + * + * @param key 键 + * @param item 项 + * @param by 要减少记(小于0) + * @return + */ + public double hdecr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, -by); + } + + // ============================set============================= + + /** + * 根据key获取Set中的所有值 + * + * @param key 键 + * @return + */ + public Set sGet(String key) { + try { + return redisTemplate.opsForSet().members(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * 随机返回并删除名称为key的set中的一个元素 + * + * @param key 键 + * @return + */ + public ZSetOperations.TypedTuple randomObj(String key) { + try { + Long xxx = redisTemplate.opsForZSet().size(key); + if (ObjectUtil.isEmpty(xxx)) { + return null; + } + Set> allSet = redisTemplate.opsForZSet().rangeWithScores(key,0,-1); + // 随机数 + int leng = allSet.size(); + Random r = new Random(); + Integer arrayindex = r.nextInt(leng); + List> results = new ArrayList<>(allSet); + ZSetOperations.TypedTuple randomObj = results.get(arrayindex); + return randomObj; + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * 根据value从一个set中查询,是否存在 + * + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + try { + return redisTemplate.opsForSet().isMember(key, value); + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将数据放入set缓存 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSet(String key, Object... values) { + try { + return redisTemplate.opsForSet().add(key, values); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 将set数据放入缓存 + * + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + try { + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0) { + expire(key, time); + } + return count; + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 获取set缓存的长度 + * + * @param key 键 + * @return + */ + public long sGetSetSize(String key) { + try { + return redisTemplate.opsForSet().size(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 移除值为value的 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + try { + Long count = redisTemplate.opsForSet().remove(key, values); + return count; + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + // ===============================list================================= + + /** + * 获取list缓存的内容 + * + * @param key 键 + * @param start 开始 + * @param end 结束 0 到 -1代表所有值 + * @return + */ + public List lGet(String key, long start, long end) { + try { + return redisTemplate.opsForList().range(key, start, end); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * rpop + * + * @param key 键 + * @return + */ + public Object rPop(String key) { + try { + return redisTemplate.opsForList().rightPop(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * rpop + * + * @param key 键 + * @return + */ + public Object lPop(String key) { + try { + return redisTemplate.opsForList().leftPop(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * rightPush + * + * @param key 键 + * @return + */ + public Object rPush(String key, Object object) { + try { + return redisTemplate.opsForList().rightPush(key, object); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * lPush + * + * @param key 键 + * @return + */ + public Object lPush(String key, Object object) { + try { + return redisTemplate.opsForList().leftPush(key, object); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * 获取list缓存的长度 + * + * @param key 键 + * @return + */ + public long lGetListSize(String key) { + try { + return redisTemplate.opsForList().size(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 通过索引 获取list中的值 + * + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * @return + */ + public Object lGetIndex(String key, long index) { + try { + return redisTemplate.opsForList().index(key, index); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, Object value) { + try { + redisTemplate.opsForList().leftPush(key, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value, long time) { + try { + redisTemplate.opsForList().rightPush(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将String放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean put(String key, Object value, long time) { + try { + redisTemplate.opsForValue().set(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, List value) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, List value, long time) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 根据索引修改list中的某条数据 + * + * @param key 键 + * @param index 索引 + * @param value 值 + * @return / + */ + public boolean lUpdateIndex(String key, long index, Object value) { + try { + redisTemplate.opsForList().set(key, index, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 移除N个值为value + * + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + try { + return redisTemplate.opsForList().remove(key, count, value); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * @param prefix 前缀 + * @param ids id + */ + public void delByKeys(String prefix, Set ids) { + Set keys = new HashSet<>(); + for (Long id : ids) { + keys.addAll(redisTemplate.keys(new StringBuffer(prefix).append(id).toString())); + } + long count = redisTemplate.delete(keys); + // 此处提示可自行删除 + log.debug("--------------------------------------------"); + log.debug("成功删除缓存:" + keys.toString()); + log.debug("缓存删除数量:" + count + "个"); + log.debug("--------------------------------------------"); + } + + // ===============================setsort================================= + + /** + * 添加元素到变量中同时指定元素的分值。 + * @param key + * @param value + * @param score + * @return + */ + public boolean zSortAdd(String key, Object value, double score) { + try { + redisTemplate.opsForZSet().add(key, value, score); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 根据分值移除区间元素。 + * @param key + * @param min + * @param max + * @return + */ + public Long removeRangeByScore(String key, double min, double max) { + return redisTemplate.opsForZSet().removeRangeByScore(key, min, max); + } + + /** + * 获取变量指定区间的元素。 + * @param key + * @param start + * @param end + * @return + */ + public Set range(String key, long start, long end) { + return redisTemplate.opsForZSet().range(key, start, end); + } + + /** + * 返回有序集 key 中,成员 member 的 score 值。 + * 如果 member 元素不是有序集 key 的成员,或 key 不存在,返回 nil 。 + * @param key + * @param member + * @return + */ + public Double zscore(String key, Object member) { + return redisTemplate.opsForZSet().score(key, member); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/RedissonUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/RedissonUtil.java new file mode 100644 index 0000000..f02ed00 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/RedissonUtil.java @@ -0,0 +1,167 @@ +package me.zhengjie.utils; + + +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.exception.BadRequestException; +import org.redisson.api.*; +import org.redisson.config.Config; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +/** + *

+ * redisson + *

+ * + * @Author xx + * @Date 2021/8/11 + **/ +@Slf4j +@Component("redissonUtil") +public class RedissonUtil { + + @Resource + private RedissonClient redissonClient; + + public void getRedissonClient() throws IOException { + Config config = redissonClient.getConfig(); +// System.out.println(config.toJSON().toString()); + } + + /**` + * 获取字符串对象 + * + * @param objectName + * @return + */ + public RBucket getRBucket(String objectName) { + RBucket bucket = redissonClient.getBucket(objectName); + return bucket; + } + + /** + * 获取Map对象 + * + * @param objectName + * @return + */ + public RMap getRMap(String objectName) { + RMap map = redissonClient.getMap(objectName); + return map; + } + + /** + * 获取有序集合 + * + * @param objectName + * @return + */ + public RSortedSet getRSortedSet(String objectName) { + RSortedSet sortedSet = redissonClient.getSortedSet(objectName); + return sortedSet; + } + + /** + * 获取集合 + * + * @param objectName + * @return + */ + public RSet getRSet(String objectName) { + RSet rSet = redissonClient.getSet(objectName); + return rSet; + } + + /** + * 获取列表 + * + * @param objectName + * @return + */ + public RList getRList(String objectName) { + RList rList = redissonClient.getList(objectName); + return rList; + } + + /** + * 获取队列 + * + * @param objectName + * @return + */ + public RQueue getRQueue(String objectName) { + RQueue rQueue = redissonClient.getQueue(objectName); + return rQueue; + } + + /** + * 获取双端队列 + * + * @param objectName + * @return + */ + public RDeque getRDeque(String objectName) { + RDeque rDeque = redissonClient.getDeque(objectName); + return rDeque; + } + + + /** + * 获取锁 + * + * @param objectName + * @return + */ + public RLock getRLock(String objectName) { + RLock rLock = redissonClient.getLock(objectName); + return rLock; + } + + /** + * 获取读取锁 + * + * @param objectName + * @return + */ + public RReadWriteLock getRWLock(String objectName) { + RReadWriteLock rwlock = redissonClient.getReadWriteLock(objectName); + return rwlock; + } + + /** + * 获取原子数 + * + * @param objectName + * @return + */ + public RAtomicLong getRAtomicLong(String objectName) { + RAtomicLong rAtomicLong = redissonClient.getAtomicLong(objectName); + return rAtomicLong; + } + + /** + * 获取记数锁 + * + * @param objectName + * @return + */ + public RCountDownLatch getRCountDownLatch(String objectName) { + RCountDownLatch rCountDownLatch = redissonClient.getCountDownLatch(objectName); + return rCountDownLatch; + } + + /** + * 获取消息的Topic + * + * @param objectName + * @return + */ + public RTopic getRTopic(String objectName) { + RTopic rTopic = redissonClient.getTopic(objectName); + return rTopic; + } +} + diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/RequestHolder.java b/wjcy-common/src/main/java/me/zhengjie/utils/RequestHolder.java new file mode 100644 index 0000000..2720ae5 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/RequestHolder.java @@ -0,0 +1,50 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; +import me.zhengjie.enums.LanguageEnum; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import javax.servlet.http.HttpServletRequest; +import java.util.Objects; + +/** + * 获取 HttpServletRequest + * @author Zheng Jie + * @date 2018-11-24 + */ +public class RequestHolder { + + public static HttpServletRequest getHttpServletRequest() { + return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); + } + + public static String getLanguage() { + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + if (ObjectUtil.isNull(requestAttributes) || !(requestAttributes instanceof ServletRequestAttributes)) { + return LanguageEnum.ZH.getValue(); + } + HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); + if (ObjectUtil.isNull(request)) { + return LanguageEnum.ZH.getValue(); + } + return Convert.toStr(request.getHeader("language"), LanguageEnum.ZH.getValue()); + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/RsaUtils.java b/wjcy-common/src/main/java/me/zhengjie/utils/RsaUtils.java new file mode 100644 index 0000000..b42cec7 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/RsaUtils.java @@ -0,0 +1,202 @@ +package me.zhengjie.utils; + +import org.apache.commons.codec.binary.Base64; +import javax.crypto.Cipher; +import java.io.ByteArrayOutputStream; +import java.security.*; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/** + * @author https://www.cnblogs.com/nihaorz/p/10690643.html + * @description Rsa 工具类,公钥私钥生成,加解密 + * @date 2020-05-18 + **/ +public class RsaUtils { + + private static final String SRC = "panpan@123"; + + public static void main(String[] args) throws Exception { +// System.out.println("\n"); +// RsaKeyPair keyPair = generateKeyPair(); +// System.out.println("公钥:" + keyPair.getPublicKey()); +// System.out.println("私钥:" + keyPair.getPrivateKey()); +// System.out.println("\n"); +// test1(keyPair); +// System.out.println("\n"); +// test2(keyPair); +// System.out.println("\n"); + + + String text1 = encryptByPublicKey("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdFXJjqlBdh1ri8hS2bEvwjREJyRAqruwtf+c/bgFiBOxuW4LAVIiMnimfnmLiL0/h0Q1YLKjrnFkOwXLvZTgwwCiX1uF5WhOyCsGEEQDhfvFTlInemFNdi8zqWxoONbRBb9wJbqS8K6LtzXu2Oltu5hzqQXKwY+sNCVbKCrt/KwIDAQAB", RsaUtils.SRC); + System.out.println(text1); + } + + /** + * 公钥加密私钥解密 + */ + private static void test1(RsaKeyPair keyPair) throws Exception { + System.out.println("***************** 公钥加密私钥解密开始 *****************"); + String text1 = encryptByPublicKey(keyPair.getPublicKey(), RsaUtils.SRC); + String text2 = decryptByPrivateKey(keyPair.getPrivateKey(), text1); + System.out.println("加密前:" + RsaUtils.SRC); + System.out.println("加密后:" + text1); + System.out.println("解密后:" + text2); + if (RsaUtils.SRC.equals(text2)) { + System.out.println("解密字符串和原始字符串一致,解密成功"); + } else { + System.out.println("解密字符串和原始字符串不一致,解密失败"); + } + System.out.println("***************** 公钥加密私钥解密结束 *****************"); + } + + /** + * 私钥加密公钥解密 + * @throws Exception / + */ + private static void test2(RsaKeyPair keyPair) throws Exception { + System.out.println("***************** 私钥加密公钥解密开始 *****************"); + String text1 = encryptByPrivateKey(keyPair.getPrivateKey(), RsaUtils.SRC); + String text2 = decryptByPublicKey(keyPair.getPublicKey(), text1); + System.out.println("加密前:" + RsaUtils.SRC); + System.out.println("加密后:" + text1); + System.out.println("解密后:" + text2); + if (RsaUtils.SRC.equals(text2)) { + System.out.println("解密字符串和原始字符串一致,解密成功"); + } else { + System.out.println("解密字符串和原始字符串不一致,解密失败"); + } + System.out.println("***************** 私钥加密公钥解密结束 *****************"); + } + + /** + * 公钥解密 + * + * @param publicKeyText 公钥 + * @param text 待解密的信息 + * @return / + * @throws Exception / + */ + public static String decryptByPublicKey(String publicKeyText, String text) throws Exception { + X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, publicKey); + byte[] result = doLongerCipherFinal(Cipher.DECRYPT_MODE, cipher, Base64.decodeBase64(text)); + return new String(result); + } + + /** + * 私钥加密 + * + * @param privateKeyText 私钥 + * @param text 待加密的信息 + * @return / + * @throws Exception / + */ + public static String encryptByPrivateKey(String privateKeyText, String text) throws Exception { + PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + byte[] result = doLongerCipherFinal(Cipher.ENCRYPT_MODE, cipher, text.getBytes()); + return Base64.encodeBase64String(result); + } + + /** + * 私钥解密 + * + * @param privateKeyText 私钥 + * @param text 待解密的文本 + * @return / + * @throws Exception / + */ + public static String decryptByPrivateKey(String privateKeyText, String text) throws Exception { + PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] result = doLongerCipherFinal(Cipher.DECRYPT_MODE, cipher, Base64.decodeBase64(text)); + return new String(result); + } + + /** + * 公钥加密 + * + * @param publicKeyText 公钥 + * @param text 待加密的文本 + * @return / + */ + public static String encryptByPublicKey(String publicKeyText, String text) throws Exception { + X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] result = doLongerCipherFinal(Cipher.ENCRYPT_MODE, cipher, text.getBytes()); + return Base64.encodeBase64String(result); + } + + private static byte[] doLongerCipherFinal(int opMode,Cipher cipher, byte[] source) throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + if (opMode == Cipher.DECRYPT_MODE) { + out.write(cipher.doFinal(source)); + } else { + int offset = 0; + int totalSize = source.length; + while (totalSize - offset > 0) { + int size = Math.min(cipher.getOutputSize(0) - 11, totalSize - offset); + out.write(cipher.doFinal(source, offset, size)); + offset += size; + } + } + out.close(); + return out.toByteArray(); + } + + /** + * 构建RSA密钥对 + * + * @return / + * @throws NoSuchAlgorithmException / + */ + public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(1024); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); + RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); + String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded()); + String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded()); + return new RsaKeyPair(publicKeyString, privateKeyString); + } + + + /** + * RSA密钥对对象 + */ + public static class RsaKeyPair { + + private final String publicKey; + private final String privateKey; + + public RsaKeyPair(String publicKey, String privateKey) { + this.publicKey = publicKey; + this.privateKey = privateKey; + } + + public String getPublicKey() { + return publicKey; + } + + public String getPrivateKey() { + return privateKey; + } + + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/SecurityUtils.java b/wjcy-common/src/main/java/me/zhengjie/utils/SecurityUtils.java new file mode 100644 index 0000000..dfeee43 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/SecurityUtils.java @@ -0,0 +1,109 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.utils.enums.DataScopeEnum; +import org.springframework.http.HttpStatus; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import java.util.List; + +/** + * 获取当前登录的用户 + * @author Zheng Jie + * @date 2019-01-17 + */ +@Slf4j +public class SecurityUtils { + + /** + * 获取当前登录的用户 + * @return UserDetails + */ + public static UserDetails getCurrentUser() { + UserDetailsService userDetailsService = SpringContextHolder.getBean(UserDetailsService.class); + return userDetailsService.loadUserByUsername(getCurrentUsername()); + } + + /** + * 获取系统用户名称 + * + * @return 系统用户名称 + */ + public static String getCurrentUsername() { + final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null) { + throw new BadRequestException(HttpStatus.UNAUTHORIZED, "当前登录状态过期"); + } + if (authentication.getPrincipal() instanceof UserDetails) { + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + return userDetails.getUsername(); + } + throw new BadRequestException(HttpStatus.UNAUTHORIZED, "找不到当前登录的信息"); + } + + /** + * 获取系统用户ID + * @return 系统用户ID + */ + public static Long getCurrentUserId() { + UserDetails userDetails = getCurrentUser(); + return new JSONObject(new JSONObject(userDetails).get("user")).get("id", Long.class); + } + + /** + * 是否是总商户号 + * @return true:是 + */ + public static boolean isAdmin() { + UserDetails userDetails = getCurrentUser(); + return new JSONObject(new JSONObject(userDetails).get("user")).get("isAdmin", Boolean.class); + } + + + public static boolean isNotAdmin() { + return !isAdmin(); + } + + /** + * 获取当前用户的数据权限 + * @return / + */ + public static List getCurrentUserDataScope(){ + UserDetails userDetails = getCurrentUser(); + JSONArray array = JSONUtil.parseArray(new JSONObject(userDetails).get("dataScopes")); + return JSONUtil.toList(array,Long.class); + } + + /** + * 获取数据权限级别 + * @return 级别 + */ + public static String getDataScopeType() { + List dataScopes = getCurrentUserDataScope(); + if(dataScopes.size() != 0){ + return ""; + } + return DataScopeEnum.ALL.getValue(); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/SpringContextHolder.java b/wjcy-common/src/main/java/me/zhengjie/utils/SpringContextHolder.java new file mode 100644 index 0000000..4f3aaf6 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/SpringContextHolder.java @@ -0,0 +1,151 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.core.env.Environment; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author Jie + * @date 2019-01-07 + */ +@Slf4j +public class SpringContextHolder implements ApplicationContextAware, DisposableBean { + + private static ApplicationContext applicationContext = null; + private static final List CALL_BACKS = new ArrayList<>(); + private static boolean addCallback = true; + + /** + * 针对 某些初始化方法,在SpringContextHolder 未初始化时 提交回调方法。 + * 在SpringContextHolder 初始化后,进行回调使用 + * + * @param callBack 回调函数 + */ + public synchronized static void addCallBacks(CallBack callBack) { + if (addCallback) { + SpringContextHolder.CALL_BACKS.add(callBack); + } else { + log.warn("CallBack:{} 已无法添加!立即执行", callBack.getCallBackName()); + callBack.executor(); + } + } + + /** + * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. + */ + @SuppressWarnings("unchecked") + public static T getBean(String name) { + assertContextInjected(); + return (T) applicationContext.getBean(name); + } + + public static Map getBeansOfType(Class tClass) { + assertContextInjected(); + return applicationContext.getBeansOfType(tClass); + } + + /** + * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. + */ + public static T getBean(Class requiredType) { + assertContextInjected(); + return applicationContext.getBean(requiredType); + } + + /** + * 获取SpringBoot 配置信息 + * + * @param property 属性key + * @param defaultValue 默认值 + * @param requiredType 返回类型 + * @return / + */ + public static T getProperties(String property, T defaultValue, Class requiredType) { + T result = defaultValue; + try { + result = getBean(Environment.class).getProperty(property, requiredType); + } catch (Exception ignored) {} + return result; + } + + /** + * 获取SpringBoot 配置信息 + * + * @param property 属性key + * @return / + */ + public static String getProperties(String property) { + return getProperties(property, null, String.class); + } + + /** + * 获取SpringBoot 配置信息 + * + * @param property 属性key + * @param requiredType 返回类型 + * @return / + */ + public static T getProperties(String property, Class requiredType) { + return getProperties(property, null, requiredType); + } + + /** + * 检查ApplicationContext不为空. + */ + private static void assertContextInjected() { + if (applicationContext == null) { + throw new IllegalStateException("applicaitonContext属性未注入, 请在applicationContext" + + ".xml中定义SpringContextHolder或在SpringBoot启动类中注册SpringContextHolder."); + } + } + + /** + * 清除SpringContextHolder中的ApplicationContext为Null. + */ + private static void clearHolder() { + log.debug("清除SpringContextHolder中的ApplicationContext:" + + applicationContext); + applicationContext = null; + } + + @Override + public void destroy() { + SpringContextHolder.clearHolder(); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + if (SpringContextHolder.applicationContext != null) { + log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext); + } + SpringContextHolder.applicationContext = applicationContext; + if (addCallback) { + for (CallBack callBack : SpringContextHolder.CALL_BACKS) { + callBack.executor(); + } + CALL_BACKS.clear(); + } + SpringContextHolder.addCallback = false; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/StringUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/StringUtil.java new file mode 100644 index 0000000..c2c474d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/StringUtil.java @@ -0,0 +1,200 @@ +package me.zhengjie.utils; + + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; + +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.util.Calendar; +import java.util.LinkedList; +import java.util.List; +/** + *

+ * 驼峰与下划线的属性名互相转换 + *

+ * + * @Author xx + * @Date 2021/7/20 + **/ +public class StringUtil { + + /** + * 先按英文逗号打散成字符串数组,在随机从中选择一个返回 + * @author: zeng + */ + public static String spiltAndRandom(String str){ + if (ObjectUtil.isEmpty(str)) { + return null; + } + String[] split = str.split(","); + + int randomNum = (int) (Math.random() * split.length); + return split[randomNum]; + } + + /** + * 验证4段ip地址是否符合规范,并且开始的ip不能大于结束的ip + * + * @return + */ + public static boolean verifyIpAddr(String beginIp, String endIp) { + String[] beginIPsplit = beginIp.split("\\."); + String[] endIPsplit = endIp.split("\\."); + if (beginIPsplit.length == 4 && endIPsplit.length == 4) { + for (int i = 0; i < 4; i++) { + if (Convert.toInt(beginIPsplit[i]) < 0 || Convert.toInt(beginIPsplit[i]) > 255) { + return false; + } + if (Convert.toInt(endIPsplit[i]) < 0 || Convert.toInt(endIPsplit[i]) > 255) { + return false; + } +// if (Convert.toInt(beginIPsplit[i]) > Convert.toInt(endIPsplit[i])) { +// return false; +// } + } + return true; + } + return false; + } + + /** + * 转换为下划线 + * + * @param camelCaseName + * @return + */ + public static String underscoreName(String camelCaseName) { + StringBuilder result = new StringBuilder(); + if (camelCaseName != null && camelCaseName.length() > 0) { + result.append(camelCaseName.substring(0, 1).toLowerCase()); + for (int i = 1; i < camelCaseName.length(); i++) { + char ch = camelCaseName.charAt(i); + if (Character.isUpperCase(ch)) { + result.append("_"); + result.append(Character.toLowerCase(ch)); + } else { + result.append(ch); + } + } + } + return result.toString(); + } + + /** + * 转换为驼峰 + * + * @param underscoreName + * @return + */ + public static String camelCaseName(String underscoreName) { + StringBuilder result = new StringBuilder(); + if (underscoreName != null && underscoreName.length() > 0) { + boolean flag = false; + for (int i = 0; i < underscoreName.length(); i++) { + char ch = underscoreName.charAt(i); + if ("_".charAt(0) == ch) { + flag = true; + } else { + if (flag) { + result.append(Character.toUpperCase(ch)); + flag = false; + } else { + result.append(ch); + } + } + } + } + return result.toString(); + } + + public static String getDeviceType(String userAgent) { + if (ObjectUtil.isNotEmpty(userAgent)) { + + userAgent = userAgent.toUpperCase(); + + if (userAgent.contains("WINDOWS")) { + return "WINDOWS"; + } + if (userAgent.contains("IPHONE")) { + return "IOS"; + } + if (userAgent.contains("HUAWEI")) { + return "华为"; + } + if (userAgent.contains("MI")) { + return "小米"; + } + if (userAgent.contains("VIVO")) { + return "VIVO"; + } + if (userAgent.contains("OPPO")) { + return "OPPO"; + } + if (userAgent.contains("MEIZU")) { + return "魅族"; + } + if (userAgent.contains("SM-")) { + return "三星"; + } + if (userAgent.contains("ANDROID")){ + return "安卓"; + } + } + return "未知"; + } + + //设置时间格式 + static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + + /** + * 获取当月第一天 yyyy-MM-dd 格式日期 + * @return + */ + public static String getMonthFirstDay() { + Calendar ca = Calendar.getInstance(); + ca.add(Calendar.MONTH, 0); + ca.set(Calendar.DAY_OF_MONTH, 1); + String firstDay = format.format(ca.getTime()); + return firstDay; + } + /** + * 获取当月最后一天 yyyy-MM-dd 格式日期 + * @return + */ + public static String getMonthLastDay() { + //获得实体类 + Calendar ca = Calendar.getInstance(); + //设置最后一天 + ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH)); + //最后一天格式化 + String lastDay = format.format(ca.getTime()); + return lastDay; + } + + /** + * 获取当月每天的 yyyy-MM-dd 格式日期 + * @return + */ + public static List getMonthAllDay() { + List list = new LinkedList(); + LocalDate monthFirstDay = DateUtil.parseLocalDateFormatyMd(getMonthFirstDay()); + LocalDate monthLastDay = DateUtil.parseLocalDateFormatyMd(getMonthLastDay()); + while (true) { + list.add(monthFirstDay.toString()); + if (monthFirstDay.equals(monthLastDay)) { + return list; + } + monthFirstDay = monthFirstDay.plusDays(1); + } + } + + + public static void main(String[] args) { + // System.out.println(StringUtil.underscoreName("orderNo")); +// getMonthAllDay().forEach(System.out::println); + + String deviceType = getDeviceType("NX629J(Android/11) (com.hj.bybf8) UniApp/0.28.0 1080x2340"); + System.out.println(deviceType); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/StringUtils.java b/wjcy-common/src/main/java/me/zhengjie/utils/StringUtils.java new file mode 100644 index 0000000..b5c2bd6 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/StringUtils.java @@ -0,0 +1,332 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import me.zhengjie.config.SystemConfig; +import nl.basjes.parse.useragent.UserAgent; +import nl.basjes.parse.useragent.UserAgentAnalyzer; +import org.lionsoul.ip2region.DataBlock; +import org.lionsoul.ip2region.DbConfig; +import org.lionsoul.ip2region.DbSearcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.UnknownHostException; +import java.util.Calendar; +import java.util.Date; +import java.util.Enumeration; + +/** + * @author Zheng Jie + * 字符串工具类, 继承org.apache.commons.lang3.StringUtils类 + */ +public class StringUtils extends org.apache.commons.lang3.StringUtils { + + private static final Logger log = LoggerFactory.getLogger(StringUtils.class); + private static boolean ipLocal = false; + private static File file = null; + private static DbConfig config; + private static final char SEPARATOR = '_'; + private static final String UNKNOWN = "unknown"; + + private static final UserAgentAnalyzer userAgentAnalyzer = UserAgentAnalyzer + .newBuilder() + .hideMatcherLoadStats() + .withCache(10000) + .withField(UserAgent.AGENT_NAME_VERSION) + .build(); + + + static { + SpringContextHolder.addCallBacks(() -> { + StringUtils.ipLocal = SpringContextHolder.getProperties("ip.local-parsing", false, Boolean.class); + if (ipLocal) { + /* + * 此文件为独享 ,不必关闭 + */ +// String path = "ip2region/ip2region.db"; +// String name = "ip2region.db"; + try { + config = new DbConfig(); + file = new File(SystemConfig.IP2REGION_DB_PATH); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + }); + } + + /** + * 驼峰命名法工具 + * + * @return toCamelCase(" hello_world ") == "helloWorld" + * toCapitalizeCamelCase("hello_world") == "HelloWorld" + * toUnderScoreCase("helloWorld") = "hello_world" + */ + public static String toCamelCase(String s) { + if (s == null) { + return null; + } + + s = s.toLowerCase(); + + StringBuilder sb = new StringBuilder(s.length()); + boolean upperCase = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + + if (c == SEPARATOR) { + upperCase = true; + } else if (upperCase) { + sb.append(Character.toUpperCase(c)); + upperCase = false; + } else { + sb.append(c); + } + } + + return sb.toString(); + } + + /** + * 驼峰命名法工具 + * + * @return toCamelCase(" hello_world ") == "helloWorld" + * toCapitalizeCamelCase("hello_world") == "HelloWorld" + * toUnderScoreCase("helloWorld") = "hello_world" + */ + public static String toCapitalizeCamelCase(String s) { + if (s == null) { + return null; + } + s = toCamelCase(s); + return s.substring(0, 1).toUpperCase() + s.substring(1); + } + + /** + * 驼峰命名法工具 + * + * @return toCamelCase(" hello_world ") == "helloWorld" + * toCapitalizeCamelCase("hello_world") == "HelloWorld" + * toUnderScoreCase("helloWorld") = "hello_world" + */ + static String toUnderScoreCase(String s) { + if (s == null) { + return null; + } + + StringBuilder sb = new StringBuilder(); + boolean upperCase = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + + boolean nextUpperCase = true; + + if (i < (s.length() - 1)) { + nextUpperCase = Character.isUpperCase(s.charAt(i + 1)); + } + + if ((i > 0) && Character.isUpperCase(c)) { + if (!upperCase || !nextUpperCase) { + sb.append(SEPARATOR); + } + upperCase = true; + } else { + upperCase = false; + } + + sb.append(Character.toLowerCase(c)); + } + + return sb.toString(); + } + + /** + * 获取ip地址 + */ + public static String getIp(HttpServletRequest request) { + String ip = request.getHeader("X-Real-IP"); + if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Forwarded-For"); + } + if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + String comma = ","; + String localhost = "127.0.0.1"; + if (ip.contains(comma)) { + ip = ip.split(",")[0]; + } + if (localhost.equals(ip)) { + // 获取本机真正的ip地址 + try { + ip = InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + log.error(e.getMessage(), e); + } + } + return ip; + } + + /** + * 根据ip获取详细地址 + */ + public static String getCityInfo(String ip) { + if (ipLocal) { + return getLocalCityInfo(ip); + } else { + return getHttpCityInfo(ip); + } + } + + /** + * 根据ip获取详细地址 + */ + public static String getHttpCityInfo(String ip) { + String api = String.format(ElAdminConstant.Url.IP_URL, ip); + JSONObject object = JSONUtil.parseObj(HttpUtil.get(api)); + return object.get("addr", String.class); + } + + /** + * 根据ip获取详细地址 + */ + public static String getLocalCityInfo(String ip) { + try { + DataBlock dataBlock = new DbSearcher(config, file.getPath()) + .binarySearch(ip); + String region = dataBlock.getRegion(); + String address = region.replace("0|", ""); + char symbol = '|'; + if (address.charAt(address.length() - 1) == symbol) { + address = address.substring(0, address.length() - 1); + } + return address.equals(ElAdminConstant.REGION) ? "内网IP" : address; + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return ""; + } + + public static String getBrowser(HttpServletRequest request) { + UserAgent.ImmutableUserAgent userAgent = userAgentAnalyzer.parse(request.getHeader("User-Agent")); + return userAgent.get(UserAgent.AGENT_NAME_VERSION).getValue(); + } + + /** + * 获得当天是周几 + */ + public static String getWeekDay() { + String[] weekDays = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date()); + + int w = cal.get(Calendar.DAY_OF_WEEK) - 1; + if (w < 0) { + w = 0; + } + return weekDays[w]; + } + + /** + * 获取当前机器的IP + * + * @return / + */ + public static String getLocalIp() { + try { + InetAddress candidateAddress = null; + // 遍历所有的网络接口 + for (Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements();) { + NetworkInterface anInterface = interfaces.nextElement(); + // 在所有的接口下再遍历IP + for (Enumeration inetAddresses = anInterface.getInetAddresses(); inetAddresses.hasMoreElements();) { + InetAddress inetAddr = inetAddresses.nextElement(); + // 排除loopback类型地址 + if (!inetAddr.isLoopbackAddress()) { + if (inetAddr.isSiteLocalAddress()) { + // 如果是site-local地址,就是它了 + return inetAddr.getHostAddress(); + } else if (candidateAddress == null) { + // site-local类型的地址未被发现,先记录候选地址 + candidateAddress = inetAddr; + } + } + } + } + if (candidateAddress != null) { + return candidateAddress.getHostAddress(); + } + // 如果没有发现 non-loopback地址.只能用最次选的方案 + InetAddress jdkSuppliedAddress = InetAddress.getLocalHost(); + if (jdkSuppliedAddress == null) { + return ""; + } + return jdkSuppliedAddress.getHostAddress(); + } catch (Exception e) { + return ""; + } + } + + public static String append(String str, char appendValue, int count) { + + StringBuilder stringBuilder = new StringBuilder(str); + for (int i = 0; i < count; i++) { + stringBuilder.append(appendValue); + } + + return stringBuilder.toString(); + } + + + /** + * 首字母大写 + * + * @param string + * @return + */ + public static String toUpperCase4Index(String string) { + char[] methodName = string.toCharArray(); + methodName[0] = toUpperCase(methodName[0]); + return String.valueOf(methodName); + } + + /** + * 字符转成大写 + * + * @param chars + * @return + */ + public static char toUpperCase(char chars) { + if (97 <= chars && chars <= 122) { + chars ^= 32; + } + return chars; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/ThrowableUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/ThrowableUtil.java new file mode 100644 index 0000000..075a65c --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/ThrowableUtil.java @@ -0,0 +1,37 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * 异常工具 2019-01-06 + * @author Zheng Jie + */ +public class ThrowableUtil { + + /** + * 获取堆栈信息 + */ + public static String getStackTrace(Throwable throwable){ + StringWriter sw = new StringWriter(); + try (PrintWriter pw = new PrintWriter(sw)) { + throwable.printStackTrace(pw); + return sw.toString(); + } + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/TransformMap.java b/wjcy-common/src/main/java/me/zhengjie/utils/TransformMap.java new file mode 100644 index 0000000..c5aa2be --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/TransformMap.java @@ -0,0 +1,60 @@ +package me.zhengjie.utils; + + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; + +import java.util.Collections; +import java.util.Map; +/** + *

+ * DTO 转为 map集合,并过滤时间 + *

+ * + * @Author xx + * @Date 2021/7/22 + **/ +public class TransformMap { + + public static Map toMap(Object dto) { + if (dto == null) { + return Collections.emptyMap(); + } + Object obj = EmptyAttributeFiler.emptyAttributeFiler(dto); + Map map = BeanUtil.beanToMap(obj); + if (obj instanceof Map) { + map = (Map)obj; + } + String stime = Convert.toStr(map.get("stime")); + String etime = Convert.toStr(map.get("etime")); + if (ObjectUtil.isAllNotEmpty(stime,etime) && (stime.length()== etime.length() && stime.length()==10)) { + map.put("stime", map.get("stime").toString() + " 00:00:00"); + map.put("etime", map.get("etime").toString() + " 23:59:59"); + } + Integer page = Convert.toInt(map.get("page")); + Integer pageSize = Convert.toInt(map.get("pageSize")); + if (ObjectUtil.isNotNull(page) && ObjectUtil.isNotNull(pageSize)) { + if (page < 1) { + page = 1; + } + if (pageSize < 1) { + pageSize = 10; + map.put("pageSize", 10); + } + map.put("page", (page - 1) * pageSize); + } + Double minPrice =Convert.toDouble(map.get("minPrice")); + if(ObjectUtil.isNotNull(minPrice)){ + map.put("minPrice",minPrice*100); + } + + Double maxPrice =Convert.toDouble(map.get("maxPrice")); + if(ObjectUtil.isNotNull(maxPrice)){ + map.put("maxPrice",maxPrice*100); + } + return map; + } + + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/TransformQueryWrapper.java b/wjcy-common/src/main/java/me/zhengjie/utils/TransformQueryWrapper.java new file mode 100644 index 0000000..f796fd0 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/TransformQueryWrapper.java @@ -0,0 +1,165 @@ +package me.zhengjie.utils; + + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import me.zhengjie.entity.QueryWrapperAndPage; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Date; +import java.util.Map; +/** + *

+ * DTO 转为 QueryWrapper,并过滤时间 + *

+ * + * @Author xx + * @Date 2021/7/20 + **/ +public class TransformQueryWrapper { + + /** + * DTO 转QueryWrapperAndPage + * 时间特殊处理 其他都是等于 + * 参数对象 属性命名 保持与书库驼峰对应 + * @param dto + * @return + */ + public QueryWrapperAndPage dtoToQueryWrapper(Object dto) { + QueryWrapperAndPage queryWrapperAndPage = new QueryWrapperAndPage(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + Page page = new Page<>(1,10); + Map dtoMap = BeanUtil.beanToMap(dto); + if (ObjectUtil.isNotNull(dtoMap.get("stime"))) { + queryWrapper.ge("created_at", dtoMap.get("stime").toString() + " 00:00:00"); + dtoMap.remove("stime"); + } + + if (ObjectUtil.isNotNull(dtoMap.get("etime"))) { + queryWrapper.le("created_at", dtoMap.get("etime").toString() + " 23:59:59"); + dtoMap.remove("etime"); + } + if (ObjectUtil.isNotNull(dtoMap.get("guessStime"))) { + queryWrapper.ge("completion_time", dtoMap.get("guessStime").toString() + " 00:00:00"); + dtoMap.remove("guessStime"); + } + + if (ObjectUtil.isNotNull(dtoMap.get("guessEtime"))) { + queryWrapper.le("completion_time", dtoMap.get("guessEtime").toString() + " 23:59:59"); + dtoMap.remove("guessEtime"); + } + if (ObjectUtil.isNotNull(dtoMap.get("gamestime"))) { + queryWrapper.ge("start_time", dtoMap.get("gamestime").toString() + " 00:00:00"); + dtoMap.remove("gamestime"); + } + + if (ObjectUtil.isNotNull(dtoMap.get("gameetime"))) { + queryWrapper.le("start_time", dtoMap.get("gameetime").toString() + " 23:59:59"); + dtoMap.remove("gameetime"); + } + + if (ObjectUtil.isNotNull(dtoMap.get("releaseStime"))) { + queryWrapper.ge("release_time", dtoMap.get("releaseStime").toString() + " 00:00:00"); + dtoMap.remove("releaseStime"); + } + + if (ObjectUtil.isNotNull(dtoMap.get("releaseEtime"))) { + queryWrapper.le("release_time", dtoMap.get("releaseEtime").toString() + " 23:59:59"); + dtoMap.remove("releaseEtime"); + } + // 封装所有分页信息 + if (ObjectUtil.isNotEmpty(dtoMap.get("page")) && ObjectUtil.isNotEmpty(dtoMap.get("pageSize"))) { + page.setCurrent(Long.valueOf(dtoMap.get("page").toString())); + page.setSize(Long.valueOf(dtoMap.get("pageSize").toString())); + queryWrapperAndPage.setPage(page); + dtoMap.remove("page"); + dtoMap.remove("pageSize"); + } + + // 封装所有查询条件信息 + for (Map.Entry map :dtoMap.entrySet()) { + if (ObjectUtil.isNotEmpty(map.getValue())){ + queryWrapper.eq(StringUtil.underscoreName(map.getKey()), map.getValue()); + } + } + + queryWrapperAndPage.setQueryWrapper(queryWrapper); + + return queryWrapperAndPage; + } + + /** + * 目前都是等值赋值。 需要的话在后续拓展 + * @param model + * @return + */ + public static QueryWrapper toQueryWrapper(Object model) { + + QueryWrapper queryWrapper = new QueryWrapper<>(); + + // 通过反射 赋值 + Field[] field = model.getClass().getDeclaredFields(); + try { + // 遍历所有属性 + for (int j = 0; j < field.length; j++) { + // 获取属性的名字 + String name = field[j].getName(); + // 将属性的首字符大写,方便构造get,set方法 + name = name.substring(0, 1).toUpperCase() + name.substring(1); + // 获取属性的类型 + String type = field[j].getGenericType().toString(); + // 如果type是类类型,则前面包含"class ",后面跟类名 + if ("class java.lang.String".equals(type)) { + Method m = model.getClass().getMethod("get" + name); + // 调用getter方法获取属性值 + String value = (String) m.invoke(model); + if (ObjectUtil.isNotEmpty(value)) { + queryWrapper.eq(name, value); + } + } + if ("class java.lang.Integer".equals(type)) { + Method m = model.getClass().getMethod("get" + name); + Integer value = (Integer) m.invoke(model); + + if (ObjectUtil.isNotEmpty(value)){ + queryWrapper.eq(name, value); + } + } + if ("class java.lang.Boolean".equals(type)) { + Method m = model.getClass().getMethod("get" + name); + Boolean value = (Boolean) m.invoke(model); + + if (ObjectUtil.isNotEmpty(value)){ + queryWrapper.eq(name, value); + } + } + if ("class java.util.Date".equals(type)) { + Method m = model.getClass().getMethod("get" + name); + Date value = (Date) m.invoke(model); + + if (ObjectUtil.isNotEmpty(value)){ + queryWrapper.eq(name, value); + } + } + + // 如果有需要,可以仿照上面继续进行扩充,再增加对其它类型的判断 + } + }catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + + return queryWrapper; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/TranslatorUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/TranslatorUtil.java new file mode 100644 index 0000000..f2bd5d2 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/TranslatorUtil.java @@ -0,0 +1,66 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import cn.hutool.json.JSONArray; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; + +/** + * @author Zheng Jie + * 翻译工具类 + */ +public class TranslatorUtil { + + public static String translate(String word){ + try { + String url = "https://translate.googleapis.com/translate_a/single?" + + "client=gtx&" + + "sl=en" + + "&tl=zh-CN" + + "&dt=t&q=" + URLEncoder.encode(word, "UTF-8"); + + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + con.setRequestProperty("User-Agent", "Mozilla/5.0"); + + BufferedReader in = new BufferedReader( + new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuilder response = new StringBuilder(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + return parseResult(response.toString()); + }catch (Exception e){ + return word; + } + } + + private static String parseResult(String inputJson){ + JSONArray jsonArray2 = (JSONArray) new JSONArray(inputJson).get(0); + StringBuilder result = new StringBuilder(); + for (Object o : jsonArray2) { + result.append(((JSONArray) o).get(0).toString()); + } + return result.toString(); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/ValidationUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/ValidationUtil.java new file mode 100644 index 0000000..c2c81d2 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/ValidationUtil.java @@ -0,0 +1,126 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.exception.BadRequestException; +import org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator; + +import java.lang.reflect.Field; + +/** + * 验证工具 + * @author Zheng Jie + * @date 2018-11-23 + */ +@Slf4j +public class ValidationUtil{ + + /** + * 验证空 + */ + public static void isNull(Object obj, String entity, String parameter , Object value){ + if(ObjectUtil.isNull(obj)){ + String msg = entity + " 不存在: "+ parameter +" is "+ value; + throw new BadRequestException(msg); + } + } + + /** + * 验证是否为邮箱 + */ + public static boolean isEmail(String email) { + return new EmailValidator().isValid(email, null); + } + + + /** + * 反射检验对象是否包含指定名称的 变量 + * @param fieldName + * @param obj + * @return + */ + public static Boolean isExistFieldName(String fieldName, Object obj) { + if (obj == null || StringUtils.isEmpty(fieldName)) { + return false; + } + //获取这个类的所有属性 + Field[] fields = obj.getClass().getDeclaredFields(); + //循环遍历所有的fields + for (int i = 0; i < fields.length; i++) { + if (fields[i].getName().equals(fieldName)) { + return true; + } + } + return false; + } + +// /** +// * 判断是否包含 passType +// * @param mqSettlePassCurrencyTypeList +// * @param passType +// * @return +// */ +// public static Boolean isContainPassType(List mqSettlePassCurrencyTypeList, Integer passType) { +// if (ObjectUtil.isEmpty(mqSettlePassCurrencyTypeList) || ObjectUtil.isEmpty(passType)) { +// log.error("---isContainPassType------mqSettlePassCurrencyTypeList-------null"); +// return false; +// } +// List list = mqSettlePassCurrencyTypeList.stream().filter(l->l.getPassType().equals(passType)).collect(Collectors.toList()); +// if (ObjectUtil.isNotEmpty(list)) { +// return true; +// } +// +// log.error("---isContainPassType------mqSettlePassCurrencyTypeList----return---null"); +// return false; +// } +// +// /** +// * 判断是否包含 passType 中的currencyType +// * @param mqSettlePassCurrencyTypeList +// * @param passType +// * @param currencyType +// * @return +// */ +// public static Boolean isContainPassCurrencyType(List mqSettlePassCurrencyTypeList, Integer passType, Integer currencyType) { +// if (ObjectUtil.isEmpty(mqSettlePassCurrencyTypeList) || ObjectUtil.isEmpty(passType) || ObjectUtil.isEmpty(currencyType)) { +// log.error("---isContainPassCurrencyType------mqSettlePassCurrencyTypeList-------null"); +// return false; +// } +// +// List list = mqSettlePassCurrencyTypeList.stream().filter(l->l.getPassType().equals(passType)).collect(Collectors.toList()); +// if (ObjectUtil.isEmpty(list)) { +// log.error("---isContainPassCurrencyType------List----return---false"); +// return false; +// } +// +// for (MqSettlePassCurrencyType mqSettlePassCurrencyType:list) { +// List currencyTypeList = mqSettlePassCurrencyType.getCurrencyList(); +// if (ObjectUtil.isEmpty(currencyTypeList)) { +// continue; +// } +// +// List currencyList = currencyTypeList.stream().filter(c->c.getCurrencyType().equals(currencyType)).collect(Collectors.toList()); +// if (ObjectUtil.isNotEmpty(currencyList)) { +// return true; +// } +// } +// +// log.error("---isContainPassCurrencyType------mqSettlePassCurrencyTypeList----return---false"); +// return false; +// } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/YdCallBackUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/YdCallBackUtil.java new file mode 100644 index 0000000..6a6b29f --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/YdCallBackUtil.java @@ -0,0 +1,89 @@ +package me.zhengjie.utils; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.config.BeanFactory; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtApply; +import me.zhengjie.entity.CtRebot; +import me.zhengjie.entity.ReturnObje; +import me.zhengjie.entity.YdSign; +import me.zhengjie.enums.YesOrNoEnum; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.service.CtRebotService; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +/** + * 影刀回调 + * + * @author rch + * @create 2022-08-23 + */ +@Slf4j +public class YdCallBackUtil { + + @Transactional(rollbackFor = Exception.class) + public Dto callback(HttpServletRequest httpServletRequest, CtApply ctApply, String data){ + log.info("=======影刀回调=======callback"); + String requestUrl = httpServletRequest.getRequestURI(); + Map map = httpServletRequest.getParameterMap(); + if (ObjectUtil.isEmpty(map.get("sign"))) { + return Dto.getInstance(ErrorCodeEnum.ERROR_PARAM_NULL); + } + + String getSign = map.get("sign")[0]; + JSONObject jsonObject = JSONUtil.parseObj(data); + + // 根据task枚举获取 应用信息 取出 accessKey 和 accessKeySecret 用于鉴权 + if (ObjectUtil.isEmpty(ctApply) || ObjectUtil.isEmpty(getSign) + || ObjectUtil.isEmpty(jsonObject) + || ObjectUtil.isEmpty(ctApply.getAccessKeyId()) + || ObjectUtil.isEmpty(ctApply.getAccessKeySecret())) { + return Dto.getInstance(ErrorCodeEnum.ERROR_PARAM_NULL); + } + + String accessKeyId = ctApply.getAccessKeyId(); + String accessKeySecret = ctApply.getAccessKeySecret(); + + // 鉴权 + YdSign ydSign = new YdSign(); + ydSign.setTimestamp(Long.valueOf(map.get("timestamp")[0])); + ydSign.setAccessKeyId(accessKeyId); + ydSign.setAccessKeySecret(accessKeySecret); + ydSign.setBodyMd5(map.get("bodyMd5")[0]); + + log.info("-------map:{}" , JSONUtil.toJsonStr(map)); + log.info("====ydSign====={}", JSONUtil.toJsonStr(ydSign)); + String sign = YdSignUtil.getSign(ydSign); + log.info("====sign:{} ---getSign:{}", sign, getSign); + if (ObjectUtil.isEmpty(sign) || !getSign.equals(sign)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_CALLBACK_SIGN_NULL); + } + + // TODO 获取设备id 然后修改设备状态是未占用 + CtRebotService ctRebotService = BeanFactory.getBean(CtRebotService.class); + ReturnObje returnObje = JSONUtil.toBean(data, ReturnObje.class); + String rebotClientName = returnObje.getRobotClientName(); + CtRebot ctRebot = ctRebotService.getByAccountNameLock(rebotClientName); + if (ObjectUtil.isEmpty(ctRebot)) { + // 有问题 不执行 + System.out.println("===========设备有问题==========="); + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_OR_OCCUPY); + } + if (YesOrNoEnum.NO.eqValue(ctRebot.getStatus())) { + return Dto.returnResult(true); + } + + // 修改机器人状态 不管是什么状态,执行完成之后在我们平台就是修改为 待占用即可 + CtRebot updateCtRebot = new CtRebot(); + updateCtRebot.setId(ctRebot.getId()); + updateCtRebot.setStatus(YesOrNoEnum.NO.value()); + Boolean resultBoolean = ctRebotService.updateById(updateCtRebot); + return Dto.returnResult(resultBoolean); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/YdParamsCheck.java b/wjcy-common/src/main/java/me/zhengjie/utils/YdParamsCheck.java new file mode 100644 index 0000000..b69eea3 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/YdParamsCheck.java @@ -0,0 +1,54 @@ +package me.zhengjie.utils; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import me.zhengjie.entity.quartz.Boss; +import me.zhengjie.entity.quartz.Param; + +import java.util.List; + +/** + * 检验影刀参数是否是json数组格式 + * + * @author rch + * @create 2022-08-17 + */ +public class YdParamsCheck { + + /** + * params 是json格式则返回true 否则返回false + * @param str + * @return + */ + public static Boolean paramIsJson(String str) { + + if (ObjectUtil.isEmpty(str)) { + return false; + } + + if (!JSONUtil.isJson(str)) { + return false; + } + + Boss boss = JSONUtil.toBean(str, Boss.class); + if (ObjectUtil.isEmpty(boss) || ObjectUtil.isEmpty(boss.getParams())) { + return false; + } + + List paramList = boss.getParams(); + for (Param param:paramList) { + if (ObjectUtil.isEmpty(param)) { + return false; + } + } + + return true; + } + + public static void main(String[] args) { + String str = "{\"accountName\":\"linbiaoyuan@vogocm\",\"applyId\":2,\"params\":1}"; + str = "{\"accountName\":\"linbiaoyuan@vogocm\",\"applyId\":2,\"params\":[{\"name\":\"id\",\"value\":\"1\",\"type\":\"str\"}]}"; + Boolean boolean1 = paramIsJson(str); + System.out.println("==========boolean1:" + boolean1); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/YdSignUtil.java b/wjcy-common/src/main/java/me/zhengjie/utils/YdSignUtil.java new file mode 100644 index 0000000..7acc18d --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/YdSignUtil.java @@ -0,0 +1,94 @@ +package me.zhengjie.utils; + +import cn.hutool.core.util.ObjectUtil; +import me.zhengjie.entity.YdSign; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.Charset; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.Date; + +/** + * 影刀鉴权工具类 + * + * @author rch + * @create 2022-07-26 + */ +public class YdSignUtil { + + private static final char[] DIGITS_LOWER = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};; + + private static final String UTF8_NAME = "UTF-8"; + + private static final Charset UTF8_CHARSET = Charset.forName(UTF8_NAME); + + + public static String getSign(YdSign ydSign) { + String sign = null; + if (ObjectUtil.isEmpty(ydSign) + || ObjectUtil.isEmpty(ydSign.getAccessKeyId()) + || ObjectUtil.isEmpty(ydSign.getTimestamp()) + || ObjectUtil.isEmpty(ydSign.getBodyMd5()) + || ObjectUtil.isEmpty(ydSign.getAccessKeySecret())) { + return sign; + } + + //由回调接口回传 + long timestamp = ydSign.getTimestamp(); + //影刀控制台配置的accessKeyId + String accessKeyId = ydSign.getAccessKeyId(); + //影刀控制台配置的accessKeySecret + String accessKeySecret = ydSign.getAccessKeySecret(); + //由回调接口回传 + String bodyMd5 = ydSign.getBodyMd5(); + DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + Date date = new Date(timestamp); + LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); + + System.out.println(bodyMd5); + StringBuilder sb = new StringBuilder(); + sb.append("accessKeyId="); + sb.append(accessKeyId); + sb.append("&bodyMd5="); + sb.append(bodyMd5); + sb.append("×tamp="); + sb.append(pattern.format(localDateTime)); + + String originalStr = sb.toString(); + byte[] keyBytes = accessKeySecret.getBytes(); + SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "HmacSHA1"); + try { + Mac mac = Mac.getInstance("HmacSHA1"); + mac.init(secretKey); + byte[] rawHmac = mac.doFinal(originalStr.getBytes(UTF8_CHARSET)); + sign = encodeHex(rawHmac); + System.out.println("sign: " + sign); + } catch (Exception e) { + e.printStackTrace(); + return sign; + } + + return sign; + } + + /** + * 转换16进制 + * + * @param data + * @return + */ + private static String encodeHex(byte[] data) { + int l = data.length; + char[] out = new char[l << 1]; + int i = 0; + + for(int var5 = 0; i < l; ++i) { + out[var5++] = DIGITS_LOWER[(240 & data[i]) >>> 4]; + out[var5++] = DIGITS_LOWER[15 & data[i]]; + } + return new String(out); + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/enums/CodeBiEnum.java b/wjcy-common/src/main/java/me/zhengjie/utils/enums/CodeBiEnum.java new file mode 100644 index 0000000..661e0a0 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/enums/CodeBiEnum.java @@ -0,0 +1,50 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + *

+ * 验证码业务场景 + *

+ * @author Zheng Jie + * @date 2020-05-02 + */ +@Getter +@AllArgsConstructor +public enum CodeBiEnum { + + /* 旧邮箱修改邮箱 */ + ONE(1, "旧邮箱修改邮箱"), + + /* 通过邮箱修改密码 */ + TWO(2, "通过邮箱修改密码"); + + private final Integer code; + private final String description; + + public static CodeBiEnum find(Integer code) { + for (CodeBiEnum value : CodeBiEnum.values()) { + if (code.equals(value.getCode())) { + return value; + } + } + return null; + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/enums/CodeEnum.java b/wjcy-common/src/main/java/me/zhengjie/utils/enums/CodeEnum.java new file mode 100644 index 0000000..916862a --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/enums/CodeEnum.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + *

+ * 验证码业务场景对应的 Redis 中的 key + *

+ * @author Zheng Jie + * @date 2020-05-02 + */ +@Getter +@AllArgsConstructor +public enum CodeEnum { + + /* 通过手机号码重置邮箱 */ + PHONE_RESET_EMAIL_CODE("phone_reset_email_code_", "通过手机号码重置邮箱"), + + /* 通过旧邮箱重置邮箱 */ + EMAIL_RESET_EMAIL_CODE("email_reset_email_code_", "通过旧邮箱重置邮箱"), + + /* 通过手机号码重置密码 */ + PHONE_RESET_PWD_CODE("phone_reset_pwd_code_", "通过手机号码重置密码"), + + /* 通过邮箱重置密码 */ + EMAIL_RESET_PWD_CODE("email_reset_pwd_code_", "通过邮箱重置密码"); + + private final String key; + private final String description; +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/enums/DataScopeEnum.java b/wjcy-common/src/main/java/me/zhengjie/utils/enums/DataScopeEnum.java new file mode 100644 index 0000000..5352b7b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/enums/DataScopeEnum.java @@ -0,0 +1,53 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + *

+ * 数据权限枚举 + *

+ * @author Zheng Jie + * @date 2020-05-07 + */ +@Getter +@AllArgsConstructor +public enum DataScopeEnum { + + /* 全部的数据权限 */ + ALL("全部", "全部的数据权限"), + + /* 自己部门的数据权限 */ + THIS_LEVEL("本级", "自己部门的数据权限"), + + /* 自定义的数据权限 */ + CUSTOMIZE("自定义", "自定义的数据权限"); + + private final String value; + private final String description; + + public static DataScopeEnum find(String val) { + for (DataScopeEnum dataScopeEnum : DataScopeEnum.values()) { + if (val.equals(dataScopeEnum.getValue())) { + return dataScopeEnum; + } + } + return null; + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/enums/RequestMethodEnum.java b/wjcy-common/src/main/java/me/zhengjie/utils/enums/RequestMethodEnum.java new file mode 100644 index 0000000..1b65c78 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/enums/RequestMethodEnum.java @@ -0,0 +1,74 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author Zheng Jie + * @website https://el-admin.vip + * @description + * @date 2020-06-10 + **/ +@Getter +@AllArgsConstructor +public enum RequestMethodEnum { + + /** + * 搜寻 @AnonymousGetMapping + */ + GET("GET"), + + /** + * 搜寻 @AnonymousPostMapping + */ + POST("POST"), + + /** + * 搜寻 @AnonymousPutMapping + */ + PUT("PUT"), + + /** + * 搜寻 @AnonymousPatchMapping + */ + PATCH("PATCH"), + + /** + * 搜寻 @AnonymousDeleteMapping + */ + DELETE("DELETE"), + + /** + * 否则就是所有 Request 接口都放行 + */ + ALL("All"); + + /** + * Request 类型 + */ + private final String type; + + public static RequestMethodEnum find(String type) { + for (RequestMethodEnum value : RequestMethodEnum.values()) { + if (type.equals(value.getType())) { + return value; + } + } + return ALL; + } +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/excel/ExcelClassField.java b/wjcy-common/src/main/java/me/zhengjie/utils/excel/ExcelClassField.java new file mode 100644 index 0000000..2107f6e --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/excel/ExcelClassField.java @@ -0,0 +1,79 @@ +package me.zhengjie.utils.excel; + +import java.util.LinkedHashMap; + +/** + * ExcelClassField + * + * @author rch + * @create 2022-06-22 + */ +public class ExcelClassField { + + /** 字段名称 */ + private String fieldName; + + /** 表头名称 */ + private String name; + + /** 映射关系 */ + private LinkedHashMap kvMap; + + /** 示例值 */ + private Object example; + + /** 排序 */ + private int sort; + + /** 是否为注解字段:0-否,1-是 */ + private int hasAnnotation; + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public LinkedHashMap getKvMap() { + return kvMap; + } + + public void setKvMap(LinkedHashMap kvMap) { + this.kvMap = kvMap; + } + + public Object getExample() { + return example; + } + + public void setExample(Object example) { + this.example = example; + } + + public int getSort() { + return sort; + } + + public void setSort(int sort) { + this.sort = sort; + } + + public int getHasAnnotation() { + return hasAnnotation; + } + + public void setHasAnnotation(int hasAnnotation) { + this.hasAnnotation = hasAnnotation; + } + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/excel/ExcelExport.java b/wjcy-common/src/main/java/me/zhengjie/utils/excel/ExcelExport.java new file mode 100644 index 0000000..706d95b --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/excel/ExcelExport.java @@ -0,0 +1,30 @@ +package me.zhengjie.utils.excel; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ExcelExport + * + * @author rch + * @create 2022-06-22 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface ExcelExport { + + /** 字段名称 */ + String value(); + + /** 导出排序先后: 数字越小越靠前(默认按Java类字段顺序导出) */ + int sort() default 0; + + /** 导出映射,格式如:0-未知;1-男;2-女 */ + String kv() default ""; + + /** 导出模板示例值(有值的话,直接取该值,不做映射) */ + String example() default ""; + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/excel/ExcelImport.java b/wjcy-common/src/main/java/me/zhengjie/utils/excel/ExcelImport.java new file mode 100644 index 0000000..5110dad --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/excel/ExcelImport.java @@ -0,0 +1,34 @@ +package me.zhengjie.utils.excel; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ExcelImport + * + * @author rch + * @create 2022-06-22 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface ExcelImport { + + /** 字段名称 */ + String value(); + + /** 导出映射,格式如:0-未知;1-男;2-女 */ + String kv() default ""; + + /** 是否为必填字段(默认为非必填) */ + boolean required() default false; + + /** 最大长度(默认255) */ + int maxLength() default 255; + + /** 导入唯一性验证(多个字段则取联合验证) */ + boolean unique() default false; + +} diff --git a/wjcy-common/src/main/java/me/zhengjie/utils/excel/ExcelUtils.java b/wjcy-common/src/main/java/me/zhengjie/utils/excel/ExcelUtils.java new file mode 100644 index 0000000..59b1998 --- /dev/null +++ b/wjcy-common/src/main/java/me/zhengjie/utils/excel/ExcelUtils.java @@ -0,0 +1,993 @@ +package me.zhengjie.utils.excel; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import org.apache.poi.hssf.usermodel.HSSFDataValidation; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.net.URL; +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.Map.Entry; +import java.util.regex.Pattern; + +/** + * Excel导入导出工具类 + * + * @author rch + * @create 2022-06-22 + */ +public class ExcelUtils { + private static final String XLSX = ".xlsx"; + private static final String XLS = ".xls"; + public static final String ROW_MERGE = "row_merge"; + public static final String COLUMN_MERGE = "column_merge"; + private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + private static final String ROW_NUM = "rowNum"; + private static final String ROW_DATA = "rowData"; + private static final String ROW_TIPS = "rowTips"; + private static final int CELL_OTHER = 0; + private static final int CELL_ROW_MERGE = 1; + private static final int CELL_COLUMN_MERGE = 2; + private static final int IMG_HEIGHT = 30; + private static final int IMG_WIDTH = 30; + private static final char LEAN_LINE = '/'; + private static final int BYTES_DEFAULT_LENGTH = 10240; + private static final NumberFormat NUMBER_FORMAT = NumberFormat.getNumberInstance(); + + + public static List readFile(File file, Class clazz) throws Exception { + JSONArray array = readFile(file); + return getBeanList(array, clazz); + } + + public static List readMultipartFile(MultipartFile mFile, Class clazz) throws Exception { + JSONArray array = readMultipartFile(mFile); + return getBeanList(array, clazz); + } + + public static JSONArray readFile(File file) throws Exception { + return readExcel(null, file); + } + + public static JSONArray readMultipartFile(MultipartFile mFile) throws Exception { + return readExcel(mFile, null); + } + + public static Map readFileManySheet(File file) throws Exception { + return readExcelManySheet(null, file); + } + + public static Map readFileManySheet(MultipartFile file) throws Exception { + return readExcelManySheet(file, null); + } + + private static List getBeanList(JSONArray array, Class clazz) throws Exception { + List list = new ArrayList<>(); + Map uniqueMap = new HashMap<>(16); + for (int i = 0; i < array.size(); i++) { + list.add(getBean(clazz, array.getJSONObject(i), uniqueMap)); + } + return list; + } + + /** + * 获取每个对象的数据 + */ + private static T getBean(Class c, JSONObject obj, Map uniqueMap) throws Exception { + T t = c.newInstance(); + Field[] fields = c.getDeclaredFields(); + List errMsgList = new ArrayList<>(); + boolean hasRowTipsField = false; + StringBuilder uniqueBuilder = new StringBuilder(); + int rowNum = 0; + for (Field field : fields) { + // 行号 + if (field.getName().equals(ROW_NUM)) { + rowNum = obj.getInteger(ROW_NUM); + field.setAccessible(true); + field.set(t, rowNum); + continue; + } + // 是否需要设置异常信息 + if (field.getName().equals(ROW_TIPS)) { + hasRowTipsField = true; + continue; + } + // 原始数据 + if (field.getName().equals(ROW_DATA)) { + field.setAccessible(true); + field.set(t, obj.toString()); + continue; + } + // 设置对应属性值 + setFieldValue(t, field, obj, uniqueBuilder, errMsgList); + } + // 数据唯一性校验 + if (uniqueBuilder.length() > 0) { + if (uniqueMap.containsValue(uniqueBuilder.toString())) { + Set rowNumKeys = uniqueMap.keySet(); + for (Integer num : rowNumKeys) { + if (uniqueMap.get(num).equals(uniqueBuilder.toString())) { + errMsgList.add(String.format("数据唯一性校验失败,(%s)与第%s行重复)", uniqueBuilder, num)); + } + } + } else { + uniqueMap.put(rowNum, uniqueBuilder.toString()); + } + } + // 失败处理 + if (errMsgList.isEmpty() && !hasRowTipsField) { + return t; + } + StringBuilder sb = new StringBuilder(); + int size = errMsgList.size(); + for (int i = 0; i < size; i++) { + if (i == size - 1) { + sb.append(errMsgList.get(i)); + } else { + sb.append(errMsgList.get(i)).append(";"); + } + } + // 设置错误信息 + for (Field field : fields) { + if (field.getName().equals(ROW_TIPS)) { + field.setAccessible(true); + field.set(t, sb.toString()); + } + } + return t; + } + + private static void setFieldValue(T t, Field field, JSONObject obj, StringBuilder uniqueBuilder, List errMsgList) { + // 获取 ExcelImport 注解属性 + ExcelImport annotation = field.getAnnotation(ExcelImport.class); + if (annotation == null) { + return; + } + String cname = annotation.value(); + if (cname.trim().length() == 0) { + return; + } + // 获取具体值 + String val = null; + if (obj.containsKey(cname)) { + val = getString(obj.getString(cname)); + } + if (val == null) { + return; + } + field.setAccessible(true); + // 判断是否必填 + boolean require = annotation.required(); + if (require && val.isEmpty()) { + errMsgList.add(String.format("[%s]不能为空", cname)); + return; + } + // 数据唯一性获取 + boolean unique = annotation.unique(); + if (unique) { + if (uniqueBuilder.length() > 0) { + uniqueBuilder.append("--").append(val); + } else { + uniqueBuilder.append(val); + } + } + // 判断是否超过最大长度 + int maxLength = annotation.maxLength(); + if (maxLength > 0 && val.length() > maxLength) { + errMsgList.add(String.format("[%s]长度不能超过%s个字符(当前%s个字符)", cname, maxLength, val.length())); + } + // 判断当前属性是否有映射关系 + LinkedHashMap kvMap = getKvMap(annotation.kv()); + if (!kvMap.isEmpty()) { + boolean isMatch = false; + for (String key : kvMap.keySet()) { + if (kvMap.get(key).equals(val)) { + val = key; + isMatch = true; + break; + } + } + if (!isMatch) { + errMsgList.add(String.format("[%s]的值不正确(当前值为%s)", cname, val)); + return; + } + } + // 其余情况根据类型赋值 + String fieldClassName = field.getType().getSimpleName(); + try { + if ("String".equalsIgnoreCase(fieldClassName)) { + field.set(t, val); + } else if ("boolean".equalsIgnoreCase(fieldClassName)) { + field.set(t, Boolean.valueOf(val)); + } else if ("int".equalsIgnoreCase(fieldClassName) || "Integer".equals(fieldClassName)) { + try { + field.set(t, Integer.valueOf(val)); + } catch (NumberFormatException e) { + errMsgList.add(String.format("[%s]的值格式不正确(当前值为%s)", cname, val)); + } + } else if ("double".equalsIgnoreCase(fieldClassName)) { + field.set(t, Double.valueOf(val)); + } else if ("long".equalsIgnoreCase(fieldClassName)) { + field.set(t, Long.valueOf(val)); + } else if ("BigDecimal".equalsIgnoreCase(fieldClassName)) { + field.set(t, new BigDecimal(val)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static Map readExcelManySheet(MultipartFile mFile, File file) throws IOException { + Workbook book = getWorkbook(mFile, file); + if (book == null) { + return Collections.emptyMap(); + } + Map map = new LinkedHashMap<>(); + for (int i = 0; i < book.getNumberOfSheets(); i++) { + Sheet sheet = book.getSheetAt(i); + JSONArray arr = readSheet(sheet); + map.put(sheet.getSheetName(), arr); + } + book.close(); + return map; + } + + private static JSONArray readExcel(MultipartFile mFile, File file) throws IOException { + Workbook book = getWorkbook(mFile, file); + if (book == null) { + return new JSONArray(); + } + JSONArray array = readSheet(book.getSheetAt(0)); + book.close(); + return array; + } + + private static Workbook getWorkbook(MultipartFile mFile, File file) throws IOException { + boolean fileNotExist = (file == null || !file.exists()); + if (mFile == null && fileNotExist) { + return null; + } + // 解析表格数据 + InputStream in; + String fileName; + if (mFile != null) { + // 上传文件解析 + in = mFile.getInputStream(); + fileName = getString(mFile.getOriginalFilename()).toLowerCase(); + } else { + // 本地文件解析 + in = new FileInputStream(file); + fileName = file.getName().toLowerCase(); + } + Workbook book; + if (fileName.endsWith(XLSX)) { + book = new XSSFWorkbook(in); + } else if (fileName.endsWith(XLS)) { + POIFSFileSystem poifsFileSystem = new POIFSFileSystem(in); + book = new HSSFWorkbook(poifsFileSystem); + } else { + return null; + } + in.close(); + return book; + } + + private static JSONArray readSheet(Sheet sheet) { + // 首行下标 + int rowStart = sheet.getFirstRowNum(); + // 尾行下标 + int rowEnd = sheet.getLastRowNum(); + // 获取表头行 + Row headRow = sheet.getRow(rowStart); + if (headRow == null) { + return new JSONArray(); + } + int cellStart = headRow.getFirstCellNum(); + int cellEnd = headRow.getLastCellNum(); + Map keyMap = new HashMap<>(16); + for (int j = cellStart; j < cellEnd; j++) { + // 获取表头数据 + String val = getCellValue(headRow.getCell(j)); + if (val != null && val.trim().length() != 0) { + keyMap.put(j, val); + } + } + // 如果表头没有数据则不进行解析 + if (keyMap.isEmpty()) { + return (JSONArray) Collections.emptyList(); + } + // 获取每行JSON对象的值 + JSONArray array = new JSONArray(); + // 如果首行与尾行相同,表明只有一行,返回表头数据 + if (rowStart == rowEnd) { + JSONObject obj = new JSONObject(); + // 添加行号 + obj.put(ROW_NUM, 1); + for (int i : keyMap.keySet()) { + obj.put(keyMap.get(i), ""); + } + array.add(obj); + return array; + } + for (int i = rowStart + 1; i <= rowEnd; i++) { + Row eachRow = sheet.getRow(i); + JSONObject obj = new JSONObject(); + // 添加行号 + obj.put(ROW_NUM, i + 1); + StringBuilder sb = new StringBuilder(); + for (int k = cellStart; k < cellEnd; k++) { + if (eachRow != null) { + String val = getCellValue(eachRow.getCell(k)); + // 所有数据添加到里面,用于判断该行是否为空 + sb.append(val); + obj.put(keyMap.get(k), val); + } + } + if (sb.length() > 0) { + array.add(obj); + } + } + return array; + } + + private static String getCellValue(Cell cell) { + // 空白或空 + if (cell == null || cell.getCellTypeEnum() == CellType.BLANK) { + return ""; + } + // String类型 + if (cell.getCellTypeEnum() == CellType.STRING) { + String val = cell.getStringCellValue(); + if (val == null || val.trim().length() == 0) { + return ""; + } + return val.trim(); + } + // 数字类型 + if (cell.getCellTypeEnum() == CellType.NUMERIC) { + String s = cell.getNumericCellValue() + ""; + // 去掉尾巴上的小数点0 + if (Pattern.matches(".*\\.0*", s)) { + return s.split("\\.")[0]; + } else { + return s; + } + } + // 布尔值类型 + if (cell.getCellTypeEnum() == CellType.BOOLEAN) { + return cell.getBooleanCellValue() + ""; + } + // 错误类型 + return cell.getCellFormula(); + } + + public static void exportTemplate(HttpServletResponse response, String fileName, Class clazz) { + exportTemplate(response, fileName, fileName, clazz, false); + } + + public static void exportTemplate(HttpServletResponse response, String fileName, String sheetName, + Class clazz) { + exportTemplate(response, fileName, sheetName, clazz, false); + } + + public static void exportTemplate(HttpServletResponse response, String fileName, Class clazz, + boolean isContainExample) { + exportTemplate(response, fileName, fileName, clazz, isContainExample); + } + + public static void exportTemplate(HttpServletResponse response, String fileName, String sheetName, + Class clazz, boolean isContainExample) { + // 获取表头字段 + List headFieldList = getExcelClassFieldList(clazz); + // 获取表头数据和示例数据 + List> sheetDataList = new ArrayList<>(); + List headList = new ArrayList<>(); + List exampleList = new ArrayList<>(); + Map> selectMap = new LinkedHashMap<>(); + for (int i = 0; i < headFieldList.size(); i++) { + ExcelClassField each = headFieldList.get(i); + headList.add(each.getName()); + exampleList.add(each.getExample()); + LinkedHashMap kvMap = each.getKvMap(); + if (kvMap != null && kvMap.size() > 0) { + selectMap.put(i, new ArrayList<>(kvMap.values())); + } + } + sheetDataList.add(headList); + if (isContainExample) { + sheetDataList.add(exampleList); + } + // 导出数据 + export(response, fileName, sheetName, sheetDataList, selectMap); + } + + private static List getExcelClassFieldList(Class clazz) { + // 解析所有字段 + Field[] fields = clazz.getDeclaredFields(); + boolean hasExportAnnotation = false; + Map> map = new LinkedHashMap<>(); + List sortList = new ArrayList<>(); + for (Field field : fields) { + ExcelClassField cf = getExcelClassField(field); + if (cf.getHasAnnotation() == 1) { + hasExportAnnotation = true; + } + int sort = cf.getSort(); + if (map.containsKey(sort)) { + map.get(sort).add(cf); + } else { + List list = new ArrayList<>(); + list.add(cf); + sortList.add(sort); + map.put(sort, list); + } + } + Collections.sort(sortList); + // 获取表头 + List headFieldList = new ArrayList<>(); + if (hasExportAnnotation) { + for (Integer sort : sortList) { + for (ExcelClassField cf : map.get(sort)) { + if (cf.getHasAnnotation() == 1) { + headFieldList.add(cf); + } + } + } + } else { + headFieldList.addAll(map.get(0)); + } + return headFieldList; + } + + private static ExcelClassField getExcelClassField(Field field) { + ExcelClassField cf = new ExcelClassField(); + String fieldName = field.getName(); + cf.setFieldName(fieldName); + ExcelExport annotation = field.getAnnotation(ExcelExport.class); + // 无 ExcelExport 注解情况 + if (annotation == null) { + cf.setHasAnnotation(0); + cf.setName(fieldName); + cf.setSort(0); + return cf; + } + // 有 ExcelExport 注解情况 + cf.setHasAnnotation(1); + cf.setName(annotation.value()); + String example = getString(annotation.example()); + if (!example.isEmpty()) { + if (isNumeric(example)) { + cf.setExample(Double.valueOf(example)); + } else { + cf.setExample(example); + } + } else { + cf.setExample(""); + } + cf.setSort(annotation.sort()); + // 解析映射 + String kv = getString(annotation.kv()); + cf.setKvMap(getKvMap(kv)); + return cf; + } + + private static LinkedHashMap getKvMap(String kv) { + LinkedHashMap kvMap = new LinkedHashMap<>(); + if (kv.isEmpty()) { + return kvMap; + } + String[] kvs = kv.split(";"); + if (kvs.length == 0) { + return kvMap; + } + for (String each : kvs) { + String[] eachKv = getString(each).split("-"); + if (eachKv.length != 2) { + continue; + } + String k = eachKv[0]; + String v = eachKv[1]; + if (k.isEmpty() || v.isEmpty()) { + continue; + } + kvMap.put(k, v); + } + return kvMap; + } + + /** + * 导出表格到本地 + * + * @param file 本地文件对象 + * @param sheetData 导出数据 + */ + public static void exportFile(File file, List> sheetData) { + if (file == null) { + System.out.println("文件创建失败"); + return; + } + if (sheetData == null) { + sheetData = new ArrayList<>(); + } + Map>> map = new HashMap<>(16); + map.put(file.getName(), sheetData); + export(null, file, file.getName(), map, null); + } + + /** + * 导出表格到本地 + * + * @param 导出数据类似,和K类型保持一致 + * @param filePath 文件父路径(如:D:/doc/excel/) + * @param fileName 文件名称(不带尾缀,如:学生表) + * @param list 导出数据 + * @throws IOException IO异常 + */ + public static File exportFile(String filePath, String fileName, List list) throws IOException { + File file = getFile(filePath, fileName); + List> sheetData = getSheetData(list); + exportFile(file, sheetData); + return file; + } + + /** + * 获取文件 + * + * @param filePath filePath 文件父路径(如:D:/doc/excel/) + * @param fileName 文件名称(不带尾缀,如:用户表) + * @return 本地File文件对象 + */ + private static File getFile(String filePath, String fileName) throws IOException { + String dirPath = getString(filePath); + String fileFullPath; + if (dirPath.isEmpty()) { + fileFullPath = fileName; + } else { + // 判定文件夹是否存在,如果不存在,则级联创建 + File dirFile = new File(dirPath); + if (!dirFile.exists()) { + dirFile.mkdirs(); + } + // 获取文件夹全名 + if (dirPath.endsWith(String.valueOf(LEAN_LINE))) { + fileFullPath = dirPath + fileName + XLSX; + } else { + fileFullPath = dirPath + LEAN_LINE + fileName + XLSX; + } + } + System.out.println(fileFullPath); + File file = new File(fileFullPath); + if (!file.exists()) { + file.createNewFile(); + } + return file; + } + + private static List> getSheetData(List list) { + // 获取表头字段 + List excelClassFieldList = getExcelClassFieldList(list.get(0).getClass()); + List headFieldList = new ArrayList<>(); + List headList = new ArrayList<>(); + Map headFieldMap = new HashMap<>(16); + for (ExcelClassField each : excelClassFieldList) { + String fieldName = each.getFieldName(); + headFieldList.add(fieldName); + headFieldMap.put(fieldName, each); + headList.add(each.getName()); + } + // 添加表头名称 + List> sheetDataList = new ArrayList<>(); + sheetDataList.add(headList); + // 获取表数据 + for (T t : list) { + Map fieldDataMap = getFieldDataMap(t); + Set fieldDataKeys = fieldDataMap.keySet(); + List rowList = new ArrayList<>(); + for (String headField : headFieldList) { + if (!fieldDataKeys.contains(headField)) { + continue; + } + Object data = fieldDataMap.get(headField); + if (data == null) { + rowList.add(""); + continue; + } + ExcelClassField cf = headFieldMap.get(headField); + // 判断是否有映射关系 + LinkedHashMap kvMap = cf.getKvMap(); + if (kvMap == null || kvMap.isEmpty()) { + rowList.add(data); + continue; + } + String val = kvMap.get(data.toString()); + if (isNumeric(val)) { + rowList.add(Double.valueOf(val)); + } else { + rowList.add(val); + } + } + sheetDataList.add(rowList); + } + return sheetDataList; + } + + private static Map getFieldDataMap(T t) { + Map map = new HashMap<>(16); + Field[] fields = t.getClass().getDeclaredFields(); + try { + for (Field field : fields) { + String fieldName = field.getName(); + field.setAccessible(true); + Object object = field.get(t); + map.put(fieldName, object); + } + } catch (IllegalArgumentException | IllegalAccessException e) { + e.printStackTrace(); + } + return map; + } + + public static void exportEmpty(HttpServletResponse response, String fileName) { + List> sheetDataList = new ArrayList<>(); + List headList = new ArrayList<>(); + headList.add("导出无数据"); + sheetDataList.add(headList); + export(response, fileName, sheetDataList); + } + + public static void export(HttpServletResponse response, String fileName, List> sheetDataList) { + export(response, fileName, fileName, sheetDataList, null); + } + + public static void exportManySheet(HttpServletResponse response, String fileName, Map>> sheetMap) { + export(response, null, fileName, sheetMap, null); + } + + + public static void export(HttpServletResponse response, String fileName, String sheetName, + List> sheetDataList) { + export(response, fileName, sheetName, sheetDataList, null); + } + + public static void export(HttpServletResponse response, String fileName, String sheetName, + List> sheetDataList, Map> selectMap) { + + Map>> map = new HashMap<>(16); + map.put(sheetName, sheetDataList); + export(response, null, fileName, map, selectMap); + } + + public static void export(HttpServletResponse response, String fileName, List list, Class template) { + // list 是否为空 + boolean lisIsEmpty = list == null || list.isEmpty(); + // 如果模板数据为空,且导入的数据为空,则导出空文件 + if (template == null && lisIsEmpty) { + exportEmpty(response, fileName); + return; + } + // 如果 list 数据,则导出模板数据 + if (lisIsEmpty) { + exportTemplate(response, fileName, template); + return; + } + // 导出数据 + List> sheetDataList = getSheetData(list); + export(response, fileName, sheetDataList); + } + + public static void export(HttpServletResponse response, String fileName, List> sheetDataList, Map> selectMap) { + export(response, fileName, fileName, sheetDataList, selectMap); + } + + private static void export(HttpServletResponse response, File file, String fileName, + Map>> sheetMap, Map> selectMap) { + // 整个 Excel 表格 book 对象 + SXSSFWorkbook book = new SXSSFWorkbook(); + // 每个 Sheet 页 + Set>>> entries = sheetMap.entrySet(); + for (Entry>> entry : entries) { + List> sheetDataList = entry.getValue(); + Sheet sheet = book.createSheet(entry.getKey()); + Drawing patriarch = sheet.createDrawingPatriarch(); + // 设置表头背景色(灰色) + CellStyle headStyle = book.createCellStyle(); + headStyle.setFillForegroundColor(IndexedColors.GREY_80_PERCENT.index); + headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + headStyle.setAlignment(HorizontalAlignment.CENTER); + headStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.index); + // 设置表身背景色(默认色) + CellStyle rowStyle = book.createCellStyle(); + rowStyle.setAlignment(HorizontalAlignment.CENTER); + rowStyle.setVerticalAlignment(VerticalAlignment.CENTER); + // 设置表格列宽度(默认为15个字节) + sheet.setDefaultColumnWidth(15); + // 创建合并算法数组 + int rowLength = sheetDataList.size(); + int columnLength = sheetDataList.get(0).size(); + int[][] mergeArray = new int[rowLength][columnLength]; + for (int i = 0; i < sheetDataList.size(); i++) { + // 每个 Sheet 页中的行数据 + Row row = sheet.createRow(i); + List rowList = sheetDataList.get(i); + for (int j = 0; j < rowList.size(); j++) { + // 每个行数据中的单元格数据 + Object o = rowList.get(j); + int v = 0; + if (o instanceof URL) { + // 如果要导出图片的话, 链接需要传递 URL 对象 + setCellPicture(book, row, patriarch, i, j, (URL) o); + } else { + Cell cell = row.createCell(j); + if (i == 0) { + // 第一行为表头行,采用灰色底背景 + v = setCellValue(cell, o, headStyle); + } else { + // 其他行为数据行,默认白底色 + v = setCellValue(cell, o, rowStyle); + } + } + mergeArray[i][j] = v; + } + } + // 合并单元格 + mergeCells(sheet, mergeArray); + // 设置下拉列表 + setSelect(sheet, selectMap); + } + // 写数据 + if (response != null) { + // 前端导出 + try { + write(response, book, fileName); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + // 本地导出 + FileOutputStream fos; + try { + fos = new FileOutputStream(file); + ByteArrayOutputStream ops = new ByteArrayOutputStream(); + book.write(ops); + fos.write(ops.toByteArray()); + fos.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 合并当前Sheet页的单元格 + * + * @param sheet 当前 sheet 页 + * @param mergeArray 合并单元格算法 + */ + private static void mergeCells(Sheet sheet, int[][] mergeArray) { + // 横向合并 + for (int x = 0; x < mergeArray.length; x++) { + int[] arr = mergeArray[x]; + boolean merge = false; + int y1 = 0; + int y2 = 0; + for (int y = 0; y < arr.length; y++) { + int value = arr[y]; + if (value == CELL_COLUMN_MERGE) { + if (!merge) { + y1 = y; + } + y2 = y; + merge = true; + } else { + merge = false; + if (y1 > 0) { + sheet.addMergedRegion(new CellRangeAddress(x, x, (y1 - 1), y2)); + } + y1 = 0; + y2 = 0; + } + } + if (y1 > 0) { + sheet.addMergedRegion(new CellRangeAddress(x, x, (y1 - 1), y2)); + } + } + // 纵向合并 + int xLen = mergeArray.length; + int yLen = mergeArray[0].length; + for (int y = 0; y < yLen; y++) { + boolean merge = false; + int x1 = 0; + int x2 = 0; + for (int x = 0; x < xLen; x++) { + int value = mergeArray[x][y]; + if (value == CELL_ROW_MERGE) { + if (!merge) { + x1 = x; + } + x2 = x; + merge = true; + } else { + merge = false; + if (x1 > 0) { + sheet.addMergedRegion(new CellRangeAddress((x1 - 1), x2, y, y)); + } + x1 = 0; + x2 = 0; + } + } + if (x1 > 0) { + sheet.addMergedRegion(new CellRangeAddress((x1 - 1), x2, y, y)); + } + } + } + + private static void write(HttpServletResponse response, SXSSFWorkbook book, String fileName) throws IOException { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + String name = new String(fileName.getBytes("GBK"), "ISO8859_1") + XLSX; + response.addHeader("Content-Disposition", "attachment;filename=" + name); + ServletOutputStream out = response.getOutputStream(); + book.write(out); + out.flush(); + out.close(); + } + + private static int setCellValue(Cell cell, Object o, CellStyle style) { + // 设置样式 + cell.setCellStyle(style); + // 数据为空时 + if (ObjectUtil.isEmpty(o)) { + cell.setCellType(CellType.STRING); + cell.setCellValue(""); + return CELL_OTHER; + } + // 是否为字符串 + if (o instanceof String) { + String s = o.toString(); + if (isNumeric(s)) { + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(Double.parseDouble(s)); + return CELL_OTHER; + } else { + cell.setCellType(CellType.STRING); + cell.setCellValue(s); + } + if (s.equals(ROW_MERGE)) { + return CELL_ROW_MERGE; + } else if (s.equals(COLUMN_MERGE)) { + return CELL_COLUMN_MERGE; + } else { + return CELL_OTHER; + } + } + // 是否为字符串 + if (o instanceof Integer || o instanceof Long || o instanceof Double || o instanceof Float) { + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(Double.parseDouble(o.toString())); + return CELL_OTHER; + } + // 是否为Boolean + if (o instanceof Boolean) { + cell.setCellType(CellType.BOOLEAN); + cell.setCellValue((Boolean) o); + return CELL_OTHER; + } + // 如果是BigDecimal,则默认3位小数 + if (o instanceof BigDecimal) { + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(((BigDecimal) o).setScale(3, RoundingMode.HALF_UP).doubleValue()); + return CELL_OTHER; + } + // 如果是Date数据,则显示格式化数据 + if (o instanceof Date) { + cell.setCellType(CellType.STRING); + cell.setCellValue(formatDate((Date) o)); + return CELL_OTHER; + } + // 如果是其他,则默认字符串类型 + cell.setCellType(CellType.STRING); + cell.setCellValue(o.toString()); + return CELL_OTHER; + } + + private static void setCellPicture(SXSSFWorkbook wb, Row sr, Drawing patriarch, int x, int y, URL url) { + // 设置图片宽高 + sr.setHeight((short) (IMG_WIDTH * IMG_HEIGHT)); + // (jdk1.7版本try中定义流可自动关闭) + try (InputStream is = url.openStream(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + byte[] buff = new byte[BYTES_DEFAULT_LENGTH]; + int rc; + while ((rc = is.read(buff, 0, BYTES_DEFAULT_LENGTH)) > 0) { + outputStream.write(buff, 0, rc); + } + // 设置图片位置 + XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, y, x, y + 1, x + 1); + // 设置这个,图片会自动填满单元格的长宽 + anchor.setAnchorType(AnchorType.MOVE_AND_RESIZE); + patriarch.createPicture(anchor, wb.addPicture(outputStream.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static String formatDate(Date date) { + if (date == null) { + return ""; + } + SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT); + return format.format(date); + } + + private static void setSelect(Sheet sheet, Map> selectMap) { + if (selectMap == null || selectMap.isEmpty()) { + return; + } + Set>> entrySet = selectMap.entrySet(); + for (Entry> entry : entrySet) { + int y = entry.getKey(); + List list = entry.getValue(); + if (list == null || list.isEmpty()) { + continue; + } + String[] arr = new String[list.size()]; + for (int i = 0; i < list.size(); i++) { + arr[i] = list.get(i); + } + DataValidationHelper helper = sheet.getDataValidationHelper(); + CellRangeAddressList addressList = new CellRangeAddressList(1, 65000, y, y); + DataValidationConstraint dvc = helper.createExplicitListConstraint(arr); + DataValidation dv = helper.createValidation(dvc, addressList); + if (dv instanceof HSSFDataValidation) { + dv.setSuppressDropDownArrow(false); + } else { + dv.setSuppressDropDownArrow(true); + dv.setShowErrorBox(true); + } + sheet.addValidationData(dv); + } + } + + private static boolean isNumeric(String str) { + if ("0.0".equals(str)) { + return true; + } + if (str.length() >= 15) { + return false; + } + for (int i = str.length(); --i >= 0; ) { + if (!Character.isDigit(str.charAt(i))) { + return false; + } + } + return true; + } + + private static String getString(String s) { + if (s == null) { + return ""; + } + if (s.isEmpty()) { + return s; + } + return s.trim(); + } +} diff --git a/wjcy-common/src/test/java/me/zhengjie/utils/EncryptUtilsTest.java b/wjcy-common/src/test/java/me/zhengjie/utils/EncryptUtilsTest.java new file mode 100644 index 0000000..f909d9d --- /dev/null +++ b/wjcy-common/src/test/java/me/zhengjie/utils/EncryptUtilsTest.java @@ -0,0 +1,32 @@ +package me.zhengjie.utils; + +import org.junit.Test; +import static org.junit.Assert.*; +import static me.zhengjie.utils.EncryptUtils.*; + +public class EncryptUtilsTest { + + /** + * 对称加密 + */ + @Test + public void testDesEncrypt() { + try { + assertEquals("7772841DC6099402", desEncrypt("123456")); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 对称解密 + */ + @Test + public void testDesDecrypt() { + try { + assertEquals("123456", desDecrypt("7772841DC6099402")); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/wjcy-common/src/test/java/me/zhengjie/utils/FileUtilTest.java b/wjcy-common/src/test/java/me/zhengjie/utils/FileUtilTest.java new file mode 100644 index 0000000..f069c15 --- /dev/null +++ b/wjcy-common/src/test/java/me/zhengjie/utils/FileUtilTest.java @@ -0,0 +1,36 @@ +package me.zhengjie.utils; + +import org.junit.Test; +import org.springframework.mock.web.MockMultipartFile; + +import static org.junit.Assert.*; +import static me.zhengjie.utils.FileUtil.*; + +public class FileUtilTest { + + @Test + public void testToFile() { + long retval = toFile(new MockMultipartFile("foo", (byte[]) null)).getTotalSpace(); + assertEquals(500695072768L, retval); + } + + @Test + public void testGetExtensionName() { + assertEquals("foo", getExtensionName("foo")); + assertEquals("exe", getExtensionName("bar.exe")); + } + + @Test + public void testGetFileNameNoEx() { + assertEquals("foo", getFileNameNoEx("foo")); + assertEquals("bar", getFileNameNoEx("bar.txt")); + } + + @Test + public void testGetSize() { + assertEquals("1000B ", getSize(1000)); + assertEquals("1.00KB ", getSize(1024)); + assertEquals("1.00MB ", getSize(1048576)); + assertEquals("1.00GB ", getSize(1073741824)); + } +} diff --git a/wjcy-common/src/test/java/me/zhengjie/utils/StringUtilsTest.java b/wjcy-common/src/test/java/me/zhengjie/utils/StringUtilsTest.java new file mode 100644 index 0000000..16de472 --- /dev/null +++ b/wjcy-common/src/test/java/me/zhengjie/utils/StringUtilsTest.java @@ -0,0 +1,66 @@ +package me.zhengjie.utils; + +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.thymeleaf.util.DateUtils; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import static me.zhengjie.utils.StringUtils.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class StringUtilsTest { + + @Test + public void testToCamelCase() { + assertNull(toCamelCase(null)); + } + + @Test + public void testToCapitalizeCamelCase() { + assertNull(StringUtils.toCapitalizeCamelCase(null)); + assertEquals("HelloWorld", toCapitalizeCamelCase("hello_world")); + } + + @Test + public void testToUnderScoreCase() { + assertNull(StringUtils.toUnderScoreCase(null)); + assertEquals("hello_world", toUnderScoreCase("helloWorld")); + assertEquals("\u0000\u0000", toUnderScoreCase("\u0000\u0000")); + assertEquals("\u0000_a", toUnderScoreCase("\u0000A")); + } + + @Test + public void testGetWeekDay() { + SimpleDateFormat simpleDateformat = new SimpleDateFormat("E"); + assertEquals(simpleDateformat.format(new Date()), getWeekDay()); + } + + @Test + public void testGetIP() { + assertEquals("127.0.0.1", getIp(new MockHttpServletRequest())); + } + + + + @Test + public void test123() { + // 仅一次 + Date date = DateUtil.date(); + System.out.println("date:" + date); + DateTime dateTime = DateUtil.offsetSecond(date, 5); + System.out.println("dateTime:" + dateTime); + + String onlyOnce = CronUtils.onlyOnce(DateUtil.formatDateTime(dateTime)); + String onlyOnce1 = CronUtils.onlyOnce("2022-10-10 10:10:10"); + System.out.println(onlyOnce); + + // 一部到位 + String onlyOnce2 = CronUtils.onlyOnce(DateUtil.formatDateTime(DateUtil.offsetSecond(DateUtil.date(), 5))); + System.out.println(onlyOnce2); + } +} \ No newline at end of file diff --git a/wjcy-generator/pom.xml b/wjcy-generator/pom.xml new file mode 100644 index 0000000..87d7e4e --- /dev/null +++ b/wjcy-generator/pom.xml @@ -0,0 +1,39 @@ + + + + wjcy + me.zhengjie + 1.0 + + 4.0.0 + + wjcy-generator + 代码生成模块 + + + 1.9 + + + + + me.zhengjie + wjcy-common + 1.0 + + + + + org.springframework.boot + spring-boot-starter-freemarker + + + + + commons-configuration + commons-configuration + ${configuration.version} + + + \ No newline at end of file diff --git a/wjcy-generator/src/main/java/me/zhengjie/domain/ColumnInfo.java b/wjcy-generator/src/main/java/me/zhengjie/domain/ColumnInfo.java new file mode 100644 index 0000000..fdb962a --- /dev/null +++ b/wjcy-generator/src/main/java/me/zhengjie/domain/ColumnInfo.java @@ -0,0 +1,97 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import me.zhengjie.utils.GenUtil; +import javax.persistence.*; +import java.io.Serializable; + +/** + * 列的数据信息 + * @author Zheng Jie + * @date 2019-01-02 + */ +@Getter +@Setter +@Entity +@NoArgsConstructor +@Table(name = "code_column_config") +public class ColumnInfo implements Serializable { + + @Id + @Column(name = "column_id") + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ApiModelProperty(value = "表名") + private String tableName; + + @ApiModelProperty(value = "数据库字段名称") + private String columnName; + + @ApiModelProperty(value = "数据库字段类型") + private String columnType; + + @ApiModelProperty(value = "数据库字段键类型") + private String keyType; + + @ApiModelProperty(value = "字段额外的参数") + private String extra; + + @ApiModelProperty(value = "数据库字段描述") + private String remark; + + @ApiModelProperty(value = "是否必填") + private Boolean notNull; + + @ApiModelProperty(value = "是否在列表显示") + private Boolean listShow; + + @ApiModelProperty(value = "是否表单显示") + private Boolean formShow; + + @ApiModelProperty(value = "表单类型") + private String formType; + + @ApiModelProperty(value = "查询 1:模糊 2:精确") + private String queryType; + + @ApiModelProperty(value = "字典名称") + private String dictName; + + @ApiModelProperty(value = "日期注解") + private String dateAnnotation; + + public ColumnInfo(String tableName, String columnName, Boolean notNull, String columnType, String remark, String keyType, String extra) { + this.tableName = tableName; + this.columnName = columnName; + this.columnType = columnType; + this.keyType = keyType; + this.extra = extra; + this.notNull = notNull; + if(GenUtil.PK.equalsIgnoreCase(keyType) && GenUtil.EXTRA.equalsIgnoreCase(extra)){ + this.notNull = false; + } + this.remark = remark; + this.listShow = true; + this.formShow = true; + } +} diff --git a/wjcy-generator/src/main/java/me/zhengjie/domain/GenConfig.java b/wjcy-generator/src/main/java/me/zhengjie/domain/GenConfig.java new file mode 100644 index 0000000..a2d6706 --- /dev/null +++ b/wjcy-generator/src/main/java/me/zhengjie/domain/GenConfig.java @@ -0,0 +1,78 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * 代码生成配置 + * @author Zheng Jie + * @date 2019-01-03 + */ +@Getter +@Setter +@Entity +@NoArgsConstructor +@Table(name = "code_gen_config") +public class GenConfig implements Serializable { + + public GenConfig(String tableName) { + this.tableName = tableName; + } + + @Id + @Column(name = "config_id") + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotBlank + @ApiModelProperty(value = "表名") + private String tableName; + + @ApiModelProperty(value = "接口名称") + private String apiAlias; + + @NotBlank + @ApiModelProperty(value = "包路径") + private String pack; + + @NotBlank + @ApiModelProperty(value = "模块名") + private String moduleName; + + @NotBlank + @ApiModelProperty(value = "前端文件路径") + private String path; + + @ApiModelProperty(value = "前端文件路径") + private String apiPath; + + @ApiModelProperty(value = "作者") + private String author; + + @ApiModelProperty(value = "表前缀") + private String prefix; + + @ApiModelProperty(value = "是否覆盖") + private Boolean cover = false; +} diff --git a/wjcy-generator/src/main/java/me/zhengjie/domain/vo/TableInfo.java b/wjcy-generator/src/main/java/me/zhengjie/domain/vo/TableInfo.java new file mode 100644 index 0000000..1d3967b --- /dev/null +++ b/wjcy-generator/src/main/java/me/zhengjie/domain/vo/TableInfo.java @@ -0,0 +1,48 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.domain.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 表的数据信息 + * @author Zheng Jie + * @date 2019-01-02 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class TableInfo { + + /** 表名称 */ + private Object tableName; + + /** 创建日期 */ + private Object createTime; + + /** 数据库引擎 */ + private Object engine; + + /** 编码集 */ + private Object coding; + + /** 备注 */ + private Object remark; + + +} diff --git a/wjcy-generator/src/main/java/me/zhengjie/repository/ColumnInfoRepository.java b/wjcy-generator/src/main/java/me/zhengjie/repository/ColumnInfoRepository.java new file mode 100644 index 0000000..4638be2 --- /dev/null +++ b/wjcy-generator/src/main/java/me/zhengjie/repository/ColumnInfoRepository.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.repository; + +import me.zhengjie.domain.ColumnInfo; +import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; + +/** + * @author Zheng Jie + * @date 2019-01-14 + */ +public interface ColumnInfoRepository extends JpaRepository { + + /** + * 查询表信息 + * @param tableName 表格名 + * @return 表信息 + */ + List findByTableNameOrderByIdAsc(String tableName); +} diff --git a/wjcy-generator/src/main/java/me/zhengjie/repository/GenConfigRepository.java b/wjcy-generator/src/main/java/me/zhengjie/repository/GenConfigRepository.java new file mode 100644 index 0000000..18c9a0c --- /dev/null +++ b/wjcy-generator/src/main/java/me/zhengjie/repository/GenConfigRepository.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.repository; + +import me.zhengjie.domain.GenConfig; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * @author Zheng Jie + * @date 2019-01-14 + */ +public interface GenConfigRepository extends JpaRepository { + + /** + * 查询表配置 + * @param tableName 表名 + * @return / + */ + GenConfig findByTableName(String tableName); +} diff --git a/wjcy-generator/src/main/java/me/zhengjie/rest/GenConfigController.java b/wjcy-generator/src/main/java/me/zhengjie/rest/GenConfigController.java new file mode 100644 index 0000000..98ec149 --- /dev/null +++ b/wjcy-generator/src/main/java/me/zhengjie/rest/GenConfigController.java @@ -0,0 +1,51 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.domain.GenConfig; +import me.zhengjie.service.GenConfigService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +/** + * @author Zheng Jie + * @date 2019-01-14 + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/genConfig") +@Api(tags = "系统:代码生成器配置管理") +public class GenConfigController { + + private final GenConfigService genConfigService; + + @ApiOperation("查询") + @GetMapping(value = "/{tableName}") + public ResponseEntity query(@PathVariable String tableName){ + return new ResponseEntity<>(genConfigService.find(tableName), HttpStatus.OK); + } + + @ApiOperation("修改") + @PutMapping + public ResponseEntity update(@Validated @RequestBody GenConfig genConfig){ + return new ResponseEntity<>(genConfigService.update(genConfig.getTableName(), genConfig),HttpStatus.OK); + } +} diff --git a/wjcy-generator/src/main/java/me/zhengjie/rest/GeneratorController.java b/wjcy-generator/src/main/java/me/zhengjie/rest/GeneratorController.java new file mode 100644 index 0000000..ce6a17d --- /dev/null +++ b/wjcy-generator/src/main/java/me/zhengjie/rest/GeneratorController.java @@ -0,0 +1,107 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.domain.ColumnInfo; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.service.GenConfigService; +import me.zhengjie.service.GeneratorService; +import me.zhengjie.utils.PageUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author Zheng Jie + * @date 2019-01-02 + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/generator") +@Api(tags = "系统:代码生成管理") +public class GeneratorController { + + private final GeneratorService generatorService; + private final GenConfigService genConfigService; + + @Value("${generator.enabled}") + private Boolean generatorEnabled; + + @ApiOperation("查询数据库数据") + @GetMapping(value = "/tables/all") + public ResponseEntity queryTables(){ + return new ResponseEntity<>(generatorService.getTables(), HttpStatus.OK); + } + + @ApiOperation("查询数据库数据") + @GetMapping(value = "/tables") + public ResponseEntity queryTables(@RequestParam(defaultValue = "") String name, + @RequestParam(defaultValue = "0")Integer page, + @RequestParam(defaultValue = "10")Integer size){ + int[] startEnd = PageUtil.transToStartEnd(page, size); + return new ResponseEntity<>(generatorService.getTables(name,startEnd), HttpStatus.OK); + } + + @ApiOperation("查询字段数据") + @GetMapping(value = "/columns") + public ResponseEntity queryColumns(@RequestParam String tableName){ + List columnInfos = generatorService.getColumns(tableName); + return new ResponseEntity<>(PageUtil.toPage(columnInfos,columnInfos.size()), HttpStatus.OK); + } + + @ApiOperation("保存字段数据") + @PutMapping + public ResponseEntity save(@RequestBody List columnInfos){ + generatorService.save(columnInfos); + return new ResponseEntity<>(HttpStatus.OK); + } + + @ApiOperation("同步字段数据") + @PostMapping(value = "sync") + public ResponseEntity sync(@RequestBody List tables){ + for (String table : tables) { + generatorService.sync(generatorService.getColumns(table), generatorService.query(table)); + } + return new ResponseEntity<>(HttpStatus.OK); + } + + @ApiOperation("生成代码") + @PostMapping(value = "/{tableName}/{type}") + public ResponseEntity generator(@PathVariable String tableName, @PathVariable Integer type, HttpServletRequest request, HttpServletResponse response){ + if(!generatorEnabled && type == 0){ + throw new BadRequestException("此环境不允许生成代码,请选择预览或者下载查看!"); + } + switch (type){ + // 生成代码 + case 0: generatorService.generator(genConfigService.find(tableName), generatorService.getColumns(tableName)); + break; + // 预览 + case 1: return generatorService.preview(genConfigService.find(tableName), generatorService.getColumns(tableName)); + // 打包 + case 2: generatorService.download(genConfigService.find(tableName), generatorService.getColumns(tableName), request, response); + break; + default: throw new BadRequestException("没有这个选项"); + } + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/wjcy-generator/src/main/java/me/zhengjie/service/GenConfigService.java b/wjcy-generator/src/main/java/me/zhengjie/service/GenConfigService.java new file mode 100644 index 0000000..b5711f4 --- /dev/null +++ b/wjcy-generator/src/main/java/me/zhengjie/service/GenConfigService.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service; + +import me.zhengjie.domain.GenConfig; + +/** + * @author Zheng Jie + * @date 2019-01-14 + */ +public interface GenConfigService { + + /** + * 查询表配置 + * @param tableName 表名 + * @return 表配置 + */ + GenConfig find(String tableName); + + /** + * 更新表配置 + * @param tableName 表名 + * @param genConfig 表配置 + * @return 表配置 + */ + GenConfig update(String tableName, GenConfig genConfig); +} diff --git a/wjcy-generator/src/main/java/me/zhengjie/service/GeneratorService.java b/wjcy-generator/src/main/java/me/zhengjie/service/GeneratorService.java new file mode 100644 index 0000000..b5a1e0a --- /dev/null +++ b/wjcy-generator/src/main/java/me/zhengjie/service/GeneratorService.java @@ -0,0 +1,96 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service; + +import me.zhengjie.domain.GenConfig; +import me.zhengjie.domain.ColumnInfo; +import org.springframework.http.ResponseEntity; +import org.springframework.scheduling.annotation.Async; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author Zheng Jie + * @date 2019-01-02 + */ +public interface GeneratorService { + + /** + * 查询数据库元数据 + * @param name 表名 + * @param startEnd 分页参数 + * @return / + */ + Object getTables(String name, int[] startEnd); + + /** + * 得到数据表的元数据 + * @param name 表名 + * @return / + */ + List getColumns(String name); + + /** + * 同步表数据 + * @param columnInfos / + * @param columnInfoList / + */ + void sync(List columnInfos, List columnInfoList); + + /** + * 保持数据 + * @param columnInfos / + */ + void save(List columnInfos); + + /** + * 获取所有table + * @return / + */ + Object getTables(); + + /** + * 代码生成 + * @param genConfig 配置信息 + * @param columns 字段信息 + */ + void generator(GenConfig genConfig, List columns); + + /** + * 预览 + * @param genConfig 配置信息 + * @param columns 字段信息 + * @return / + */ + ResponseEntity preview(GenConfig genConfig, List columns); + + /** + * 打包下载 + * @param genConfig 配置信息 + * @param columns 字段信息 + * @param request / + * @param response / + */ + void download(GenConfig genConfig, List columns, HttpServletRequest request, HttpServletResponse response); + + /** + * 查询数据库的表字段数据数据 + * @param table / + * @return / + */ + List query(String table); +} diff --git a/wjcy-generator/src/main/java/me/zhengjie/service/impl/GenConfigServiceImpl.java b/wjcy-generator/src/main/java/me/zhengjie/service/impl/GenConfigServiceImpl.java new file mode 100644 index 0000000..bc2d061 --- /dev/null +++ b/wjcy-generator/src/main/java/me/zhengjie/service/impl/GenConfigServiceImpl.java @@ -0,0 +1,67 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.impl; + +import lombok.RequiredArgsConstructor; +import me.zhengjie.domain.GenConfig; +import me.zhengjie.repository.GenConfigRepository; +import me.zhengjie.service.GenConfigService; +import me.zhengjie.utils.StringUtils; +import org.springframework.stereotype.Service; +import java.io.File; + +/** + * @author Zheng Jie + * @date 2019-01-14 + */ +@Service +@RequiredArgsConstructor +public class GenConfigServiceImpl implements GenConfigService { + + private final GenConfigRepository genConfigRepository; + + @Override + public GenConfig find(String tableName) { + GenConfig genConfig = genConfigRepository.findByTableName(tableName); + if(genConfig == null){ + return new GenConfig(tableName); + } + return genConfig; + } + + @Override + public GenConfig update(String tableName, GenConfig genConfig) { + String separator = File.separator; + String[] paths; + String symbol = "\\"; + if (symbol.equals(separator)) { + paths = genConfig.getPath().split("\\\\"); + } else { + paths = genConfig.getPath().split(File.separator); + } + StringBuilder api = new StringBuilder(); + for (String path : paths) { + api.append(path); + api.append(separator); + if ("src".equals(path)) { + api.append("api"); + break; + } + } + genConfig.setApiPath(api.toString()); + return genConfigRepository.save(genConfig); + } +} diff --git a/wjcy-generator/src/main/java/me/zhengjie/service/impl/GeneratorServiceImpl.java b/wjcy-generator/src/main/java/me/zhengjie/service/impl/GeneratorServiceImpl.java new file mode 100644 index 0000000..1b1803b --- /dev/null +++ b/wjcy-generator/src/main/java/me/zhengjie/service/impl/GeneratorServiceImpl.java @@ -0,0 +1,203 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.ZipUtil; +import lombok.RequiredArgsConstructor; +import me.zhengjie.domain.GenConfig; +import me.zhengjie.domain.ColumnInfo; +import me.zhengjie.domain.vo.TableInfo; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.repository.ColumnInfoRepository; +import me.zhengjie.service.GeneratorService; +import me.zhengjie.utils.FileUtil; +import me.zhengjie.utils.GenUtil; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + * @date 2019-01-02 + */ +@Service +@RequiredArgsConstructor +public class GeneratorServiceImpl implements GeneratorService { + private static final Logger log = LoggerFactory.getLogger(GeneratorServiceImpl.class); + @PersistenceContext + private EntityManager em; + + private final ColumnInfoRepository columnInfoRepository; + + @Override + public Object getTables() { + // 使用预编译防止sql注入 + String sql = "select table_name ,create_time , engine, table_collation, table_comment from information_schema.tables " + + "where table_schema = (select database()) " + + "order by create_time desc"; + Query query = em.createNativeQuery(sql); + return query.getResultList(); + } + + @Override + public Object getTables(String name, int[] startEnd) { + // 使用预编译防止sql注入 + String sql = "select table_name ,create_time , engine, table_collation, table_comment from information_schema.tables " + + "where table_schema = (select database()) " + + "and table_name like ? order by create_time desc"; + Query query = em.createNativeQuery(sql); + query.setFirstResult(startEnd[0]); + query.setMaxResults(startEnd[1] - startEnd[0]); + query.setParameter(1, StringUtils.isNotBlank(name) ? ("%" + name + "%") : "%%"); + List result = query.getResultList(); + List tableInfos = new ArrayList<>(); + for (Object obj : result) { + Object[] arr = (Object[]) obj; + tableInfos.add(new TableInfo(arr[0], arr[1], arr[2], arr[3], ObjectUtil.isNotEmpty(arr[4]) ? arr[4] : "-")); + } + Query query1 = em.createNativeQuery("SELECT COUNT(*) from information_schema.tables where table_schema = (select database())"); + Object totalElements = query1.getSingleResult(); + return PageUtil.toPage(tableInfos, totalElements); + } + + @Override + public List getColumns(String tableName) { + List columnInfos = columnInfoRepository.findByTableNameOrderByIdAsc(tableName); + if (CollectionUtil.isNotEmpty(columnInfos)) { + return columnInfos; + } else { + columnInfos = query(tableName); + return columnInfoRepository.saveAll(columnInfos); + } + } + + @Override + public List query(String tableName) { + // 使用预编译防止sql注入 + String sql = "select column_name, is_nullable, data_type, column_comment, column_key, extra from information_schema.columns " + + "where table_name = ? and table_schema = (select database()) order by ordinal_position"; + Query query = em.createNativeQuery(sql); + query.setParameter(1, tableName); + List result = query.getResultList(); + List columnInfos = new ArrayList<>(); + for (Object obj : result) { + Object[] arr = (Object[]) obj; + columnInfos.add( + new ColumnInfo( + tableName, + arr[0].toString(), + "NO".equals(arr[1]), + arr[2].toString(), + ObjectUtil.isNotNull(arr[3]) ? arr[3].toString() : null, + ObjectUtil.isNotNull(arr[4]) ? arr[4].toString() : null, + ObjectUtil.isNotNull(arr[5]) ? arr[5].toString() : null) + ); + } + return columnInfos; + } + + @Override + public void sync(List columnInfos, List columnInfoList) { + // 第一种情况,数据库类字段改变或者新增字段 + for (ColumnInfo columnInfo : columnInfoList) { + // 根据字段名称查找 + List columns = columnInfos.stream().filter(c -> c.getColumnName().equals(columnInfo.getColumnName())).collect(Collectors.toList()); + // 如果能找到,就修改部分可能被字段 + if (CollectionUtil.isNotEmpty(columns)) { + ColumnInfo column = columns.get(0); + column.setColumnType(columnInfo.getColumnType()); + column.setExtra(columnInfo.getExtra()); + column.setKeyType(columnInfo.getKeyType()); + if (StringUtils.isBlank(column.getRemark())) { + column.setRemark(columnInfo.getRemark()); + } + columnInfoRepository.save(column); + } else { + // 如果找不到,则保存新字段信息 + columnInfoRepository.save(columnInfo); + } + } + // 第二种情况,数据库字段删除了 + for (ColumnInfo columnInfo : columnInfos) { + // 根据字段名称查找 + List columns = columnInfoList.stream().filter(c -> c.getColumnName().equals(columnInfo.getColumnName())).collect(Collectors.toList()); + // 如果找不到,就代表字段被删除了,则需要删除该字段 + if (CollectionUtil.isEmpty(columns)) { + columnInfoRepository.delete(columnInfo); + } + } + } + + @Override + public void save(List columnInfos) { + columnInfoRepository.saveAll(columnInfos); + } + + @Override + public void generator(GenConfig genConfig, List columns) { + if (genConfig.getId() == null) { + throw new BadRequestException("请先配置生成器"); + } + try { + GenUtil.generatorCode(columns, genConfig); + } catch (IOException e) { + log.error(e.getMessage(), e); + throw new BadRequestException("生成失败,请手动处理已生成的文件"); + } + } + + @Override + public ResponseEntity preview(GenConfig genConfig, List columns) { + if (genConfig.getId() == null) { + throw new BadRequestException("请先配置生成器"); + } + List> genList = GenUtil.preview(columns, genConfig); + return new ResponseEntity<>(genList, HttpStatus.OK); + } + + @Override + public void download(GenConfig genConfig, List columns, HttpServletRequest request, HttpServletResponse response) { + if (genConfig.getId() == null) { + throw new BadRequestException("请先配置生成器"); + } + try { + File file = new File(GenUtil.download(columns, genConfig)); + String zipPath = file.getPath() + ".zip"; + ZipUtil.zip(file.getPath(), zipPath); + FileUtil.downloadFile(request, response, new File(zipPath), true); + } catch (IOException e) { + throw new BadRequestException("打包失败"); + } + } +} diff --git a/wjcy-generator/src/main/java/me/zhengjie/utils/ColUtil.java b/wjcy-generator/src/main/java/me/zhengjie/utils/ColUtil.java new file mode 100644 index 0000000..b5fcd6b --- /dev/null +++ b/wjcy-generator/src/main/java/me/zhengjie/utils/ColUtil.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import org.apache.commons.configuration.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * sql字段转java + * + * @author Zheng Jie + * @date 2019-01-03 + */ +public class ColUtil { + private static final Logger log = LoggerFactory.getLogger(ColUtil.class); + + /** + * 转换mysql数据类型为java数据类型 + * + * @param type 数据库字段类型 + * @return String + */ + static String cloToJava(String type) { + Configuration config = getConfig(); + assert config != null; + return config.getString(type, "unknowType"); + } + + /** + * 获取配置信息 + */ + public static PropertiesConfiguration getConfig() { + try { + return new PropertiesConfiguration("generator.properties"); + } catch (ConfigurationException e) { + log.error(e.getMessage(), e); + } + return null; + } +} diff --git a/wjcy-generator/src/main/java/me/zhengjie/utils/GenUtil.java b/wjcy-generator/src/main/java/me/zhengjie/utils/GenUtil.java new file mode 100644 index 0000000..566b6d8 --- /dev/null +++ b/wjcy-generator/src/main/java/me/zhengjie/utils/GenUtil.java @@ -0,0 +1,420 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.template.*; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.domain.GenConfig; +import me.zhengjie.domain.ColumnInfo; +import org.springframework.util.ObjectUtils; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.time.LocalDate; +import java.util.*; + +import static me.zhengjie.utils.FileUtil.SYS_TEM_DIR; + +/** + * 代码生成 + * + * @author Zheng Jie + * @date 2019-01-02 + */ +@Slf4j +@SuppressWarnings({"unchecked", "all"}) +public class GenUtil { + + private static final String TIMESTAMP = "Timestamp"; + + private static final String BIGDECIMAL = "BigDecimal"; + + public static final String PK = "PRI"; + + public static final String EXTRA = "auto_increment"; + + /** + * 获取后端代码模板名称 + * + * @return List + */ + private static List getAdminTemplateNames() { + List templateNames = new ArrayList<>(); + templateNames.add("Entity"); + templateNames.add("Dto"); + templateNames.add("Mapper"); + templateNames.add("Controller"); + templateNames.add("QueryCriteria"); + templateNames.add("Service"); + templateNames.add("ServiceImpl"); + templateNames.add("Repository"); + return templateNames; + } + + /** + * 获取前端代码模板名称 + * + * @return List + */ + private static List getFrontTemplateNames() { + List templateNames = new ArrayList<>(); + templateNames.add("index"); + templateNames.add("api"); + return templateNames; + } + + public static List> preview(List columns, GenConfig genConfig) { + Map genMap = getGenMap(columns, genConfig); + List> genList = new ArrayList<>(); + // 获取后端模版 + List templates = getAdminTemplateNames(); + TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH)); + for (String templateName : templates) { + Map map = new HashMap<>(1); + Template template = engine.getTemplate("generator/admin/" + templateName + ".ftl"); + map.put("content", template.render(genMap)); + map.put("name", templateName); + genList.add(map); + } + // 获取前端模版 + templates = getFrontTemplateNames(); + for (String templateName : templates) { + Map map = new HashMap<>(1); + Template template = engine.getTemplate("generator/front/" + templateName + ".ftl"); + map.put(templateName, template.render(genMap)); + map.put("content", template.render(genMap)); + map.put("name", templateName); + genList.add(map); + } + return genList; + } + + public static String download(List columns, GenConfig genConfig) throws IOException { + // 拼接的路径:/tmpeladmin-gen-temp/,这个路径在Linux下需要root用户才有权限创建,非root用户会权限错误而失败,更改为: /tmp/eladmin-gen-temp/ + // String tempPath =SYS_TEM_DIR + "eladmin-gen-temp" + File.separator + genConfig.getTableName() + File.separator; + String tempPath = SYS_TEM_DIR + "eladmin-gen-temp" + File.separator + genConfig.getTableName() + File.separator; + Map genMap = getGenMap(columns, genConfig); + TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH)); + // 生成后端代码 + List templates = getAdminTemplateNames(); + for (String templateName : templates) { + Template template = engine.getTemplate("generator/admin/" + templateName + ".ftl"); + String filePath = getAdminFilePath(templateName, genConfig, genMap.get("className").toString(), tempPath + "eladmin" + File.separator); + assert filePath != null; + File file = new File(filePath); + // 如果非覆盖生成 + if (!genConfig.getCover() && FileUtil.exist(file)) { + continue; + } + // 生成代码 + genFile(file, template, genMap); + } + // 生成前端代码 + templates = getFrontTemplateNames(); + for (String templateName : templates) { + Template template = engine.getTemplate("generator/front/" + templateName + ".ftl"); + String path = tempPath + "eladmin-web" + File.separator; + String apiPath = path + "src" + File.separator + "api" + File.separator; + String srcPath = path + "src" + File.separator + "views" + File.separator + genMap.get("changeClassName").toString() + File.separator; + String filePath = getFrontFilePath(templateName, apiPath, srcPath, genMap.get("changeClassName").toString()); + assert filePath != null; + File file = new File(filePath); + // 如果非覆盖生成 + if (!genConfig.getCover() && FileUtil.exist(file)) { + continue; + } + // 生成代码 + genFile(file, template, genMap); + } + return tempPath; + } + + public static void generatorCode(List columnInfos, GenConfig genConfig) throws IOException { + Map genMap = getGenMap(columnInfos, genConfig); + TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH)); + // 生成后端代码 + List templates = getAdminTemplateNames(); + for (String templateName : templates) { + Template template = engine.getTemplate("generator/admin/" + templateName + ".ftl"); + String rootPath = System.getProperty("user.dir"); + String filePath = getAdminFilePath(templateName, genConfig, genMap.get("className").toString(), rootPath); + + assert filePath != null; + File file = new File(filePath); + + // 如果非覆盖生成 + if (!genConfig.getCover() && FileUtil.exist(file)) { + continue; + } + // 生成代码 + genFile(file, template, genMap); + } + + // 生成前端代码 + templates = getFrontTemplateNames(); + for (String templateName : templates) { + Template template = engine.getTemplate("generator/front/" + templateName + ".ftl"); + String filePath = getFrontFilePath(templateName, genConfig.getApiPath(), genConfig.getPath(), genMap.get("changeClassName").toString()); + + assert filePath != null; + File file = new File(filePath); + + // 如果非覆盖生成 + if (!genConfig.getCover() && FileUtil.exist(file)) { + continue; + } + // 生成代码 + genFile(file, template, genMap); + } + } + + // 获取模版数据 + private static Map getGenMap(List columnInfos, GenConfig genConfig) { + // 存储模版字段数据 + Map genMap = new HashMap<>(16); + // 接口别名 + genMap.put("apiAlias", genConfig.getApiAlias()); + // 包名称 + genMap.put("package", genConfig.getPack()); + // 模块名称 + genMap.put("moduleName", genConfig.getModuleName()); + // 作者 + genMap.put("author", genConfig.getAuthor()); + // 创建日期 + genMap.put("date", LocalDate.now().toString()); + // 表名 + genMap.put("tableName", genConfig.getTableName()); + // 大写开头的类名 + String className = StringUtils.toCapitalizeCamelCase(genConfig.getTableName()); + // 小写开头的类名 + String changeClassName = StringUtils.toCamelCase(genConfig.getTableName()); + // 判断是否去除表前缀 + if (StringUtils.isNotEmpty(genConfig.getPrefix())) { + className = StringUtils.toCapitalizeCamelCase(StrUtil.removePrefix(genConfig.getTableName(), genConfig.getPrefix())); + changeClassName = StringUtils.toCamelCase(StrUtil.removePrefix(genConfig.getTableName(), genConfig.getPrefix())); + } + // 保存类名 + genMap.put("className", className); + // 保存小写开头的类名 + genMap.put("changeClassName", changeClassName); + // 存在 Timestamp 字段 + genMap.put("hasTimestamp", false); + // 查询类中存在 Timestamp 字段 + genMap.put("queryHasTimestamp", false); + // 存在 BigDecimal 字段 + genMap.put("hasBigDecimal", false); + // 查询类中存在 BigDecimal 字段 + genMap.put("queryHasBigDecimal", false); + // 是否需要创建查询 + genMap.put("hasQuery", false); + // 自增主键 + genMap.put("auto", false); + // 存在字典 + genMap.put("hasDict", false); + // 存在日期注解 + genMap.put("hasDateAnnotation", false); + // 保存字段信息 + List> columns = new ArrayList<>(); + // 保存查询字段的信息 + List> queryColumns = new ArrayList<>(); + // 存储字典信息 + List dicts = new ArrayList<>(); + // 存储 between 信息 + List> betweens = new ArrayList<>(); + // 存储不为空的字段信息 + List> isNotNullColumns = new ArrayList<>(); + + for (ColumnInfo column : columnInfos) { + Map listMap = new HashMap<>(16); + // 字段描述 + listMap.put("remark", column.getRemark()); + // 字段类型 + listMap.put("columnKey", column.getKeyType()); + // 主键类型 + String colType = ColUtil.cloToJava(column.getColumnType()); + // 小写开头的字段名 + String changeColumnName = StringUtils.toCamelCase(column.getColumnName()); + // 大写开头的字段名 + String capitalColumnName = StringUtils.toCapitalizeCamelCase(column.getColumnName()); + if (PK.equals(column.getKeyType())) { + // 存储主键类型 + genMap.put("pkColumnType", colType); + // 存储小写开头的字段名 + genMap.put("pkChangeColName", changeColumnName); + // 存储大写开头的字段名 + genMap.put("pkCapitalColName", capitalColumnName); + } + // 是否存在 Timestamp 类型的字段 + if (TIMESTAMP.equals(colType)) { + genMap.put("hasTimestamp", true); + } + // 是否存在 BigDecimal 类型的字段 + if (BIGDECIMAL.equals(colType)) { + genMap.put("hasBigDecimal", true); + } + // 主键是否自增 + if (EXTRA.equals(column.getExtra())) { + genMap.put("auto", true); + } + // 主键存在字典 + if (StringUtils.isNotBlank(column.getDictName())) { + genMap.put("hasDict", true); + dicts.add(column.getDictName()); + } + + // 存储字段类型 + listMap.put("columnType", colType); + // 存储字原始段名称 + listMap.put("columnName", column.getColumnName()); + // 不为空 + listMap.put("istNotNull", column.getNotNull()); + // 字段列表显示 + listMap.put("columnShow", column.getListShow()); + // 表单显示 + listMap.put("formShow", column.getFormShow()); + // 表单组件类型 + listMap.put("formType", StringUtils.isNotBlank(column.getFormType()) ? column.getFormType() : "Input"); + // 小写开头的字段名称 + listMap.put("changeColumnName", changeColumnName); + //大写开头的字段名称 + listMap.put("capitalColumnName", capitalColumnName); + // 字典名称 + listMap.put("dictName", column.getDictName()); + // 日期注解 + listMap.put("dateAnnotation", column.getDateAnnotation()); + if (StringUtils.isNotBlank(column.getDateAnnotation())) { + genMap.put("hasDateAnnotation", true); + } + // 添加非空字段信息 + if (column.getNotNull()) { + isNotNullColumns.add(listMap); + } + // 判断是否有查询,如有则把查询的字段set进columnQuery + if (!StringUtils.isBlank(column.getQueryType())) { + // 查询类型 + listMap.put("queryType", column.getQueryType()); + // 是否存在查询 + genMap.put("hasQuery", true); + if (TIMESTAMP.equals(colType)) { + // 查询中存储 Timestamp 类型 + genMap.put("queryHasTimestamp", true); + } + if (BIGDECIMAL.equals(colType)) { + // 查询中存储 BigDecimal 类型 + genMap.put("queryHasBigDecimal", true); + } + if ("between".equalsIgnoreCase(column.getQueryType())) { + betweens.add(listMap); + } else { + // 添加到查询列表中 + queryColumns.add(listMap); + } + } + // 添加到字段列表中 + columns.add(listMap); + } + // 保存字段列表 + genMap.put("columns", columns); + // 保存查询列表 + genMap.put("queryColumns", queryColumns); + // 保存字段列表 + genMap.put("dicts", dicts); + // 保存查询列表 + genMap.put("betweens", betweens); + // 保存非空字段信息 + genMap.put("isNotNullColumns", isNotNullColumns); + return genMap; + } + + /** + * 定义后端文件路径以及名称 + */ + private static String getAdminFilePath(String templateName, GenConfig genConfig, String className, String rootPath) { + String projectPath = rootPath + File.separator + genConfig.getModuleName(); + String packagePath = projectPath + File.separator + "src" + File.separator + "main" + File.separator + "java" + File.separator; + if (!ObjectUtils.isEmpty(genConfig.getPack())) { + packagePath += genConfig.getPack().replace(".", File.separator) + File.separator; + } + + if ("Entity".equals(templateName)) { + return packagePath + "domain" + File.separator + className + ".java"; + } + + if ("Controller".equals(templateName)) { + return packagePath + "rest" + File.separator + className + "Controller.java"; + } + + if ("Service".equals(templateName)) { + return packagePath + "service" + File.separator + className + "Service.java"; + } + + if ("ServiceImpl".equals(templateName)) { + return packagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java"; + } + + if ("Dto".equals(templateName)) { + return packagePath + "service" + File.separator + "dto" + File.separator + className + "Dto.java"; + } + + if ("QueryCriteria".equals(templateName)) { + return packagePath + "service" + File.separator + "dto" + File.separator + className + "QueryCriteria.java"; + } + + if ("Mapper".equals(templateName)) { + return packagePath + "service" + File.separator + "mapstruct" + File.separator + className + "Mapper.java"; + } + + if ("Repository".equals(templateName)) { + return packagePath + "repository" + File.separator + className + "Repository.java"; + } + + return null; + } + + /** + * 定义前端文件路径以及名称 + */ + private static String getFrontFilePath(String templateName, String apiPath, String path, String apiName) { + + if ("api".equals(templateName)) { + return apiPath + File.separator + apiName + ".js"; + } + + if ("index".equals(templateName)) { + return path + File.separator + "index.vue"; + } + + return null; + } + + private static void genFile(File file, Template template, Map map) throws IOException { + // 生成目标文件 + Writer writer = null; + try { + FileUtil.touch(file); + writer = new FileWriter(file); + template.render(map, writer); + } catch (TemplateException | IOException e) { + throw new RuntimeException(e); + } finally { + assert writer != null; + writer.close(); + } + } +} diff --git a/wjcy-logging/pom.xml b/wjcy-logging/pom.xml new file mode 100644 index 0000000..98d6734 --- /dev/null +++ b/wjcy-logging/pom.xml @@ -0,0 +1,22 @@ + + + + wjcy + me.zhengjie + 1.0 + + 4.0.0 + + wjcy-logging + 日志模块 + + + + me.zhengjie + wjcy-common + 1.0 + + + \ No newline at end of file diff --git a/wjcy-logging/src/main/java/me/zhengjie/annotation/Log.java b/wjcy-logging/src/main/java/me/zhengjie/annotation/Log.java new file mode 100644 index 0000000..ac0a0cd --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/annotation/Log.java @@ -0,0 +1,55 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.annotation; + +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.annotation.type.LogDaoType; +import me.zhengjie.annotation.type.LogGetIdType; +import me.zhengjie.annotation.type.LogGetValueType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author Zheng Jie + * @date 2018-11-24 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Log { + String value() default ""; + + String[] daoNames() default {}; + + LogGetIdType[] idTypes() default {LogGetIdType.ID}; + + LogGetValueType[] valuesTypes() default {LogGetValueType.ID}; + + LogDaoType daoType() default LogDaoType.MyBATISPLUS; + + boolean trueList() default false; + + /** + * 是否启用 + * + * @return + */ + boolean enable() default true; + + LogActionType type() default LogActionType.SELECT; +} diff --git a/wjcy-logging/src/main/java/me/zhengjie/annotation/type/LogActionType.java b/wjcy-logging/src/main/java/me/zhengjie/annotation/type/LogActionType.java new file mode 100644 index 0000000..e99d671 --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/annotation/type/LogActionType.java @@ -0,0 +1,34 @@ +package me.zhengjie.annotation.type; + +/** + *

+ * 日志类型 + *

+ * + * @Author xx + * @Date 2021/7/22 + **/ +public enum LogActionType { + /** + * 增删改查 + */ + ADD("新增"), + SELECT("查询"), + UPDATE("更新"), + DELETE("删除"), + LOGIN("登录"), + EXPORT("导出"); + private String value; + + LogActionType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/wjcy-logging/src/main/java/me/zhengjie/annotation/type/LogDaoType.java b/wjcy-logging/src/main/java/me/zhengjie/annotation/type/LogDaoType.java new file mode 100644 index 0000000..2c96f80 --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/annotation/type/LogDaoType.java @@ -0,0 +1,30 @@ +package me.zhengjie.annotation.type; + +/** + *

+ *日志使用dao类型 + *

+ * + * @Author xx + * @Date 2021/7/22 + **/ +public enum LogDaoType { + /** + * 增删改查 + */ + MyBATISPLUS("myabtisPlus"), + SPRINGDATAJPA("springDataJpa"); + private String value; + + LogDaoType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/wjcy-logging/src/main/java/me/zhengjie/annotation/type/LogGetIdType.java b/wjcy-logging/src/main/java/me/zhengjie/annotation/type/LogGetIdType.java new file mode 100644 index 0000000..cb4a005 --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/annotation/type/LogGetIdType.java @@ -0,0 +1,36 @@ +package me.zhengjie.annotation.type; + +/** + *

+ * 日志获取修改前信息使用id类型 具体有别的在具体添加 + *

+ * + * @Author xx + * @Date 2021/7/22 + **/ +public enum LogGetIdType { + + /** ID */ + ID("id"), + /** IDS */ + IDS("ids"), + /** MEMBER_ID */ + MEMBER_ID("memberId"), + /** AUTHMEMBER_ID */ + AUTHMEMBER_ID("authMemberId"), + /** ROOM_Id */ + ROOM_Id("roomId"); + private String value; + + LogGetIdType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/wjcy-logging/src/main/java/me/zhengjie/annotation/type/LogGetValueType.java b/wjcy-logging/src/main/java/me/zhengjie/annotation/type/LogGetValueType.java new file mode 100644 index 0000000..1024cbb --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/annotation/type/LogGetValueType.java @@ -0,0 +1,32 @@ +package me.zhengjie.annotation.type; + +/** + *

+ * 日志获取修改前信息使用id对应值 具体有别的在具体添加 + *

+ * + * @Author xx + * @Date 2021/7/22 + **/ +public enum LogGetValueType { + + /** ID */ + ID("id"), + /** MEMBER_ID */ + MEMBER_ID("memberId"), + /** ROOM_ID */ + ROOM_ID("roomId"); + private String value; + + LogGetValueType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/wjcy-logging/src/main/java/me/zhengjie/aspect/LogAspect.java b/wjcy-logging/src/main/java/me/zhengjie/aspect/LogAspect.java new file mode 100644 index 0000000..01bce24 --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/aspect/LogAspect.java @@ -0,0 +1,98 @@ +///* +// * Copyright 2019-2020 Zheng Jie +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +//package me.zhengjie.aspect; +// +//import lombok.extern.slf4j.Slf4j; +//import me.zhengjie.domain.Log; +//import me.zhengjie.service.LogService; +//import me.zhengjie.utils.RequestHolder; +//import me.zhengjie.utils.SecurityUtils; +//import me.zhengjie.utils.StringUtils; +//import me.zhengjie.utils.ThrowableUtil; +//import org.aspectj.lang.JoinPoint; +//import org.aspectj.lang.ProceedingJoinPoint; +//import org.aspectj.lang.annotation.AfterThrowing; +//import org.aspectj.lang.annotation.Around; +//import org.aspectj.lang.annotation.Aspect; +//import org.aspectj.lang.annotation.Pointcut; +//import org.springframework.stereotype.Component; +//import javax.servlet.http.HttpServletRequest; +// +///** +// * @author Zheng Jie +// * @date 2018-11-24 +// */ +//@Component +//@Aspect +//@Slf4j +//public class LogAspect { +// +// private final LogService logService; +// +// ThreadLocal currentTime = new ThreadLocal<>(); +// +// public LogAspect(LogService logService) { +// this.logService = logService; +// } +// +// /** +// * 配置切入点 +// */ +// @Pointcut("@annotation(me.zhengjie.annotation.Log)") +// public void logPointcut() { +// // 该方法无方法体,主要为了让同类中其他方法使用此切入点 +// } +// +// /** +// * 配置环绕通知,使用在方法logPointcut()上注册的切入点 +// * +// * @param joinPoint join point for advice +// */ +// @Around("logPointcut()") +// public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { +// Object result; +// currentTime.set(System.currentTimeMillis()); +// result = joinPoint.proceed(); +// Log log = new Log("INFO",System.currentTimeMillis() - currentTime.get()); +// currentTime.remove(); +// HttpServletRequest request = RequestHolder.getHttpServletRequest(); +// logService.save(getUsername(), StringUtils.getBrowser(request), StringUtils.getIp(request),joinPoint, log); +// return result; +// } +// +// /** +// * 配置异常通知 +// * +// * @param joinPoint join point for advice +// * @param e exception +// */ +// @AfterThrowing(pointcut = "logPointcut()", throwing = "e") +// public void logAfterThrowing(JoinPoint joinPoint, Throwable e) { +// Log log = new Log("ERROR",System.currentTimeMillis() - currentTime.get()); +// currentTime.remove(); +// log.setExceptionDetail(ThrowableUtil.getStackTrace(e).getBytes()); +// HttpServletRequest request = RequestHolder.getHttpServletRequest(); +// logService.save(getUsername(), StringUtils.getBrowser(request), StringUtils.getIp(request), (ProceedingJoinPoint)joinPoint, log); +// } +// +// public String getUsername() { +// try { +// return SecurityUtils.getCurrentUsername(); +// }catch (Exception e){ +// return ""; +// } +// } +//} diff --git a/wjcy-logging/src/main/java/me/zhengjie/domain/Log.java b/wjcy-logging/src/main/java/me/zhengjie/domain/Log.java new file mode 100644 index 0000000..baed7df --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/domain/Log.java @@ -0,0 +1,95 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.domain; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.annotations.CreationTimestamp; +import javax.persistence.*; +import java.io.Serializable; +import java.sql.Timestamp; + + +/** + * @author Zheng Jie + * @date 2018-11-24 + */ +@Entity +@Getter +@Setter +@Table(name = "sys_log") +@NoArgsConstructor +public class Log implements Serializable { + + @Id + @Column(name = "log_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** 操作用户 */ + private String username; + + /** 描述 */ + private String description; + + /** 方法名 */ + private String method; + + /** 参数 */ + private String params; + + /** 日志类型 */ + private String logType; + + /** 请求ip */ + private String requestIp; + + /** 地址 */ + private String address; + + /** 浏览器 */ + private String browser; + + /** 请求耗时 */ + private Long time; + + /** 异常详细 */ + private String exceptionDetail; + + /** 创建日期 */ + @CreationTimestamp + private Timestamp createTime; + + /** 用户类型 */ + private Integer type; + + /** 日志记录 */ + private String platParams; + + @Transient + private Boolean trueList; + + public Log(String logType, Long time) { + this.logType = logType; + this.time = time; + } + public Log(String logType, Long time, Integer type) { + this.logType = logType; + this.time = time; + this.type = type; + } +} diff --git a/wjcy-logging/src/main/java/me/zhengjie/enums/LogTypeEnum.java b/wjcy-logging/src/main/java/me/zhengjie/enums/LogTypeEnum.java new file mode 100644 index 0000000..eb87f89 --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/enums/LogTypeEnum.java @@ -0,0 +1,33 @@ +package me.zhengjie.enums; +/** + *

+ * 日志类型 + *

+ * + * @Author xx + * @Date 2021/7/22 + **/ +public enum LogTypeEnum { + /** + * 是否展示详情类型 + * 1 修改 + * 0 不展示 + * 2 新增 + */ + + NO_PLAT_PARAMS(0), + SHOW_PLAT_PARAMS(1), + SHOW_ADD_PARAMS(2), + SHOW_LOGIN_PARAMS(3); + + private final Integer value; + + private LogTypeEnum(Integer value) { + this.value = value; + } + + + public Integer value() { + return this.value; + } +} diff --git a/wjcy-logging/src/main/java/me/zhengjie/repository/LogRepository.java b/wjcy-logging/src/main/java/me/zhengjie/repository/LogRepository.java new file mode 100644 index 0000000..0414b3e --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/repository/LogRepository.java @@ -0,0 +1,49 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.repository; + +import me.zhengjie.domain.Log; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * @author Zheng Jie + * @date 2018-11-24 + */ +@Repository +public interface LogRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据日志类型删除信息 + * @param logType 日志类型 + */ + @Modifying + @Query(value = "delete from sys_log where log_type = ?1", nativeQuery = true) + void deleteByLogType(String logType); + + /** + * 根据日志类型和显示类型删除信息 + * @param logType 日志类型 + */ + @Modifying + @Query(value = " delete from sys_log where log_type = ?1 and type in ?2",nativeQuery = true) + void deleteByLogTypeAndTypeContains(String logType, List typeList); +} diff --git a/wjcy-logging/src/main/java/me/zhengjie/rest/LogController.java b/wjcy-logging/src/main/java/me/zhengjie/rest/LogController.java new file mode 100644 index 0000000..23d27db --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/rest/LogController.java @@ -0,0 +1,157 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.dto.Dto; +import me.zhengjie.enums.LogTypeEnum; +import me.zhengjie.service.LogService; +import me.zhengjie.service.dto.LogQueryCriteria; +import me.zhengjie.utils.SecurityUtils; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Arrays; + +/** + * @author Zheng Jie + * @date 2018-11-24 + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/logs") +@Api(tags = "系统:日志管理") +public class LogController { + + private final LogService logService; + + @Log("导出操作日志数据") + @ApiOperation("导出操作日志数据") + @GetMapping(value = "/queryLog/download") + @PreAuthorize("@el.check('options:export')") + public void downloadLog(HttpServletResponse response, LogQueryCriteria criteria) throws IOException { + criteria.setLogType("INFO"); + criteria.setType(Arrays.asList(LogTypeEnum.SHOW_ADD_PARAMS.value(), LogTypeEnum.SHOW_PLAT_PARAMS.value(), LogTypeEnum.NO_PLAT_PARAMS.value())); + logService.download(logService.queryAll(criteria), response); + } + + @Log("导出登录日志数据") + @ApiOperation("导出登录日志数据") + @GetMapping(value = "/queryLogin/download") + @PreAuthorize("@el.check('login:export')") + public void downloadLogin(HttpServletResponse response, LogQueryCriteria criteria) throws IOException { + criteria.setLogType("INFO"); + criteria.setType(Arrays.asList(LogTypeEnum.SHOW_LOGIN_PARAMS.value())); + logService.download(logService.queryAll(criteria), response); + } + + @Log("导出错误数据") + @ApiOperation("导出错误数据") + @GetMapping(value = "/error/download") +// @PreAuthorize("@el.check()") + public void downloadErrorLog(HttpServletResponse response, LogQueryCriteria criteria) throws IOException { + criteria.setLogType("ERROR"); + logService.download(logService.queryAll(criteria), response); + } + + @GetMapping(value = "/queryLog") + @ApiOperation("日志查询") + @PreAuthorize("@el.check('options:list')") + public ResponseEntity queryLog(LogQueryCriteria criteria, Pageable pageable){ + criteria.setLogType("INFO"); + criteria.setType(Arrays.asList(LogTypeEnum.SHOW_ADD_PARAMS.value(), LogTypeEnum.SHOW_PLAT_PARAMS.value(), LogTypeEnum.NO_PLAT_PARAMS.value())); + return new ResponseEntity<>(logService.queryAll(criteria,pageable), HttpStatus.OK); + } + + @GetMapping(value = "/queryLogin") + @ApiOperation("日志查询") + @PreAuthorize("@el.check('login:list')") + public ResponseEntity queryLogin(LogQueryCriteria criteria, Pageable pageable){ + criteria.setLogType("INFO"); + criteria.setType(Arrays.asList(LogTypeEnum.SHOW_LOGIN_PARAMS.value())); + return new ResponseEntity<>(logService.queryAll(criteria,pageable), HttpStatus.OK); + } + + /** + * 根据id 修改前后日志变化详情 + * @param id + * @return + */ + @GetMapping(value = "/updateDetail/{id}") + @ApiOperation("日志查询") +// @PreAuthorize("@el.check()") + public Dto updateDetail(@PathVariable Long id){ + return Dto.returnResult(logService.queryUpdateDatail(id)); + } + + + + @GetMapping(value = "/user") + @ApiOperation("用户日志查询") + public ResponseEntity queryUserLog(LogQueryCriteria criteria, Pageable pageable){ + criteria.setLogType("INFO"); + criteria.setBlurry(SecurityUtils.getCurrentUsername()); + return new ResponseEntity<>(logService.queryAllByUser(criteria,pageable), HttpStatus.OK); + } + + @GetMapping(value = "/error") + @ApiOperation("错误日志查询") +// @PreAuthorize("@el.check()") + public ResponseEntity queryErrorLog(LogQueryCriteria criteria, Pageable pageable){ + criteria.setLogType("ERROR"); + return new ResponseEntity<>(logService.queryAll(criteria,pageable), HttpStatus.OK); + } + + @GetMapping(value = "/error/{id}") + @ApiOperation("日志异常详情查询") +// @PreAuthorize("@el.check()") + public ResponseEntity queryErrorLogs(@PathVariable Long id){ + return new ResponseEntity<>(logService.findByErrDetail(id), HttpStatus.OK); + } + @DeleteMapping(value = "/del/error") + @Log("删除所有ERROR日志") + @ApiOperation("删除所有ERROR日志") +// @PreAuthorize("@el.check()") + public ResponseEntity delAllErrorLog(){ + logService.delAllByError(); + return new ResponseEntity<>(HttpStatus.OK); + } + + @DeleteMapping(value = "/del/logInfo") + @Log("删除所有INFO操作日志") + @ApiOperation("删除所有INFO操作日志") + @PreAuthorize("@el.check('options:del')") + public ResponseEntity delAllLogInfo(){ + logService.deleteByLogTypeAndType("INFO", Arrays.asList(LogTypeEnum.SHOW_ADD_PARAMS.value(), LogTypeEnum.NO_PLAT_PARAMS.value(), LogTypeEnum.SHOW_PLAT_PARAMS.value())); + return new ResponseEntity<>(HttpStatus.OK); + } + + @DeleteMapping(value = "/del/loginInfo") + @Log("删除所有INFO登录日志") + @ApiOperation("删除所有INFO登录日志") + @PreAuthorize("@el.check('login:del')") + public ResponseEntity delAllLoginInfo(){ + logService.deleteByLogTypeAndType("INFO", Arrays.asList(LogTypeEnum.SHOW_LOGIN_PARAMS.value())); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/wjcy-logging/src/main/java/me/zhengjie/service/LogService.java b/wjcy-logging/src/main/java/me/zhengjie/service/LogService.java new file mode 100644 index 0000000..0dc6497 --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/service/LogService.java @@ -0,0 +1,101 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service; + +import me.zhengjie.domain.Log; +import me.zhengjie.service.dto.LogQueryCriteria; +import org.aspectj.lang.ProceedingJoinPoint; +import org.springframework.data.domain.Pageable; +import org.springframework.scheduling.annotation.Async; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** + * @author Zheng Jie + * @date 2018-11-24 + */ +public interface LogService { + + /** + * 分页查询 + * @param criteria 查询条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(LogQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部数据 + * @param criteria 查询条件 + * @return / + */ + List queryAll(LogQueryCriteria criteria); + + /** + * 查询修改数据详情 + * @param id 查询条件 + * @return / + */ + Object queryUpdateDatail(Long id); + + /** + * 查询用户日志 + * @param criteria 查询条件 + * @param pageable 分页参数 + * @return - + */ + Object queryAllByUser(LogQueryCriteria criteria, Pageable pageable); + + /** + * 保存日志数据 + * @param username 用户 + * @param browser 浏览器 + * @param ip 请求IP + * @param joinPoint / + * @param log 日志实体 + */ + @Async + void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log, Object beforeJson); + + /** + * 查询异常详情 + * @param id 日志ID + * @return Object + */ + Object findByErrDetail(Long id); + + /** + * 导出日志 + * @param logs 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List logs, HttpServletResponse response) throws IOException; + + /** + * 删除所有错误日志 + */ + void delAllByError(); + + /** + * 删除所有INFO日志 + */ + void delAllByInfo(); + + void deleteByLogTypeAndType(String logType, List typeList); +} diff --git a/wjcy-logging/src/main/java/me/zhengjie/service/dto/LogErrorDTO.java b/wjcy-logging/src/main/java/me/zhengjie/service/dto/LogErrorDTO.java new file mode 100644 index 0000000..bc0d4ec --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/service/dto/LogErrorDTO.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.dto; + +import lombok.Data; +import java.io.Serializable; +import java.sql.Timestamp; + +/** +* @author Zheng Jie +* @date 2019-5-22 +*/ +@Data +public class LogErrorDTO implements Serializable { + + private Long id; + + private String username; + + private String description; + + private String method; + + private String params; + + private String browser; + + private String requestIp; + + private String address; + + private Timestamp createTime; +} \ No newline at end of file diff --git a/wjcy-logging/src/main/java/me/zhengjie/service/dto/LogQueryCriteria.java b/wjcy-logging/src/main/java/me/zhengjie/service/dto/LogQueryCriteria.java new file mode 100644 index 0000000..dcc41f6 --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/service/dto/LogQueryCriteria.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** + * 日志查询类 + * @author Zheng Jie + * @date 2019-6-4 09:23:07 + */ +@Data +public class LogQueryCriteria { + + @Query(blurry = "username,description,address,requestIp,method,params") + private String blurry; + + @Query + private String logType; + + @Query(type = Query.Type.IN) + private List type; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/wjcy-logging/src/main/java/me/zhengjie/service/dto/LogSmallDTO.java b/wjcy-logging/src/main/java/me/zhengjie/service/dto/LogSmallDTO.java new file mode 100644 index 0000000..d074fd1 --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/service/dto/LogSmallDTO.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.dto; + +import lombok.Data; +import java.io.Serializable; +import java.sql.Timestamp; + +/** + * @author Zheng Jie + * @date 2019-5-22 + */ +@Data +public class LogSmallDTO implements Serializable { + + private String description; + + private String requestIp; + + private Long time; + + private String address; + + private String browser; + + private Timestamp createTime; +} diff --git a/wjcy-logging/src/main/java/me/zhengjie/service/impl/LogServiceImpl.java b/wjcy-logging/src/main/java/me/zhengjie/service/impl/LogServiceImpl.java new file mode 100644 index 0000000..2b96dca --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/service/impl/LogServiceImpl.java @@ -0,0 +1,232 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.impl; + +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import lombok.RequiredArgsConstructor; +import me.zhengjie.domain.Log; +import me.zhengjie.enums.LogTypeEnum; +import me.zhengjie.repository.LogRepository; +import me.zhengjie.service.LogService; +import me.zhengjie.service.dto.LogQueryCriteria; +import me.zhengjie.service.mapstruct.LogErrorMapper; +import me.zhengjie.service.mapstruct.LogSmallMapper; +import me.zhengjie.utils.*; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.*; + +/** + * @author Zheng Jie + * @date 2018-11-24 + */ +@Service +@RequiredArgsConstructor +public class LogServiceImpl implements LogService { + private static final Logger log = LoggerFactory.getLogger(LogServiceImpl.class); + private final LogRepository logRepository; + private final LogErrorMapper logErrorMapper; + private final LogSmallMapper logSmallMapper; + + + @Override + public Object queryAll(LogQueryCriteria criteria, Pageable pageable) { + Page page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable); + String status = "ERROR"; + if (status.equals(criteria.getLogType())) { + return PageUtil.toPage(page.map(logErrorMapper::toDto)); + } + return page; + } + + @Override + public List queryAll(LogQueryCriteria criteria) { + return logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb))); + } + + @Override + public Object queryUpdateDatail(Long id) { + Log log = logRepository.findById(id).orElseGet(Log::new); + ValidationUtil.isNull(log.getId(), "Log", "id", id); + String details = log.getPlatParams(); + return Dict.create().set("platParams", new String(ObjectUtil.isNotNull(details) ? details : "")); + } + + @Override + public Object queryAllByUser(LogQueryCriteria criteria, Pageable pageable) { + Page page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable); + return PageUtil.toPage(page.map(logSmallMapper::toDto)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log, Object beforeJson) { + + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + me.zhengjie.annotation.Log aopLog = method.getAnnotation(me.zhengjie.annotation.Log.class); + + // 方法路径 + String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()"; + + //参数值 + List argValues = new ArrayList<>(Arrays.asList(joinPoint.getArgs())); + + // 修改前的数据整理,仅仅只存储变化的数据即可 + StringBuilder params = new StringBuilder("[ "); + JSONArray jsonArray = new JSONArray(); + boolean showBoolean = false; + if (ObjectUtil.isNotEmpty(beforeJson) && LogTypeEnum.SHOW_PLAT_PARAMS.value().equals(log.getType())) { + jsonArray.add(jsonUnion(argValues.get(0), beforeJson)); + } + + if (LogTypeEnum.SHOW_PLAT_PARAMS.value().equals(log.getType()) || LogTypeEnum.SHOW_ADD_PARAMS.value().equals(log.getType())) { + showBoolean = true; + } + + //参数名称 + for (Object argValue : argValues) { + if (ObjectUtil.isNotEmpty(argValue)) { + params.append(EmptyAttributeFiler.emptyAttributeFilerToString(argValue)).append(" "); + if (showBoolean) { + if (log.getTrueList()) { + jsonArray = new JSONArray(argValue); + } else { + JSONObject tempBefJsonObj = new JSONObject(argValue); + jsonArray.add(tempBefJsonObj); + } + } + } + } + + // 描述 + if (log != null && ObjectUtil.isEmpty(log.getDescription())) { + log.setDescription(aopLog.value()); + } + assert log != null; + log.setRequestIp(ip); + + String loginPath = "login"; + if (loginPath.equals(signature.getName())) { + try { + username = new JSONObject(argValues.get(0)).get("username").toString(); + } catch (Exception e) { + LogServiceImpl.log.error(e.getMessage(), e); + } + } + log.setAddress(StringUtils.getLocalCityInfo(log.getRequestIp())); + log.setMethod(methodName); + log.setUsername(username); + log.setParams(params.toString() + " ]"); + if (showBoolean) { + log.setPlatParams(jsonArray.toString()); + } + log.setBrowser(browser); + logRepository.save(log); + } + + /** + * 赋值资源 + * 根据source中的key除吊target中多余的数据。 + * 使target数据结构保持和source一致 + * @param source + * @param target + * @return + */ + public JSONObject jsonUnion(Object source, Object target) { + + JSONObject targetObj = new JSONObject(target); + JSONObject sourceObj = new JSONObject(source); + + + Map objMap = new LinkedHashMap<>(); + + if (ObjectUtil.isNotEmpty(sourceObj)) { + for (Map.Entry sourceEntry: sourceObj.entrySet()) { + String key = sourceEntry.getKey(); + Object value = sourceEntry.getValue(); + + // 判断是否存在key + if (targetObj.containsKey(key)) { + objMap.put(key, targetObj.get(key)); + } + } + } + + return new JSONObject(objMap); + } + + @Override + public Object findByErrDetail(Long id) { + Log log = logRepository.findById(id).orElseGet(Log::new); + ValidationUtil.isNull(log.getId(), "Log", "id", id); + String details = log.getExceptionDetail(); + return Dict.create().set("exception", new String(ObjectUtil.isNotNull(details) ? details : "")); + } + + @Override + public void download(List logs, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (Log log : logs) { + Map map = new LinkedHashMap<>(); + map.put("用户名", log.getUsername()); + map.put("IP", log.getRequestIp()); + map.put("IP来源", log.getAddress()); + map.put("描述", log.getDescription()); + map.put("浏览器", log.getBrowser()); + map.put("请求耗时/毫秒", log.getTime()); + map.put("异常详情", new String(ObjectUtil.isNotNull(log.getExceptionDetail()) ? log.getExceptionDetail() : "")); + map.put("创建日期", log.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delAllByError() { + logRepository.deleteByLogType("ERROR"); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delAllByInfo() { + logRepository.deleteByLogType("INFO"); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteByLogTypeAndType(String logType, List typeList) { + logRepository.deleteByLogTypeAndTypeContains(logType, typeList); + } +} diff --git a/wjcy-logging/src/main/java/me/zhengjie/service/mapstruct/LogErrorMapper.java b/wjcy-logging/src/main/java/me/zhengjie/service/mapstruct/LogErrorMapper.java new file mode 100644 index 0000000..3ae02c9 --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/service/mapstruct/LogErrorMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.domain.Log; +import me.zhengjie.service.dto.LogErrorDTO; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Zheng Jie + * @date 2019-5-22 + */ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface LogErrorMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/wjcy-logging/src/main/java/me/zhengjie/service/mapstruct/LogSmallMapper.java b/wjcy-logging/src/main/java/me/zhengjie/service/mapstruct/LogSmallMapper.java new file mode 100644 index 0000000..9f2972a --- /dev/null +++ b/wjcy-logging/src/main/java/me/zhengjie/service/mapstruct/LogSmallMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.domain.Log; +import me.zhengjie.service.dto.LogSmallDTO; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Zheng Jie + * @date 2019-5-22 + */ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface LogSmallMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/wjcy-system/pom.xml b/wjcy-system/pom.xml new file mode 100644 index 0000000..0998697 --- /dev/null +++ b/wjcy-system/pom.xml @@ -0,0 +1,128 @@ + + + + wjcy + me.zhengjie + 1.0 + + 4.0.0 + jar + wjcy-system + 核心模块 + + + 0.11.1 + + 5.8.0 + + + + + + me.zhengjie + wjcy-generator + 1.0 + + + me.zhengjie + wjcy-common + + + + + + + me.zhengjie + wjcy-tools + 1.0 + + + + + org.springframework.boot + spring-boot-starter-websocket + + + + + io.jsonwebtoken + jjwt-api + ${jjwt.version} + + + io.jsonwebtoken + jjwt-impl + ${jjwt.version} + + + io.jsonwebtoken + jjwt-jackson + ${jjwt.version} + + + + + ch.ethz.ganymed + ganymed-ssh2 + build210 + + + com.jcraft + jsch + 0.1.55 + + + + + com.github.oshi + oshi-core + 5.7.1 + + + + + org.quartz-scheduler + quartz + + + + + org.apache.rocketmq + rocketmq-client + 4.4.0 + + + + + + + + src/main/resources + + **/*.* + + + **/*.db + + true + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + diff --git a/wjcy-system/src/main/java/me/zhengjie/AppRun.java b/wjcy-system/src/main/java/me/zhengjie/AppRun.java new file mode 100644 index 0000000..ed24406 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/AppRun.java @@ -0,0 +1,70 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie; + +import io.swagger.annotations.Api; +import me.zhengjie.annotation.rest.AnonymousGetMapping; +import me.zhengjie.utils.SpringContextHolder; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.transaction.annotation.EnableTransactionManagement; +import org.springframework.web.bind.annotation.RestController; + +/** + * 开启审计功能 -> @EnableJpaAuditing + * + * @author Zheng Jie + * @date 2018/11/15 9:20:19 + */ +@EnableAsync +@RestController +@Api(hidden = true) +@SpringBootApplication +@EnableTransactionManagement +@EnableJpaAuditing(auditorAwareRef = "auditorAware") +public class AppRun { + + public static void main(String[] args) { + SpringApplication.run(AppRun.class, args); + } + + @Bean + public SpringContextHolder springContextHolder() { + return new SpringContextHolder(); + } + + @Bean + public ServletWebServerFactory webServerFactory() { + TomcatServletWebServerFactory fa = new TomcatServletWebServerFactory(); + fa.addConnectorCustomizers(connector -> connector.setProperty("relaxedQueryChars", "[]{}")); + return fa; + } + + /** + * 访问首页提示 + * + * @return / + */ + @AnonymousGetMapping("/") + public String index() { + return "Backend service started successfully"; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/aspect/FormSubmissionAspect.java b/wjcy-system/src/main/java/me/zhengjie/aspect/FormSubmissionAspect.java new file mode 100644 index 0000000..e1cfec0 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/aspect/FormSubmissionAspect.java @@ -0,0 +1,93 @@ +package me.zhengjie.aspect; + +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.FormSubmission; +import me.zhengjie.dto.Dto; +import me.zhengjie.modules.security.config.bean.SecurityProperties; +import me.zhengjie.utils.RedisUtils; +import me.zhengjie.utils.RequestHolder; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +import static me.zhengjie.config.constant.Constants.FORM_SUB_TOKEN; +import static me.zhengjie.error.ErrorCodeEnum.FORM_SUBMISSION_REPETITION_ERROR; + +/** + *

+ * 表单提交 切面 + *

+ * + * @author: rch + * @since: 2022-08-30 + */ +@Component +@Aspect +@Slf4j +public class FormSubmissionAspect { + @Resource + private RedisUtils redisUtils; + @Resource + private SecurityProperties securityProperties; + + /** + * 配置切入点 + */ + @Pointcut("@annotation(me.zhengjie.annotation.FormSubmission)") + public void formSubMissionAspectPointcut() { + } + + /** 配置环绕通知,formSubMissionAspectPointcut()上注册的切入点 */ + @Around("formSubMissionAspectPointcut()") + public Object formSubMissionAspectAround(ProceedingJoinPoint joinPoint) throws Throwable { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method signatureMethod = signature.getMethod(); + FormSubmission formSubMission = signatureMethod.getAnnotation(FormSubmission.class); + HttpServletRequest request = RequestHolder.getHttpServletRequest(); + String uri = request.getRequestURI(); + String token = request.getHeader(securityProperties.getHeader()); +// Object[] args = joinPoint.getArgs(); // 参数值 + if (formSubMission.isOpen() && ObjectUtil.isNotEmpty(token)) { + +// String key = FORM_SUB_TOKEN + uri + args.toString(); + String key = FORM_SUB_TOKEN + uri; + Long count = redisUtils.incrAndExpire(key, formSubMission.second()); + /** 设置成功count=1 */ + if (count == null || count > 1) { + return Dto.getInstance(FORM_SUBMISSION_REPETITION_ERROR); + } + } + return joinPoint.proceed(); + } + + /** 配置异常通知 */ + @AfterThrowing(pointcut = "formSubMissionAspectPointcut()", throwing = "e") + public void formSubMissionAspectAfterThrowing(JoinPoint joinPoint, Exception e) { + HttpServletRequest request = RequestHolder.getHttpServletRequest(); + String uri = request.getRequestURI(); + // 接口请求的参数 + Object[] args = joinPoint.getArgs(); + // 记录报错信息 + log.error("表单重复提交验证报错,请求的接口地址:{},请求参数:{}",uri,args); + } + + + private Map transitionToMap(Object object) { + if (ObjectUtil.isNotNull(object) && object instanceof Map){ + return (Map) object; + } + return new HashMap(16); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/config/ConfigurerAdapter.java b/wjcy-system/src/main/java/me/zhengjie/config/ConfigurerAdapter.java new file mode 100644 index 0000000..e76512b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/config/ConfigurerAdapter.java @@ -0,0 +1,88 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.config; + +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +/** + * WebMvcConfigurer + * + * @author Zheng Jie + * @date 2018-11-30 + */ +@Configuration +@EnableWebMvc +public class ConfigurerAdapter implements WebMvcConfigurer { + + /** 文件配置 */ + private final FileProperties properties; + + public ConfigurerAdapter(FileProperties properties) { + this.properties = properties; + } + + @Bean + public CorsFilter corsFilter() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + config.addAllowedOrigin("*"); + config.addAllowedHeader("*"); + config.addAllowedMethod("*"); + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + FileProperties.ElPath path = properties.getPath(); + String avatarUtl = "file:" + path.getAvatar().replace("\\","/"); + String pathUtl = "file:" + path.getPath().replace("\\","/"); + registry.addResourceHandler("/avatar/**").addResourceLocations(avatarUtl).setCachePeriod(0); + registry.addResourceHandler("/file/**").addResourceLocations(pathUtl).setCachePeriod(0); + registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/").setCachePeriod(0); + } + + @Override + public void configureMessageConverters(List> converters) { + // 使用 fastjson 序列化,会导致 @JsonIgnore 失效,可以使用 @JSONField(serialize = false) 替换 + FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); + List supportMediaTypeList = new ArrayList<>(); + supportMediaTypeList.add(MediaType.APPLICATION_JSON_UTF8); + FastJsonConfig config = new FastJsonConfig(); + config.setDateFormat("yyyy-MM-dd HH:mm:ss"); + config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect); + converter.setFastJsonConfig(config); + converter.setSupportedMediaTypes(supportMediaTypeList); + converter.setDefaultCharset(StandardCharsets.UTF_8); + converters.add(converter); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/config/CorsConfig.java b/wjcy-system/src/main/java/me/zhengjie/config/CorsConfig.java new file mode 100644 index 0000000..3cd3209 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/config/CorsConfig.java @@ -0,0 +1,20 @@ +package me.zhengjie.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +/** + *

+ * 跨域配置 + *

+ * + * @Author xx + * @Date 2021/7/28 + **/ +@Configuration +public class CorsConfig implements WebMvcConfigurer { + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new CorsInterceptor()).addPathPatterns("/**"); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/config/GoogleAuthProperties.java b/wjcy-system/src/main/java/me/zhengjie/config/GoogleAuthProperties.java new file mode 100644 index 0000000..bd5fcd0 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/config/GoogleAuthProperties.java @@ -0,0 +1,58 @@ +package me.zhengjie.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +/** + * Google Auth Properties + * @author rch + * @date 2020-08-25 + */ +@Component +@Configuration +public class GoogleAuthProperties { + + public static int SECRET_SIZE; + + public static String SEED; + + public static String RANDOM_NUMBER_ALGORITHM; + + public static String REDIS_GOOGLE_AUTH_KEY; + + public static String QR_CREATE_PREFIX_URL; + + /** default 3 - max 17 (from google docs)最多可偏移的时间*/ + public static int WINDOW_SIZE; + + @Value("${auth.secret_size}") + public void setSecretSize(int secretSize) { + SECRET_SIZE = secretSize; + } + + @Value("${auth.seed}") + public void setSEED(String SEED) { + GoogleAuthProperties.SEED = SEED; + } + + @Value("${auth.random_number_algorithm}") + public void setRandomNumberAlgorithm(String randomNumberAlgorithm) { + RANDOM_NUMBER_ALGORITHM = randomNumberAlgorithm; + } + + @Value("${auth.window_size}") + public void setWindowSize(int window_size) { + GoogleAuthProperties.WINDOW_SIZE = window_size; + } + + @Value("${auth.redis_google_auth_key}") + public void setRedisGoogleAuthKey(String redisGoogleAuthKey) { + REDIS_GOOGLE_AUTH_KEY = redisGoogleAuthKey; + } + + @Value("${auth.qr_create_prefix_url}") + public void setQrCreatePrefixUrl(String qrCreatePrefixUrl) { + QR_CREATE_PREFIX_URL = qrCreatePrefixUrl; + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/config/WebSocketConfig.java b/wjcy-system/src/main/java/me/zhengjie/config/WebSocketConfig.java new file mode 100644 index 0000000..f55f5c6 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/config/WebSocketConfig.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * @author ZhangHouYing + * @date 2019-08-24 15:44 + */ +@Configuration +public class WebSocketConfig { + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/config/thread/AsyncTaskExecutePool.java b/wjcy-system/src/main/java/me/zhengjie/config/thread/AsyncTaskExecutePool.java new file mode 100644 index 0000000..8df107e --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/config/thread/AsyncTaskExecutePool.java @@ -0,0 +1,69 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.config.thread; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * 异步任务线程池装配类 + * @author https://juejin.im/entry/5abb8f6951882555677e9da2 + * @date 2019年10月31日15:06:18 + */ +@Slf4j +@Configuration +public class AsyncTaskExecutePool implements AsyncConfigurer { + + /** 注入配置类 */ + private final AsyncTaskProperties config; + + public AsyncTaskExecutePool(AsyncTaskProperties config) { + this.config = config; + } + + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程池大小 + executor.setCorePoolSize(config.getCorePoolSize()); + //最大线程数 + executor.setMaxPoolSize(config.getMaxPoolSize()); + //队列容量 + executor.setQueueCapacity(config.getQueueCapacity()); + //活跃时间 + executor.setKeepAliveSeconds(config.getKeepAliveSeconds()); + //线程名字前缀 + executor.setThreadNamePrefix("el-async-"); + // setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务 + // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + executor.initialize(); + return executor; + } + + @Override + public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { + return (throwable, method, objects) -> { + log.error("===="+throwable.getMessage()+"====", throwable); + log.error("exception method:"+method.getName()); + }; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/config/thread/AsyncTaskProperties.java b/wjcy-system/src/main/java/me/zhengjie/config/thread/AsyncTaskProperties.java new file mode 100644 index 0000000..21fdfd8 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/config/thread/AsyncTaskProperties.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.config.thread; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 线程池配置属性类 + * @author https://juejin.im/entry/5abb8f6951882555677e9da2 + * @date 2019年10月31日14:58:18 + */ +@Data +@Component +@ConfigurationProperties(prefix = "task.pool") +public class AsyncTaskProperties { + + private int corePoolSize; + + private int maxPoolSize; + + private int keepAliveSeconds; + + private int queueCapacity; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/config/thread/TheadFactoryName.java b/wjcy-system/src/main/java/me/zhengjie/config/thread/TheadFactoryName.java new file mode 100644 index 0000000..4cc8ae9 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/config/thread/TheadFactoryName.java @@ -0,0 +1,63 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.config.thread; + +import org.springframework.stereotype.Component; + +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 自定义线程名称 + * @author Zheng Jie + * @date 2019年10月31日17:49:55 + */ +@Component +public class TheadFactoryName implements ThreadFactory { + + private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1); + private final ThreadGroup group; + private final AtomicInteger threadNumber = new AtomicInteger(1); + private final String namePrefix; + + public TheadFactoryName() { + this("el-pool"); + } + + private TheadFactoryName(String name){ + SecurityManager s = System.getSecurityManager(); + group = (s != null) ? s.getThreadGroup() : + Thread.currentThread().getThreadGroup(); + //此时namePrefix就是 name + 第几个用这个工厂创建线程池的 + this.namePrefix = name + + POOL_NUMBER.getAndIncrement(); + } + + @Override + public Thread newThread(Runnable r) { + //此时线程的名字 就是 namePrefix + -thread- + 这个线程池中第几个执行的线程 + Thread t = new Thread(group, r, + namePrefix + "-thread-"+threadNumber.getAndIncrement(), + 0); + if (t.isDaemon()) { + t.setDaemon(false); + } + if (t.getPriority() != Thread.NORM_PRIORITY) { + t.setPriority(Thread.NORM_PRIORITY); + } + return t; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/config/thread/ThreadPoolExecutorUtil.java b/wjcy-system/src/main/java/me/zhengjie/config/thread/ThreadPoolExecutorUtil.java new file mode 100644 index 0000000..9a36abd --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/config/thread/ThreadPoolExecutorUtil.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.config.thread; + +import me.zhengjie.utils.SpringContextHolder; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * 用于获取自定义线程池 + * @author Zheng Jie + * @date 2019年10月31日18:16:47 + */ +public class ThreadPoolExecutorUtil { + + public static ThreadPoolExecutor getPoll(){ + AsyncTaskProperties properties = SpringContextHolder.getBean(AsyncTaskProperties.class); + return new ThreadPoolExecutor( + properties.getCorePoolSize(), + properties.getMaxPoolSize(), + properties.getKeepAliveSeconds(), + TimeUnit.SECONDS, + new ArrayBlockingQueue<>(properties.getQueueCapacity()), + new TheadFactoryName() + ); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/aspect/LogAspect.java b/wjcy-system/src/main/java/me/zhengjie/modules/aspect/LogAspect.java new file mode 100644 index 0000000..5618c65 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/aspect/LogAspect.java @@ -0,0 +1,154 @@ +package me.zhengjie.modules.aspect; + + +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.annotation.type.LogDaoType; +import me.zhengjie.annotation.type.LogGetIdType; +import me.zhengjie.config.BeanFactory; +import me.zhengjie.domain.Log; +import me.zhengjie.dto.Dto; +import me.zhengjie.enums.LogTypeEnum; +import me.zhengjie.service.LogService; +import me.zhengjie.utils.*; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +/** + * @author rch + * @date 2020-08-20 + */ +@Component +@Aspect +@Slf4j +public class LogAspect { + + private final LogService logService; + + ThreadLocal currentTime = new ThreadLocal<>(); + + public LogAspect(LogService logService) { + this.logService = logService; + } + + /** + * 配置切入点 + */ + @Pointcut("@annotation(me.zhengjie.annotation.Log)") + public void logPointcut() { + // 该方法无方法体,主要为了让同类中其他方法使用此切入点 + } + + /** + * 配置环绕通知,使用在方法logPointcut()上注册的切入点 + * + * @param joinPoint join point for advice + */ + @Around("logPointcut()") + public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { + Object result; + currentTime.set(System.currentTimeMillis()); + + // 判断是否是修改 如果是修改则获取修改前的信息 + // 如果是修改时间记录json数组,第一个为修改前的json 第二个为修改后的json数据 + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + me.zhengjie.annotation.Log aopLog = method.getAnnotation(me.zhengjie.annotation.Log.class); + //修改之前的数据 + JSONObject beforeJson = new JSONObject(); + Integer type = LogTypeEnum.NO_PLAT_PARAMS.value(); + if (LogActionType.UPDATE.equals(aopLog.type()) && ObjectUtil.isNotEmpty(aopLog.daoNames())) { + + //参数值 获取ID + JSONObject afterJson = JSONObject.parseObject(JSONObject.toJSONString(joinPoint.getArgs()[0])); + String[] daoNames = aopLog.daoNames(); + + // mybatis Plus Dao + if (LogDaoType.MyBATISPLUS.equals(aopLog.daoType())) { + type = LogTypeEnum.SHOW_PLAT_PARAMS.value(); + for (int i = 0; i < daoNames.length; i++) { + String daoName = daoNames[i]; + String idKey = aopLog.idTypes()[i].getValue(); + String valueKey = aopLog.valuesTypes()[i].getValue(); + Map queryMap = new HashMap<>(16); + queryMap.put(StringUtil.underscoreName(idKey), Long.valueOf(afterJson.getString(valueKey))); + Object beforeObj = BeanFactory.getBean(daoName, BaseMapper.class).selectByMap(queryMap).get(0); + cn.hutool.json.JSONObject tempBefJsonObj = new cn.hutool.json.JSONObject(beforeObj); + beforeJson.putAll(tempBefJsonObj); + } + } + // springBoot Data Jpa -因为springBoot Data JPa 该种类型 数据库结果映射对象不是json类型。暂定不支持先不修改不管 + if (LogDaoType.SPRINGDATAJPA.equals(aopLog.daoType())) { + // 逻辑大体同上 + } + } + + // 新增 + if (LogActionType.ADD.equals(aopLog.type())) { + type = LogTypeEnum.SHOW_ADD_PARAMS.value(); + } + + // 登录 + if (LogActionType.LOGIN.equals(aopLog.type())) { + type = LogTypeEnum.SHOW_LOGIN_PARAMS.value(); + } + + result = joinPoint.proceed(); + Log log = new Log("INFO", System.currentTimeMillis() - currentTime.get(), type); + log.setTrueList(aopLog.trueList()); + if (LogActionType.LOGIN.equals(aopLog.type())) { + // 记录失败原因 + if (ObjectUtil.isNotNull(result) && result instanceof Dto) { + log.setDescription(((Dto) result).getMessage()); + } + } + currentTime.remove(); + HttpServletRequest request = RequestHolder.getHttpServletRequest(); + logService.save(getUsername(), StringUtils.getBrowser(request), StringUtils.getIp(request), joinPoint, log, beforeJson); + return result; + } + + /** + * 配置异常通知 + * + * @param joinPoint join point for advice + * @param e exception + */ + @AfterThrowing(pointcut = "logPointcut()", throwing = "e") + public void logAfterThrowing(JoinPoint joinPoint, Throwable e) { + System.out.println("---------"); + System.out.println(e); + System.out.println(joinPoint); + long now = System.currentTimeMillis(); + long time = now - currentTime.get(); + Integer value = LogTypeEnum.NO_PLAT_PARAMS.value(); + Log log = new Log("ERROR", time, value); + currentTime.remove(); + log.setExceptionDetail(ThrowableUtil.getStackTrace(e)); + HttpServletRequest request = RequestHolder.getHttpServletRequest(); + logService.save(getUsername(), StringUtils.getBrowser(request), StringUtils.getIp(request), (ProceedingJoinPoint) joinPoint, log, null); + } + + public String getUsername() { + try { + return SecurityUtils.getCurrentUsername(); + } catch (Exception e) { + return ""; + } + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/capital/controller/FileUploadController.java b/wjcy-system/src/main/java/me/zhengjie/modules/capital/controller/FileUploadController.java new file mode 100644 index 0000000..5a197d6 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/capital/controller/FileUploadController.java @@ -0,0 +1,51 @@ +package me.zhengjie.modules.capital.controller; + +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.Log; +import me.zhengjie.config.SystemConfig; +import me.zhengjie.dto.Dto; +import me.zhengjie.service.FileUploadService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** + *

+ * 图片上传 + *

+ * + * @author: rch + * @since: 2022-06-22 + */ +@Slf4j +@RestController +public class FileUploadController { + + @Resource + private FileUploadService fileUploadService; + + /** + * 后台管理图片上传 + */ + @Log("图片上传") + @PostMapping("/api/file/uploadFile") + public Dto apiUpload(HttpServletResponse response, HttpServletRequest request) throws IOException { + List filePaths = fileUploadService.uploadify(request, response); + return Dto.returnResult(null).setData("list", filePaths); + } + + /** + * 获取图片域名 + */ + @Log("图片上传") + @GetMapping("/api/file/doMainName") + public Dto doMainName() throws IOException { + return Dto.returnResult(SystemConfig.FILE_VISIT_ADDR); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/capital/controller/GoogleAuthController.java b/wjcy-system/src/main/java/me/zhengjie/modules/capital/controller/GoogleAuthController.java new file mode 100644 index 0000000..963532a --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/capital/controller/GoogleAuthController.java @@ -0,0 +1,144 @@ +package me.zhengjie.modules.capital.controller; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtSettingSite; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.system.service.UserService; +import me.zhengjie.modules.system.service.dto.GoogleAuthQrBarCodeUrlDTO; +import me.zhengjie.modules.system.service.dto.UpdateGoogleAuthDTO; +import me.zhengjie.modules.utils.GoogleAuthenticatorUtil; +import me.zhengjie.service.SettingSiteService; +import me.zhengjie.service.vo.AdminGoogleAuthInfoVO; +import me.zhengjie.service.vo.GoogleAuthInfoVO; +import me.zhengjie.utils.SecurityUtils; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +/** + *

+ * Google Authenticator + *

+ * + * @author: rch + * @since: 2020-08-25 + */ +@Validated +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/googleAuth") +public class GoogleAuthController { + + @Resource + private SettingSiteService settingSiteService; + @Resource + private UserService userService; + + private final String GoogleValue = "ConinUnion"; + +// /** +// * 验证身份验证码是否正确 +// * @param googleAuthCodeDTO +// * @return +// */ +// @Log(value = "验证身份验证码是否正确") +// @PostMapping(value = "/authcode") +// public Dto authcode(@Valid @RequestBody GoogleAuthCodeDTO googleAuthCodeDTO) { +// if (!settingSiteService.getGooleAuthSwitch()) { +// return Dto.returnResult(null); +// } +// return Dto.returnResult(GoogleAuthenticatorUtil.authcode(googleAuthCodeDTO.getCodes(), googleAuthCodeDTO.getSavedSecret())); +// } +// +// /** +// * 获取密钥 +// * @param googleAuthGenSecretDTO +// * @return +// */ +// @Log(value = "获取密钥") +// @PostMapping(value = "/genSecret") +// public Dto genSecret(@Valid @RequestBody GoogleAuthGenSecretDTO googleAuthGenSecretDTO, HttpServletRequest request) { +// if (!settingSiteService.getGooleAuthSwitch() || ObjectUtil.isEmpty(userService.findByName(googleAuthGenSecretDTO.getUserName()))) { +// return Dto.returnResult(null); +// } +// // redis 一个用户对应 一次匹配配置的SEED 对应唯一秘钥 +// return Dto.returnResult(GoogleAuthenticatorUtil.genSecret(googleAuthGenSecretDTO.getUserName(), request.getRemoteHost())); +// } + + /** + * 获取二维码图片URL + * @param googleAuthQrBarCodeUrlDTO + * @return + */ + @Log(value = "获取二维码图片URL") + @PostMapping(value = "/getQRBarcodeURL") + public Dto getQRBarcodeURL(@Valid @RequestBody GoogleAuthQrBarCodeUrlDTO googleAuthQrBarCodeUrlDTO, HttpServletRequest request) { + if (ObjectUtil.isEmpty(userService.findByName(googleAuthQrBarCodeUrlDTO.getUserName()))) { + return Dto.returnResult(null); + } + // 没有秘钥会生成一个存储在 redis中 一个用户对应 一次匹配配置的SEED 对应唯一秘钥 + GoogleAuthInfoVO googleAuthInfoVO = new GoogleAuthInfoVO(); + String secretValue = GoogleAuthenticatorUtil.genSecret(googleAuthQrBarCodeUrlDTO.getUserName(), request.getRemoteHost()); + googleAuthInfoVO.setSecret(secretValue); + googleAuthInfoVO.setUserName(googleAuthQrBarCodeUrlDTO.getUserName()); + googleAuthInfoVO.setQrBarCodeUrl(GoogleAuthenticatorUtil.getQRBarcodeURL(googleAuthQrBarCodeUrlDTO.getUserName(), GoogleValue, secretValue)); + return Dto.returnResult(googleAuthInfoVO); + } + + /** + * 判断GoogleAuth 是否开启 + * @return + */ + @Log(value = "判断GoogleAuth 是否开启") + @PostMapping(value = "/getOpenUse") + public Dto getOpenUse(HttpServletRequest request) { + + // 获取admin 信息 + AdminGoogleAuthInfoVO adminGoogleAuthInfoVO = new AdminGoogleAuthInfoVO(); + UserDetails userDetails = SecurityUtils.getCurrentUser(); + if (ObjectUtil.isEmpty(userDetails) || ObjectUtil.isEmpty(userDetails.getUsername())) { + return Dto.getInstance(ErrorCodeEnum.BAD_CREDENTIALS); + } + + String secretValue = GoogleAuthenticatorUtil.genSecret(userDetails.getUsername(), request.getRemoteHost()); + adminGoogleAuthInfoVO.setSecret(secretValue); + adminGoogleAuthInfoVO.setUserName(userDetails.getUsername()); + adminGoogleAuthInfoVO.setQrBarCodeUrl(GoogleAuthenticatorUtil.getQRBarcodeURL(userDetails.getUsername(), GoogleValue, secretValue)); + adminGoogleAuthInfoVO.setGogoleAuthSwitch(settingSiteService.getGooleAuthSwitch()); + + return Dto.returnResult(adminGoogleAuthInfoVO); + } + + + @Log(value = "修改Google开关", type = LogActionType.UPDATE) + @PostMapping(value = "/updateOpenUse") + public Dto updateOpenUse(@Valid @RequestBody UpdateGoogleAuthDTO updateGoogleAuthDTO) { + + Integer value = updateGoogleAuthDTO.getIsOpen(); + CtSettingSite ctSettingSite = new CtSettingSite(); + ctSettingSite.setSettingValue(String.valueOf(value)); + + QueryWrapper ctSettingSiteQuery = new QueryWrapper(); + ctSettingSiteQuery.eq("setting_key", "googleAuth"); + + return Dto.returnResult(settingSiteService.update(ctSettingSite, ctSettingSiteQuery)); + } + + + @Log(value = "获取Google开关") + @GetMapping(value = "/getGoogleSwitch") + @AnonymousAccess + public Dto getGoogleSwitch() { + + return Dto.returnResult(settingSiteService.getGooleAuthSwitch()); + }} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/capital/controller/LoginIpController.java b/wjcy-system/src/main/java/me/zhengjie/modules/capital/controller/LoginIpController.java new file mode 100644 index 0000000..a50fe80 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/capital/controller/LoginIpController.java @@ -0,0 +1,68 @@ +package me.zhengjie.modules.capital.controller; + +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.dto.Dto; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.capital.dto.AddLoginIpDTO; +import me.zhengjie.modules.capital.dto.EditLoginIpDTO; +import me.zhengjie.modules.capital.dto.IdDTO; +import me.zhengjie.service.LoginIpService; +import me.zhengjie.utils.PageUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/* + * + * @Description ip限制 + * @Date 2022/3/21 + * @Author zeng + */ +@Validated +@RestController +@RequestMapping("/api/ip") +@RequiredArgsConstructor +public class LoginIpController { + + final LoginIpService loginIpService; + + @PostMapping("/list") + public Dto list(@RequestBody @Valid PageDTO pageDTO) { + PageUtils pageUtils = loginIpService.getList(pageDTO.getiPage()); + return Dto.returnResult(pageUtils); + } + + @Log(type = LogActionType.ADD,value = "添加ip限制") + @PostMapping("/add") + public Dto addIp(@RequestBody @Valid AddLoginIpDTO dto) { + if (!dto.pass()) { + return Dto.getInstance(ErrorCodeEnum.LOGIN_IP_FORMAT_ERROR); + } + return Dto.returnResult(loginIpService.addIp(dto.getLoginIp())); + } + + @Log(type = LogActionType.UPDATE,value = "修改ip限制") + @PostMapping("/edit") + public Dto editIp(@RequestBody @Valid EditLoginIpDTO dto){ + if (!dto.pass()) { + return Dto.getInstance(ErrorCodeEnum.LOGIN_IP_FORMAT_ERROR); + } + return Dto.returnResult(loginIpService.updateIp(dto.getLoginIp())); + } + + @PostMapping("/getById") + public Dto getIp(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(loginIpService.getById(idDTO.getId())); + } + + @Log(type = LogActionType.DELETE,value = "删除ip限制") + @PostMapping("/del") + public Dto delIp(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(loginIpService.deleteIp(idDTO.getId().intValue())); + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/capital/controller/SettingSiteController.java b/wjcy-system/src/main/java/me/zhengjie/modules/capital/controller/SettingSiteController.java new file mode 100644 index 0000000..65d4498 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/capital/controller/SettingSiteController.java @@ -0,0 +1,140 @@ +package me.zhengjie.modules.capital.controller; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.FormSubmission; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtSettingSite; +import me.zhengjie.modules.capital.dto.SettingSiteDTO; +import me.zhengjie.service.SettingSiteService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * 全局配置 控制类 + * + * @author rch + * @date 2020-07-29 + */ +@Validated +@RestController +@RequiredArgsConstructor +@RequestMapping("api/settingSite") +@Slf4j +public class SettingSiteController { + + @Resource + private SettingSiteService settingSiteService; + + + /** + * 获取全局配置 + * + * @return + */ + @Log("获取全局配置") + @PostMapping("/list") + public Dto list() { + List ctSettingSiteList = settingSiteService.list(); + List list = new ArrayList(); + for (CtSettingSite settingSite : ctSettingSiteList) { + Map map = BeanUtil.beanToMap(settingSite); + map.put("settingValue", getSettingValue(settingSite)); + list.add(map); + } + return Dto.returnResult(list); + } + + /** + * 配置全局配置 + * + * @param settingsiteDtoList + * @return + */ + @Log(value = "配置全局配置", type = LogActionType.ADD, trueList = true) + @PostMapping(value = "/save") + @FormSubmission + public Dto save(@Valid @RequestBody List settingsiteDtoList) { + + List updateCtSettingSiteList = new ArrayList<>(); + for (SettingSiteDTO settingSiteDTO : settingsiteDtoList) { + CtSettingSite site = new CtSettingSite(); + BeanUtil.copyProperties(settingSiteDTO, site); + + // 个别设置 可以只修改部分的内容 + switch (settingSiteDTO.getSettingKey()) { + case "shareholderCurrencySettings": { + String value = settingSiteService.getValue("shareholderCurrencySettings"); + JSONObject oldValue = JSONUtil.parseObj(value); + JSONObject updateValue = JSONUtil.parseObj(settingSiteDTO.getSettingValue()); + oldValue.putAll(updateValue); + site.setSettingValue(oldValue.toString()); + } + } + + updateCtSettingSiteList.add(site); + } + if (ObjectUtil.isEmpty(updateCtSettingSiteList)) { + return Dto.returnErrorResult(" Empty List! "); + } + + // 执行批量更新操作 + return Dto.returnResult(settingSiteService.updateBatchById(updateCtSettingSiteList)); + } + + + private Object getSettingValue(CtSettingSite settingSite) { + Object settingValue = settingSite.getSettingValue(); + switch (settingSite.getSettingKey()) { + case "currencyTemplateSettings": { + JSONObject jsonObject = JSONUtil.parseObj(settingSite.getSettingValue()); + List list = new ArrayList(); + for (String key : jsonObject.keySet()) { + JSONObject value = jsonObject.get(key, JSONObject.class); + value.putOpt("currencyName", key); + list.add(value); + } + return list; + } + case "shareholderPoolPublicSettings": { + JSONObject jsonObject = JSONUtil.parseObj(settingSite.getSettingValue()); + return jsonObject; + } + case "shareholderCurrencySettings": { + JSONObject jsonObject = JSONUtil.parseObj(settingSite.getSettingValue()); + List list = new ArrayList(); + for (String key : jsonObject.keySet()) { + Map blockChain = MapUtil.of("passType", key); + JSONObject currencys = jsonObject.get(key, JSONObject.class); + List currencyList = new ArrayList(); + for (String k : currencys.keySet()) { + JSONObject currency = currencys.get(k, JSONObject.class); + currency.putOpt("currencyName", k); + currencyList.add(currency); + } + blockChain.put("currency", currencyList); + list.add(blockChain); + } + + return list; + } + } + return settingValue; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/AddLoginIpDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/AddLoginIpDTO.java new file mode 100644 index 0000000..632652f --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/AddLoginIpDTO.java @@ -0,0 +1,50 @@ +package me.zhengjie.modules.capital.dto; + +import cn.hutool.core.util.ObjectUtil; +import lombok.Data; +import me.zhengjie.annotation.DateTime; +import me.zhengjie.entity.LoginIp; +import me.zhengjie.utils.LoginIpUtil; + +import javax.validation.constraints.NotBlank; + +/* + * + * @Description + * @Date 2022/3/21 + * @Author zeng + */ +@Data +public class AddLoginIpDTO { + + /** 开始IP */ + @NotBlank + private String ipStart; + /** 结束IP */ + private String ipEnd; + /** 备注 */ + private String remark; + /** 有效截至时间 */ + @DateTime + private String vaildTime; + + public boolean pass() { + if (!LoginIpUtil.isIP(ipStart)) { + return false; + } + if (ObjectUtil.isNotEmpty(ipEnd) && !LoginIpUtil.isIP(ipEnd)) { + return false; + } + return true; + } + + public LoginIp getLoginIp() { + LoginIp ip = new LoginIp(); + ip.setIpStart(ipStart); + ip.setIpEnd(ipEnd); + ip.setRemark(remark); + ip.setVaildTime(vaildTime); + return ip; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/EditLoginIpDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/EditLoginIpDTO.java new file mode 100644 index 0000000..7a493dd --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/EditLoginIpDTO.java @@ -0,0 +1,26 @@ +package me.zhengjie.modules.capital.dto; + +import lombok.Data; +import me.zhengjie.entity.LoginIp; + +import javax.validation.constraints.NotNull; + +/* + * + * @Description + * @Date 2022/3/21 + * @Author zeng + */ +@Data +public class EditLoginIpDTO extends AddLoginIpDTO{ + + @NotNull + private Integer id; + + @Override + public LoginIp getLoginIp() { + LoginIp loginIp = super.getLoginIp(); + loginIp.setId(id); + return loginIp; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/IdDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/IdDTO.java new file mode 100644 index 0000000..aee0b34 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/IdDTO.java @@ -0,0 +1,17 @@ +package me.zhengjie.modules.capital.dto; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/* + * + * @Description IdDTO + * @Date 2021/11/30 + * @Author zeng + */ +@Data +public class IdDTO { + @NotNull + private Long id; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/RelSettingSiteDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/RelSettingSiteDTO.java new file mode 100644 index 0000000..108c95c --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/RelSettingSiteDTO.java @@ -0,0 +1,27 @@ +package me.zhengjie.modules.capital.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 全局配置(SettingSiteDTO)表实体类 + * + * @author rch + * @since 2020-07-29 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RelSettingSiteDTO { + + @NotNull(message = "id不能为空") + private Long id; + + @Valid + List settingSiteList; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/SettingSiteDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/SettingSiteDTO.java new file mode 100644 index 0000000..8c9229c --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/capital/dto/SettingSiteDTO.java @@ -0,0 +1,33 @@ +package me.zhengjie.modules.capital.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 全局配置(SettingSiteDTO)表实体类 + * + * @author rch + * @since 2020-07-29 + */ +@Slf4j +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SettingSiteDTO { + + @NotNull(message = "id不能为空") + private Long id; + + /** 设置KEY */ + @NotBlank(message = "设置KEY") + private String settingKey; + + /** 设置value */ + @NotBlank + private String settingValue; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtApplyController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtApplyController.java new file mode 100644 index 0000000..aced8ee --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtApplyController.java @@ -0,0 +1,187 @@ +package me.zhengjie.modules.group.controller.base; + + +import cn.hutool.core.bean.BeanUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import me.zhengjie.annotation.FormSubmission; +import me.zhengjie.annotation.Log; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtApply; +import me.zhengjie.enums.TaskInfoEnum; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.group.dto.CtApplyAddDTO; +import me.zhengjie.modules.group.dto.CtApplyListDTO; +import me.zhengjie.modules.group.dto.CtApplyUpdateDTO; +import me.zhengjie.modules.group.dto.IdDTO; +import me.zhengjie.service.CtApplyService; +import me.zhengjie.service.vo.CtApplyListVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Author: zhw + * Data: 2022-07-23 + * Description 应用管理控制层——CtApply + */ +@Validated +@RequestMapping("/api/ctApply") +@RestController +@Api(tags = "业务:应用管理") +public class CtApplyController { + + @Resource + private CtApplyService ctApplyService; + + /** + * 分页查询 + */ + @ApiOperation("分页查询应用数据") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询应用数据") + @PostMapping("/list") + public Dto getApplyList(@Valid @RequestBody CtApplyListDTO dto){ + PageUtils pageUtils = ctApplyService.searchPageList(dto.getiPage(),dto.getWrapper()); + return Dto.returnResult(pageUtils); + } + + + /** + * 新增应用信息 + * @param dto + * @return Dto + */ + @ApiOperation("新增应用信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 4200, message = "应用ID存在重复!"), + @ApiResponse(code = 4201, message = "不存在对应方法名称!") + }) + @Log("新增应用信息") + @PostMapping("/add") + @FormSubmission + public Dto addCtApply(@Valid @RequestBody CtApplyAddDTO dto){ + + List applyList = ctApplyService.list(); + List applyIdList = applyList.stream().map(CtApply::getRobotUuid).collect(Collectors.toList()); + if(applyIdList.contains(dto.getRobotUuid())){ + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_REPEAT_ID); + } + + CtApply ctApply = new CtApply(); + BeanUtil.copyProperties(dto, ctApply); + //任务名首字母小写 + char[] taskNameChars = dto.getTaskName().toCharArray(); + taskNameChars[0] = Character.toLowerCase(taskNameChars[0]); + String taskName = new String(taskNameChars); + String methodName = TaskInfoEnum.getMethodNameByTaskName(taskName); + if(methodName == null || methodName.length() == 0){ + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_METHOD_NAME); + } + ctApply.setTaskName(taskName); + ctApply.setMethodName(methodName); + return Dto.returnResult(ctApplyService.save(ctApply)); + } + + /** + * 根据ID删除应用信息 + * @param idDTO + * @return Dto + */ + @ApiOperation("根据ID删除应用信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据ID删除应用信息") + @PostMapping("/delete") + public Dto delCtApplyById(@Valid @RequestBody IdDTO idDTO){ + return Dto.returnResult(ctApplyService.removeById(idDTO.getId())); + } + + /** + * 根据ID 修改应用信息 + * @param dto + * @return Dto + */ + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 4200, message = "应用ID存在重复!"), + @ApiResponse(code = 4201, message = "不存在对应方法名称!") + }) + @ApiOperation("修改应用信息") + @Log("根据ID修改应用信息") + @PostMapping("/edit") + @FormSubmission + public Dto editCtApplyById(@Valid @RequestBody CtApplyUpdateDTO dto){ + CtApply ctApplyIsExist = ctApplyService.getById(dto.getId()); + if(ctApplyIsExist == null){ + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_APPLY); + } + CtApply updateCtApply = new CtApply(); + BeanUtil.copyProperties(dto,updateCtApply); + //更新校验 + List applyList = ctApplyService.list(); + List applyIdList = applyList.stream().map(CtApply::getRobotUuid).collect(Collectors.toList()); + if(applyIdList.contains(dto.getRobotUuid()) && !dto.getRobotUuid().equals(ctApplyIsExist.getRobotUuid())){ + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_REPEAT_ID); + } + + //任务名首字母小写 + char[] taskNameChars = dto.getTaskName().toCharArray(); + taskNameChars[0] = Character.toLowerCase(taskNameChars[0]); + String taskName = new String(taskNameChars); + String methodName = TaskInfoEnum.getMethodNameByTaskName(taskName); + //判断是否存在对应方法名称 + if(methodName == null || methodName.length() == 0){ + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_METHOD_NAME); + } + updateCtApply.setTaskName(taskName); + updateCtApply.setMethodName(methodName); + return Dto.returnResult(ctApplyService.updateById(updateCtApply)); + } + + /** + * 根据ID 查询应用信息 + * @param idDTO + * @return Dto + */ + @ApiOperation("查询应用信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据ID查询应用信息") + @PostMapping("getById") + public Dto getById(@Valid @RequestBody IdDTO idDTO){ + return Dto.returnResult(ctApplyService.getById(idDTO.getId())); + } + + /** + * 获取所有应用信息 + * @return Dto + */ + @ApiOperation("查找所有应用名称") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("查找所有应用名称") + @GetMapping("getAll") + public Dto getAllApply(){ + return Dto.returnResult(ctApplyService.getAllApplyName()); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtBrowseController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtBrowseController.java new file mode 100644 index 0000000..f22c5bd --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtBrowseController.java @@ -0,0 +1,148 @@ +package me.zhengjie.modules.group.controller.base; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.FormSubmission; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtBrowse; +import me.zhengjie.enums.ClickBrowseStatusEnum; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.group.dto.CtBrowseAddDTO; +import me.zhengjie.modules.group.dto.CtBrowseListDTO; +import me.zhengjie.modules.group.dto.CtBrowseUpdateDTO; +import me.zhengjie.modules.group.dto.IdDTO; +import me.zhengjie.service.CtBrowseService; +import me.zhengjie.service.vo.CtBrowseDetailVO; +import me.zhengjie.service.vo.CtBrowseListVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + + +/** + * + * @Description 浏览收藏 控制类 + * @Date 2022-11-04 + * @Author rch + */ +@Validated +@RequestMapping("/api/ctBrowse") +@RestController +@RequiredArgsConstructor +@Api(tags = "业务:收藏浏览管理") +public class CtBrowseController { + + @Resource + private CtBrowseService ctBrowseService; + + /** + * 分页查询浏览收藏信息 + */ + @ApiOperation("分页查询浏览收藏数据") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询浏览收藏信息") + @PostMapping("/list") + public Dto getBrowseList(@Valid @RequestBody CtBrowseListDTO dto) { + PageUtils pageUtilsResult = ctBrowseService.searchPageList(dto.getiPage(), dto.getWrapper()); + return Dto.returnResult(pageUtilsResult); + } + + /** + * 新增浏览收藏信息 + */ + @ApiOperation("新增浏览收藏") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "新增浏览收藏信息",type = LogActionType.ADD) + @PostMapping("/add") + @FormSubmission + public Dto addBrowse(@Valid @RequestBody CtBrowseAddDTO dto) { + + CtBrowse ctBrowse = new CtBrowse(); + BeanUtil.copyProperties(dto, ctBrowse); + return Dto.returnResult(ctBrowseService.save(ctBrowse)); + } + + /** + * 根据Id获取浏览收藏详情 + */ + @ApiOperation("根据Id获取浏览收藏详情") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + + @Log("根据Id获取浏览收藏详情") + @PostMapping("/getById") + public Dto getBrowseById(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(ctBrowseService.getBrowseDetailById(idDTO.getId())); + } + + + /** + * 根据id删除 + * @author: rch + */ + @ApiOperation("根据id删除") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3300, message = "浏览信息不存在!") + }) + @Log(value = "根据id删除信息",type = LogActionType.DELETE) + @PostMapping("/delete") + public Dto delete(@Valid @RequestBody IdDTO idDTO) { + + // 先查询 + CtBrowse ctBrowse = ctBrowseService.getById(idDTO.getId()); + if (ObjectUtil.isEmpty(ctBrowse) + || !ClickBrowseStatusEnum.TOBE_EXECUTION.eqValue(ctBrowse.getStatus())) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_BROWSE); + } + return Dto.returnResult(ctBrowseService.removeById(idDTO.getId())); + } + + /** + * 编辑浏览收藏信息 + */ + @ApiOperation("编辑浏览收藏信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3301, message = "浏览收藏信息不存在!") + }) + @Log(value = "编辑浏览收藏信息",type = LogActionType.UPDATE) + @PostMapping("/edit") + @FormSubmission + public Dto editBrowse(@Valid @RequestBody CtBrowseUpdateDTO dto) { + + // 根据id 判断是否存在 + CtBrowse ctBrowse = ctBrowseService.getById(dto.getId()); + if (ObjectUtil.isEmpty(ctBrowse)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_BROWSE); + } + + CtBrowse updateCtBrowse = new CtBrowse(); + BeanUtil.copyProperties(dto, updateCtBrowse); + + return Dto.returnResult(ctBrowseService.updateById(updateCtBrowse)); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtBuyerController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtBuyerController.java new file mode 100644 index 0000000..6ef64e9 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtBuyerController.java @@ -0,0 +1,391 @@ +package me.zhengjie.modules.group.controller.base; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.swagger.annotations.*; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.FormSubmission; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.config.PropertiesConfig; +import me.zhengjie.config.SystemConfig; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.*; +import me.zhengjie.enums.BuyerStatusEnum; +import me.zhengjie.enums.PlatTypeEnum; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.group.dto.CtBuyerAddDTO; +import me.zhengjie.modules.group.dto.CtBuyerListDTO; +import me.zhengjie.modules.group.dto.CtBuyerUpdateDTO; +import me.zhengjie.modules.group.dto.IdDTO; +import me.zhengjie.service.*; +import me.zhengjie.service.vo.CtBuyerDetailVO; +import me.zhengjie.service.vo.CtBuyerListVO; +import me.zhengjie.utils.PageUtils; +import me.zhengjie.utils.excel.ExcelUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + + +/** + * + * @Description 群控管理-买家 控制类 + * @Date 2022-06-22 + * @Author rch + */ +@Validated +@RequestMapping("/api/ctBuyer") +@RestController +@RequiredArgsConstructor +@Api(tags = "业务:买家管理") +public class CtBuyerController { + + @Resource + private CtBuyerService ctBuyerService; + @Resource + private CtOrderService ctOrderService; + @Resource + private CtCompanyService ctCompanyService; + @Resource + private CtVpnService ctVpnService; + @Resource + private CtCardService ctCardService; + @Resource + private PropertiesConfig propertiesConfig; + @Resource + private Snowflake snowflake; + + /** + * 分页查询买家信息 + */ + @ApiOperation("分页查询买家数据") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询买家信息") + @PostMapping("/list") + public Dto getBuyerList(@Valid @RequestBody CtBuyerListDTO dto) { + PageUtils pageUtilsResult = ctBuyerService.searchPageList(dto.getiPage(), dto.getWrapper()); + return Dto.returnResult(pageUtilsResult); + } + + /** + * 新增买家信息 + */ + @ApiOperation("新增买家信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3200, message = "平台信息不存在!") + }) + @Log(value = "新增买家信息", type = LogActionType.ADD) + @PostMapping("/add") + @FormSubmission + public Dto addBuyer(@Valid @RequestBody CtBuyerAddDTO dto) { + // 检验 + Dto returnDto = addCheck(dto); + if (ObjectUtil.isNotEmpty(returnDto)) { + return returnDto; + } + + CtBuyer ctBuyer = new CtBuyer(); + BeanUtil.copyProperties(dto, ctBuyer); + return Dto.returnResult(ctBuyerService.save(ctBuyer)); + } + + /** + * 根据id买家信息详情详情 + */ + @ApiOperation("根据id查询买家详情信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据id查询买家详情信息") + @PostMapping("/getById") + public Dto getBuyerById(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(ctBuyerService.getDetailById(idDTO.getId())); + } + + /** + * 编辑买家信息 + */ + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3000, message = "买家信息不存在!"), + @ApiResponse(code = 3200, message = "平台信息不存在!") + }) + @ApiOperation("编辑买家信息") + @Log(value = "编辑买家信息", type = LogActionType.UPDATE) + @PostMapping("/edit") + @FormSubmission + public Dto editBuyer(@Valid @RequestBody CtBuyerUpdateDTO dto) { + + // 根据id 判断是否存在 + CtBuyer ctBuyer = ctBuyerService.getById(dto.getId()); + if (ObjectUtil.isEmpty(ctBuyer)) { + Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_BUYER_USER); + } + + // 如果修改平台平台信息 以及修改 密码信息 需要判断是否有关联的订单信息 存在则不允许修改 + Dto returnDto = equalsUpdateBuyerInfo(dto, ctBuyer); + if (ObjectUtil.isNotEmpty(returnDto)) { + return returnDto; + } + CtBuyer updateCtBuyer = new CtBuyer(); + BeanUtil.copyProperties(dto, updateCtBuyer); + return Dto.returnResult(ctBuyerService.updateById(updateCtBuyer)); + } + + /** + * 根据id删除买家信息 + * + * @author: rch + */ + @ApiOperation("根据ID删除买家信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "根据id删除买家信息", type = LogActionType.DELETE) + @PostMapping("/delete") + public Dto delBuyer(@Valid @RequestBody IdDTO idDTO) { + +// QueryWrapper queryWrapper = new QueryWrapper<>(); +// queryWrapper.eq("buyer_id", idDTO); +// Integer count = ctOrderService.count(queryWrapper); +// if (ObjectUtil.isNotEmpty(count) && count > 0) { +// Dto.getInstance(ErrorCodeEnum.ERROR_NOT_DEL_EXIST_ORDER_BUYER_USER); +// } + + CtBuyer updateCtBuyer = new CtBuyer(); + updateCtBuyer.setId(idDTO.getId()); + updateCtBuyer.setStatus(BuyerStatusEnum.DEL.value()); + + return Dto.returnResult(ctBuyerService.updateById(updateCtBuyer)); + } + + /** + * 新增逻辑 检验 + * + * @param dto + * @return + */ + public Dto addCheck(CtBuyerAddDTO dto) { + // 检验公司是否存在 + if (!ObjectUtil.isNotEmpty(ctCompanyService.getById(dto.getCompanyId()))) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_COMPANY); + } + + // 检验平台是否正确 + String value = PlatTypeEnum.getDescByType(dto.getPlatformId()); + if (ObjectUtil.isEmpty(value)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_PLAT_USER); + } + +// // 判断token是否重复 +// QueryWrapper queryWrapper = new QueryWrapper<>(); +// queryWrapper.eq("pwd", dto.getPwd()); +// Integer count = ctBuyerService.count(queryWrapper); +// if (ObjectUtil.isNotEmpty(count) && count > 1) { +// return Dto.getInstance(ErrorCodeEnum.ERROR_EXIST_FIND_BUYER_USER); +// } + return null; + } + + /** + * 检验是否是允许修改 + * + * @param dto + * @param ctBuyer + * @return + */ + public Dto equalsUpdateBuyerInfo(CtBuyerUpdateDTO dto, CtBuyer ctBuyer) { + Boolean canUpdate = false; + if (ObjectUtil.isNotEmpty(dto.getPwd()) && !dto.getPwd().equals(ctBuyer.getPwd())) { + canUpdate = true; + } + if (ObjectUtil.isNotEmpty(dto.getPlatformId()) && !dto.getPlatformId().equals(ctBuyer.getPlatformId())) { + canUpdate = true; + } + if (ObjectUtil.isNotEmpty(dto.getPlatformId()) && !dto.getPlatformId().equals(ctBuyer.getPlatformId())) { + canUpdate = true; + } + + if (canUpdate) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("buyer_id", dto.getId()); + Integer count = ctOrderService.count(queryWrapper); + if (ObjectUtil.isNotEmpty(count) && count > 1) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_UPDATE_EXIST_ORDER_BUYER_USER); + } + } + + // 检验公司是否存在 + if (!ObjectUtil.isNotEmpty(ctCompanyService.getById(dto.getCompanyId()))) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_COMPANY); + } + +// // 判断token是否重复 +// QueryWrapper queryWrapper = new QueryWrapper<>(); +// queryWrapper.eq("pwd", dto.getPwd()); +// Integer count = ctBuyerService.count(queryWrapper); +// if (ObjectUtil.isNotEmpty(count) && count > 1) { +// return Dto.getInstance(ErrorCodeEnum.ERROR_EXIST_FIND_BUYER_USER); +// } + return null; + } + + /** + * 从Excel导入买家信息 + */ + @ApiOperation("从Excel导入买家信息") + @ApiImplicitParams({ + @ApiImplicitParam(value = "上传文件", name = "file", dataType = "__file", required = true) + }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "Excel买家信息", type = LogActionType.ADD) + @PostMapping("import") + public Dto importBuyer(@RequestPart("file") MultipartFile file, HttpServletResponse response) throws Exception { + List ctBuyerImportList = ExcelUtils.readMultipartFile(file, CtBuyerImport.class); + //当excel表导入为空 + if (ObjectUtil.isEmpty(ctBuyerImportList)) { + return Dto.returnResult(false); + } + + List allBuyerAccount = ctBuyerService.getAllAccount(); + List companyInfoList = new ArrayList<>(); + //根据excel表中公司名称导出表中存在公司信息,自动过滤不存在的 + List buyerCompanyNameList = ctBuyerImportList.stream().map(CtBuyerImport::getCompanyName).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList()); + if (ObjectUtil.isNotEmpty(buyerCompanyNameList)) { + companyInfoList = ctCompanyService.getByNmae(buyerCompanyNameList); + } + //获取VPN列表 + List vpnInfoList = new ArrayList<>(); + List buyerVpnIpList = ctBuyerImportList.stream().map(CtBuyerImport::getVpnIp).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());; + if (ObjectUtil.isNotEmpty(buyerVpnIpList)) { + vpnInfoList = ctVpnService.getVpnInfoByIp(buyerVpnIpList); + } + //获取信用卡列表 + List cardInfoList = new ArrayList<>(); + List buyerCardNubList = ctBuyerImportList.stream().map(CtBuyerImport::getCardNumber).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());; + if (ObjectUtil.isNotEmpty(buyerCardNubList)) { + cardInfoList = ctCardService.getCardInfoByNumber(buyerCardNubList); + } + + //批量新增的买家 + List addCtBuyerList = new ArrayList<>(); + //导出异常的买家信息 + List ctBuyerExportList = new ArrayList<>(); + + //循环判断异常 + for (CtBuyerImport ctBuyerImport : ctBuyerImportList) { + //定义一个异常买家实体 + CtBuyerExport ctBuyerExport = new CtBuyerExport(); + BeanUtil.copyProperties(ctBuyerImport, ctBuyerExport); + + StringBuffer errorStrBuf = new StringBuffer(); + //错误信息 + String rowTips = ctBuyerImport.getRowTips(); + if (ObjectUtil.isNotEmpty(rowTips)) { + errorStrBuf.append(rowTips); + errorStrBuf.append(";"); + } + + if (allBuyerAccount.contains(ctBuyerImport.getAccount())) { + errorStrBuf.append("已存在该账号对应的买家信息"); + errorStrBuf.append(";"); + } + //判断是否存在该公司 + if (ObjectUtil.isEmpty(companyInfoList) || companyInfoList.stream().filter(i -> i.getName().equals(ctBuyerExport.getCompanyName())).count() < 1) { + errorStrBuf.append("公司名称不存在!"); + errorStrBuf.append(";"); + } + if (ObjectUtil.isEmpty(vpnInfoList) || vpnInfoList.stream().filter(i -> i.getIpAddress().equals(ctBuyerExport.getVpnIp())).count() < 1) { + errorStrBuf.append("VpnIP信息不存在!"); + errorStrBuf.append(";"); + } + // 敦煌的不需要检验信用卡 + if (!"敦煌".equals(ctBuyerImport.getPlatformName())) { + if (ObjectUtil.isEmpty(cardInfoList) || cardInfoList.stream().filter(i -> i.getNumber().equals(ctBuyerExport.getCardNumber())).count() < 1) { + errorStrBuf.append("信用卡卡号信息不存在!"); + errorStrBuf.append(";"); + } + } + + // 平台 + Integer platId = PlatTypeEnum.getValueByDesc(ctBuyerImport.getPlatformName()); + if (ObjectUtil.isEmpty(platId)) { + errorStrBuf.append("平台信息不存在!"); + errorStrBuf.append(";"); + } + + if (ObjectUtil.isNotEmpty(errorStrBuf)) { + ctBuyerExport.setError(errorStrBuf.toString()); + ctBuyerExportList.add(ctBuyerExport); + } else { + CtBuyer ctBuyer = new CtBuyer(); + BeanUtil.copyProperties(ctBuyerImport, ctBuyer); + //平台ID + ctBuyer.setPlatformId(platId); + //公司ID + Optional ctCompanyInfo = companyInfoList.stream().filter(c -> c.getName().equals(ctBuyerImport.getCompanyName())).findFirst(); + ctBuyer.setCompanyId(ctCompanyInfo.get().getId()); + //VPNiD + Optional ctVpnInfo = vpnInfoList.stream().filter(c -> c.getIpAddress().equals(ctBuyerImport.getVpnIp())).findFirst(); + ctBuyer.setVpnId(ctVpnInfo.get().getId()); + //信用卡ID + Optional ctCardInfo = cardInfoList.stream().filter(c -> c.getNumber().equals(ctBuyerImport.getCardNumber())).findFirst(); + ctBuyer.setCardId(ctCardInfo.get().getId()); + addCtBuyerList.add(ctBuyer); + } + } + String returnDataStr = null; + String filePath = propertiesConfig.getUploadImgPath().get(PublicConstant.EXPORT_EXCEL_FILE_TYPE); + String fileName = "买家导入异常信息表-" + snowflake.nextIdStr(); + if (ObjectUtil.isNotEmpty(ctBuyerExportList)) { + ExcelUtils.exportFile(SystemConfig.IMG_PATH + filePath, fileName, ctBuyerExportList); + returnDataStr = SystemConfig.FILE_VISIT_ADDR + filePath + fileName + ".xlsx"; + // returnDataStr = "http://localhost:8008/file" + filePath + fileName + ".xlsx"; + } + + if (ObjectUtil.isNotEmpty(addCtBuyerList)) { + ctBuyerService.saveBatch(addCtBuyerList); + } + + return Dto.returnResult(ObjectUtil.isEmpty(returnDataStr) ? true : returnDataStr); + } + + /** + * ExcelVpn信息模板导出 + */ + @ApiOperation("买家信息Excel模版导出") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "买家信息Excel模版导出") + @GetMapping("/exportTemp") + @AnonymousAccess + public void exportBuyer(HttpServletResponse response) { + ExcelUtils.exportTemplate(response, "买家导入模板", CtBuyerExportTemple.class); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtCardController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtCardController.java new file mode 100644 index 0000000..e7d0888 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtCardController.java @@ -0,0 +1,307 @@ +package me.zhengjie.modules.group.controller.base; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.swagger.annotations.*; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.FormSubmission; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.config.PropertiesConfig; +import me.zhengjie.config.SystemConfig; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtCard; +import me.zhengjie.entity.CtCardExport; +import me.zhengjie.entity.CtCardExportTemple; +import me.zhengjie.entity.CtCardImport; +import me.zhengjie.enums.CardStatusEnum; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.group.dto.CtCardAddDTO; +import me.zhengjie.modules.group.dto.CtCardListDTO; +import me.zhengjie.modules.group.dto.CtCardUpdateDTO; +import me.zhengjie.modules.group.dto.IdDTO; +import me.zhengjie.service.CtCardService; +import me.zhengjie.service.vo.CtCardDetailVO; +import me.zhengjie.service.vo.CtCardListVO; +import me.zhengjie.utils.PageUtils; +import me.zhengjie.utils.excel.ExcelUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + + +/** + * + * @Description 群控管理-信用卡 控制类 + * @Date 2022-06-22 + * @Author rch + */ +@Validated +@RequestMapping("/api/ctCard") +@RestController +@RequiredArgsConstructor +@Api(tags = "业务:信用卡管理") +public class CtCardController { + + @Resource + private CtCardService ctCardService; + @Resource + private PropertiesConfig propertiesConfig; + @Resource + private Snowflake snowflake; + + /** + * 分页查询信用卡信息 + */ + @ApiOperation("分页查询信用卡数据") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询信用卡信息") + @PostMapping("/list") + public Dto getCardList(@Valid @RequestBody CtCardListDTO dto) { + IPage page= ctCardService.page(dto.getiPage(), dto.getWrapper()); + List list = new ArrayList<>(); + for (CtCard record : page.getRecords()) { + CtCardListVO vo = new CtCardListVO(); + BeanUtil.copyProperties(record, vo); + list.add(vo); + } + + PageUtils pageUtils = new PageUtils(page.getTotal(),list); + return Dto.returnResult(pageUtils); + } + + /** + * 新增信用卡信息 + */ + @ApiOperation("新增信用卡") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "新增信用卡信息",type = LogActionType.ADD) + @PostMapping("/add") + @FormSubmission + public Dto addCard(@Valid @RequestBody CtCardAddDTO dto) { + + CtCard ctCard = new CtCard(); + BeanUtil.copyProperties(dto, ctCard); + return Dto.returnResult(ctCardService.save(ctCard)); + } + + /** + * 根据Id获取信用卡详情 + */ + @ApiOperation("根据Id获取信用卡详情") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据Id获取信用卡详情") + @PostMapping("/getById") + public Dto getCardById(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(ctCardService.getById(idDTO.getId())); + } + + + /** + * 根据id删除信用卡信息 + * @author: rch + */ + @ApiOperation("根据id删除信用卡信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3300, message = "信用卡信息不存在,或者已删除或异常!") + }) + @Log(value = "根据id删除信用卡信息",type = LogActionType.DELETE) + @PostMapping("/delete") + public Dto delCard(@Valid @RequestBody IdDTO idDTO) { + + // 先查询 + CtCard ctCard = ctCardService.getById(idDTO.getId()); + if (ObjectUtil.isEmpty(ctCard) || CardStatusEnum.DEL.eqValue(ctCard.getStatus())) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_CARD_INFO); + } + + CtCard updateCtCard = new CtCard(); + updateCtCard.setId(idDTO.getId()); + updateCtCard.setStatus(CardStatusEnum.DEL.value()); + + return Dto.returnResult(ctCardService.updateById(updateCtCard)); + } + + + /** + * 根据id修改信用卡状态异常 + * @author: rch + */ + @ApiOperation("根据id修改信用卡状态异常") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3300, message = "信用卡信息不存在,或者已删除或异常!") + }) + @Log(value = "根据id修改信用卡状态异常",type = LogActionType.UPDATE) + @PostMapping("/abMormal") + public Dto abMormal(@Valid @RequestBody IdDTO idDTO) { + + // 先查询 + CtCard ctCard = ctCardService.getById(idDTO.getId()); + if (ObjectUtil.isEmpty(ctCard) || CardStatusEnum.AB_NORMAL.eqValue(ctCard.getStatus())) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_CARD_INFO); + } + + CtCard updateCtCard = new CtCard(); + updateCtCard.setId(idDTO.getId()); + updateCtCard.setStatus(CardStatusEnum.AB_NORMAL.value()); + + return Dto.returnResult(ctCardService.updateById(updateCtCard)); + } + + + /** + * 编辑信用卡信息 + */ + @ApiOperation("编辑信用卡信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3301, message = "信用卡信息不存在!") + }) + @Log(value = "编辑信用卡信息",type = LogActionType.UPDATE) + @PostMapping("/edit") + @FormSubmission + public Dto editCard(@Valid @RequestBody CtCardUpdateDTO dto) { + + // 根据id 判断是否存在 + CtCard ctCard = ctCardService.getById(dto.getId()); + if (ObjectUtil.isEmpty(ctCard)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_CARD); + } + + CtCard updateCard = new CtCard(); + BeanUtil.copyProperties(dto, updateCard); + + return Dto.returnResult(ctCardService.updateById(updateCard)); + } + + /** + * Excel导入信用卡信息 + * @param file + * @param response + * @return + * @throws Exception + */ + @ApiOperation("Excel导入信用卡信息") + @ApiImplicitParams({ + @ApiImplicitParam(value = "上传文件", name = "file", dataType = "__file", required = true) + }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "Excel导入信用卡信息",type = LogActionType.ADD) + @PostMapping("/import") + public Dto importCard(@RequestPart("file")MultipartFile file, HttpServletResponse response) throws Exception { + + // TODO 对Excel 信息进行检测 如果不符合要求的 最终要导出错误Excel提示 + List ctCardImportList = ExcelUtils.readMultipartFile(file, CtCardImport.class); + if (ObjectUtil.isEmpty(ctCardImportList)) { + return Dto.returnResult(true); + } + + List addCtCardList = new ArrayList<>(); + List numberValueList = ctCardService.getNumberList(); + List ctCardExportList = new ArrayList<>(); + for (CtCardImport ctCardImport:ctCardImportList) { + CtCardExport ctCardExport = new CtCardExport(); + BeanUtil.copyProperties(ctCardImport, ctCardExport); + + StringBuffer errorStrBuf = new StringBuffer(); + String rowTips = ctCardImport.getRowTips(); + if (ObjectUtil.isNotEmpty(rowTips)) { + errorStrBuf.append(rowTips); + errorStrBuf.append(";"); + } + if (numberValueList.contains(ctCardImport.getNumber())) { + errorStrBuf.append("平台已经存在改卡号对应的信用卡信息!"); + errorStrBuf.append(";"); + } + // 判断日期格式是否正确 + String termOfValidity = ctCardImport.getTermOfValidity(); + String datePattern = "\\d{4}-\\d{1,2}-\\d{1,2}"; + if (!termOfValidity.matches(datePattern)) { + errorStrBuf.append("时间格式错误(yyyy-MM-dd)!"); + errorStrBuf.append(";"); + } + if (ObjectUtil.isNotEmpty(errorStrBuf)) { + ctCardExport.setError(errorStrBuf.toString()); + ctCardExportList.add(ctCardExport); + } else { + CtCard ctCard = new CtCard(); + BeanUtils.copyProperties(ctCardImport, ctCard); + addCtCardList.add(ctCard); + } + } + + String returnDataStr = null; + String filePath = propertiesConfig.getUploadImgPath().get(PublicConstant.EXPORT_EXCEL_FILE_TYPE); + String fileName = "信用卡导入异常信息表-" + snowflake.nextIdStr(); + if (ObjectUtil.isNotEmpty(ctCardExportList)) { + ExcelUtils.exportFile(SystemConfig.IMG_PATH + filePath, fileName, ctCardExportList); + returnDataStr = SystemConfig.FILE_VISIT_ADDR + filePath + fileName + ".xlsx"; +// returnDataStr = "http://localhost:8008/file" + filePath + fileName + ".xlsx"; + } + + if (ObjectUtil.isNotEmpty(addCtCardList)) { + ctCardService.saveBatch(addCtCardList); + } + + return Dto.returnResult(returnDataStr); + +// // 剔除已经有的了 +// List numberList = ctCardList.stream().map(CtCard::getNumber).collect(Collectors.toList()); +// if (ObjectUtil.isEmpty(numberValueList)) { +// return Dto.returnResult(true); +// } +// List finalNumberList = (List) CollectionUtils.subtract(numberList, numberValueList); +// if (ObjectUtil.isEmpty(finalNumberList)) { +// return Dto.returnResult(true); +// } +// ctCardList = ctCardList.stream().filter(c-> finalNumberList.contains(c.getNumber())).collect(Collectors.toList()); + + } + + + /** + * Excel信用卡信息模版导出 + * @param response + */ + @ApiOperation("Excel信用卡信息模版导出") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "Excel信用卡信息模版导出") + @GetMapping("/exportTemp") + @AnonymousAccess + public void importCard(HttpServletResponse response) { + ExcelUtils.exportTemplate(response, "信用卡模版", CtCardExportTemple.class); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtClickFarmingController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtClickFarmingController.java new file mode 100644 index 0000000..3e481cc --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtClickFarmingController.java @@ -0,0 +1,301 @@ +package me.zhengjie.modules.group.controller.base; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.ObjectUtil; +import io.swagger.annotations.*; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.FormSubmission; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.config.PropertiesConfig; +import me.zhengjie.config.SystemConfig; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.*; +import me.zhengjie.enums.ClickFarmingStatusEnum; +import me.zhengjie.enums.ParamsTypeEnum; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.group.dto.CtClickFarmingAddDTO; +import me.zhengjie.modules.group.dto.CtClickFarmingDTO; +import me.zhengjie.modules.group.dto.CtClickFarmingEditDTO; +import me.zhengjie.modules.group.dto.IdDTO; +import me.zhengjie.service.CtBuyerService; +import me.zhengjie.service.CtClickFarmingService; +import me.zhengjie.service.vo.CtClickFarmEditDetailVO; +import me.zhengjie.service.vo.CtClickFarmingDetailVO; +import me.zhengjie.service.vo.CtClickFarmingVO; +import me.zhengjie.utils.PageUtils; +import me.zhengjie.utils.excel.ExcelUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +/** + * + * @Description 群控管理-刷单信息 控制类 + * @Date 2022-06-22 + * @Author rch + */ +@Validated +@RequestMapping("/api/clickFarming") +@RestController +@RequiredArgsConstructor +@Api(tags = "业务:刷单信息管理") +public class CtClickFarmingController { + + @Resource + private CtClickFarmingService ctClickFarmingService; + @Resource + private PropertiesConfig propertiesConfig; + @Resource + private CtBuyerService ctBuyerService; + @Resource + private Snowflake snowflake; + + /** + * 分页查询刷单信息 + */ + @ApiOperation("分页查询刷单数据") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询刷单信息") + @PostMapping("/list") + public Dto getClickFarmingList(@Valid @RequestBody CtClickFarmingDTO dto) { + PageUtils pageUtilsResult = ctClickFarmingService.searchPageList(dto.getiPage(), dto.getWrapper()); + return Dto.returnResult(pageUtilsResult); + } + + /** + * 新增刷单信息 + */ + @ApiOperation("新增刷单信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "新增刷单信息",type = LogActionType.ADD) + @PostMapping("/add") + @FormSubmission + public Dto addClickFarming(@Valid @RequestBody CtClickFarmingAddDTO dto) { + + CtClickFarming ctClickFarming = new CtClickFarming(); + BeanUtil.copyProperties(dto, ctClickFarming); + return Dto.returnResult(ctClickFarmingService.save(ctClickFarming)); + } + + /** + * 根据id获取刷单信息 + */ + @ApiOperation("根据id获取刷单信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据id获取刷单信息") + @PostMapping("/getById") + public Dto getById(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(ctClickFarmingService.getDetailById(idDTO.getId())); + } + + /** + * 根据id获取修改回显信息 + */ + @ApiOperation("根据id获取修改回显信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据id获取修改回显信息") + @PostMapping("/getEditDetailById") + public Dto getEditDetailById(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(ctClickFarmingService.getEditDetailById(idDTO.getId())); + } + + /** + * 根据id删除刷单信息 + * @author: rch + */ + @ApiOperation("根据id删除刷单信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3300, message = "信用卡信息不存在,或者已删除或异常!"), + @ApiResponse(code = 3901, message = "只有待执行的刷单信息才允许删除!") + }) + @Log(value = "根据id删除刷单信息",type = LogActionType.DELETE) + @PostMapping("/delete") + public Dto delClickFarming(@Valid @RequestBody IdDTO idDTO) { + + // 先查询 + CtClickFarming ctClickFarming = ctClickFarmingService.getById(idDTO.getId()); + if (ObjectUtil.isEmpty(ctClickFarming)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_CARD_INFO); + } + + if (!ClickFarmingStatusEnum.TOBE_EXECUTION.eqValue(ctClickFarming.getStatus())) { + return Dto.getInstance(ErrorCodeEnum.ERROR_DEL_CLICKFARMING_INFO); + } + + return Dto.returnResult(ctClickFarmingService.removeById(idDTO.getId())); + } + + /** + * 编辑刷单信息 + */ + @ApiOperation("编辑刷单信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3900, message ="刷单信息不存在!") + }) + @Log(value = "编辑刷单信息",type = LogActionType.UPDATE) + @PostMapping("/edit") + @FormSubmission + public Dto editClickFarming(@Valid @RequestBody CtClickFarmingEditDTO dto) { + // 判断状态 只有待执行状态太允许修改 + CtClickFarming ctClickFarming = ctClickFarmingService.getByIdLock(dto.getId()); + if (ObjectUtil.isEmpty(ctClickFarming)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_CLICKFARMING_INFO); + } + + CtClickFarming updateCtClickFarming = new CtClickFarming(); + BeanUtil.copyProperties(dto, updateCtClickFarming); + + return Dto.returnResult(ctClickFarmingService.updateById(updateCtClickFarming)); + } + + /** + * + * @param file + * @param response + * @return + * @throws Exception + */ + @ApiOperation("Excel刷单信息导入") + @ApiImplicitParams({ + @ApiImplicitParam(value = "上传文件", name = "file", dataType = "__file", required = true) + }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "Excel刷单信息导入",type = LogActionType.ADD) + @PostMapping("/import") + public Dto importClickFarming(@RequestPart("file")MultipartFile file, HttpServletResponse response) throws Exception { + + // TODO 对Excel 信息进行检测 如果不符合要求的 最终要导出错误Excel提示 + List ctClickFarmingImportList = ExcelUtils.readMultipartFile(file, CtClickFarmingImport.class); + if (ObjectUtil.isEmpty(ctClickFarmingImportList)) { + return Dto.returnResult(true); + } + + List addCtClickFarmingList = new ArrayList<>(); + List ctClickFarmingExportList = new ArrayList<>(); + + // 买家id + List buyerAccountList = ctClickFarmingImportList.stream().map(c->c.getAccount()).collect(Collectors.toList()); + Map buyerMap = ctBuyerService.getBuyerList(buyerAccountList); + + for (CtClickFarmingImport ctClickFarmingImport:ctClickFarmingImportList) { + CtClickFarmingExport ctClickFarmingExport = new CtClickFarmingExport(); + BeanUtil.copyProperties(ctClickFarmingImport, ctClickFarmingExport); + + StringBuffer errorStrBuf = new StringBuffer(); + String rowTips = ctClickFarmingImport.getRowTips(); + if (ObjectUtil.isNotEmpty(rowTips)) { + errorStrBuf.append(rowTips); + errorStrBuf.append(";"); + } + + if (ObjectUtil.isEmpty(ctClickFarmingImport.getSpecification())) { + errorStrBuf.append("规格-必填!"); + errorStrBuf.append(";"); + } + if (ObjectUtil.isEmpty(ctClickFarmingImport.getColor())) { + errorStrBuf.append("颜色-必填!"); + errorStrBuf.append(";"); + } + if (ObjectUtil.isEmpty(ctClickFarmingImport.getExchange())) { + errorStrBuf.append("优惠劵-必填!"); + errorStrBuf.append(";"); + } + + // 判断类型 + if (ParamsTypeEnum.KEY_WORD.eqValue(ctClickFarmingImport.getParamsType())) { + if (ObjectUtil.isEmpty(ctClickFarmingImport.getKeyWord())) { + errorStrBuf.append("关键词-必填!"); + errorStrBuf.append(";"); + } + if (ObjectUtil.isEmpty(ctClickFarmingImport.getTitle())) { + errorStrBuf.append("标题-必填!"); + errorStrBuf.append(";"); + } + if (ObjectUtil.isEmpty(ctClickFarmingImport.getItem())) { + errorStrBuf.append("item-必填!"); + errorStrBuf.append(";"); + } + } else { + if (ObjectUtil.isEmpty(ctClickFarmingImport.getLink())) { + errorStrBuf.append("链接-必填!"); + errorStrBuf.append(";"); + } + } + + if (ObjectUtil.isEmpty(buyerMap) || !buyerMap.containsKey(ctClickFarmingImport.getAccount())) { + errorStrBuf.append("买家信息不存在!"); + errorStrBuf.append(";"); + } else { + Long buyerId = buyerMap.entrySet().stream().collect(Collectors.toMap(entity -> entity.getKey(), entity -> entity.getValue())).get(ctClickFarmingImport.getAccount()).getId(); + ctClickFarmingImport.setBuyerId(buyerId); + } + if (ObjectUtil.isNotEmpty(errorStrBuf)) { + ctClickFarmingExport.setError(errorStrBuf.toString()); + ctClickFarmingExportList.add(ctClickFarmingExport); + } else { + CtClickFarming ctClickFarming = new CtClickFarming(); + BeanUtils.copyProperties(ctClickFarmingImport, ctClickFarming); + addCtClickFarmingList.add(ctClickFarming); + } + } + + String returnDataStr = null; + String filePath = propertiesConfig.getUploadImgPath().get(PublicConstant.EXPORT_EXCEL_FILE_TYPE); + String fileName = "刷单信息导入异常信息表-" + snowflake.nextIdStr(); + if (ObjectUtil.isNotEmpty(ctClickFarmingExportList)) { + ExcelUtils.exportFile(SystemConfig.IMG_PATH + filePath, fileName, ctClickFarmingExportList); + returnDataStr = SystemConfig.FILE_VISIT_ADDR + filePath + fileName + ".xlsx"; +// returnDataStr = "http://localhost:8008/file" + filePath + fileName + ".xlsx"; + } + + if (ObjectUtil.isNotEmpty(addCtClickFarmingList)) { + ctClickFarmingService.saveBatch(addCtClickFarmingList); + } + + return Dto.returnResult(returnDataStr); + } + + @ApiOperation("Excel刷单信息模版导出") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "Excel刷单信息模版导出") + @GetMapping("/exportTemp") + @AnonymousAccess + public void importClickFarming(HttpServletResponse response) { + ExcelUtils.exportTemplate(response, "刷单信息模版", CtClickFarmingExportTemp.class); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtClickOrderController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtClickOrderController.java new file mode 100644 index 0000000..fadc5d1 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtClickOrderController.java @@ -0,0 +1,330 @@ +package me.zhengjie.modules.group.controller.base; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.ObjectUtil; +import io.swagger.annotations.*; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.rest.AnonymousPostMapping; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.config.PropertiesConfig; +import me.zhengjie.config.SystemConfig; +import me.zhengjie.constant.Constants; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.*; +import me.zhengjie.enums.ClickFarmingStatusEnum; +import me.zhengjie.enums.OrderTypeEnum; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.group.dto.*; +import me.zhengjie.service.CtClickFarmingService; +import me.zhengjie.service.CtClickOrderService; +import me.zhengjie.service.CtCompanyService; +import me.zhengjie.service.vo.CtClickOrderDetailVO; +import me.zhengjie.service.vo.CtClickOrderListVO; +import me.zhengjie.utils.PageUtils; +import me.zhengjie.utils.excel.ExcelUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +/** + * + * @Description 群控管理-刷单信息订单 控制类 + * @Date 2022-06-22 + * @Author rch + */ +@Validated +@RequestMapping("/api/clickOrder") +@RestController +@RequiredArgsConstructor +@Api(tags = "业务:刷单订单管理") +public class CtClickOrderController { + + @Resource + private CtClickOrderService ctClickOrderService; + @Resource + private CtCompanyService ctCompanyService; + @Resource + private PropertiesConfig propertiesConfig; + @Resource + private CtClickFarmingService ctClickFarmingService; + @Resource + private Snowflake snowflake; + + /** + * 分页查询刷单订单信息 + */ + @ApiOperation("分页查询刷单订单信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询刷单订单信息") + @PostMapping("/list") + @AnonymousAccess + public Dto getClickOrderList(@Valid @RequestBody CtClickOrderListDTO dto) { + PageUtils pageUtilsResult = ctClickOrderService.searchPageList(dto.getiPage(), dto.getWrapper()); + return Dto.returnResult(pageUtilsResult); + } + + /** + * 开放刷单订单接口给到ERP + * @param dto + * @return + */ + @ApiOperation("开放刷单订单接口") + @ApiImplicitParam(value = "鉴权token", name = "erpToken", paramType = "header", dataType = "String", required = true) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 4101, message = "鉴权信息不能为空!"), + @ApiResponse(code = 4102, message = "鉴权信息错误,请检查后重试!") + }) + @Log(value = "开放刷单订单接口") + @AnonymousPostMapping(value = "/searchClickOrder") + public Dto searchClickOrder(@Valid @RequestBody SearchOrderListDTO dto, HttpServletRequest request) { + + // 1.权限检验 + String erpToken = request.getHeader("erpToken"); + if (ObjectUtil.isEmpty(erpToken)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_NULL_ERP_AUTH_TOKEN); + } + + if (!Constants.ERP_AUTH_TOKEN.equals(erpToken)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_ERP_AUTH_TOKEN); + } + + // 2.根据请求条件查询记录并返回 + PageUtils pageUtilsResult = ctClickOrderService.searchPageList(dto.getiPage(), dto.getWrapper()); + return Dto.returnResult(pageUtilsResult); + } + + /** + * 根据id刷单信息详情详情 + */ + @ApiOperation("根据id刷单信息详情详情") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据id刷单信息详情详情") + @PostMapping("/getById") + public Dto getCardById(@Valid @RequestBody IdDTO idDTO) { + // 获取 + CtClickOrderDetailVO ctClickOrderDetailVO = ctClickOrderService.getClickOrderDetailById(idDTO.getId()); +// if (ObjectUtil.isNotEmpty(ctClickOrderDetailVO.getPaths())) { +// List pathStrList = new ArrayList<>(); +// List pathList = Arrays.asList(ctClickOrderDetailVO.getPaths().split(",")); +// for (String path:pathList) { +//// path = "http://localhost:8008/file" + path; +// path = SystemConfig.FILE_VISIT_ADDR + path; +// pathStrList.add(path); +// } +// ctClickOrderDetailVO.setPaths(pathStrList.stream().collect(Collectors.joining(","))); +// } + return Dto.returnResult(ctClickOrderDetailVO); + } + + + /** + * 新增订单评论信息 + */ + @ApiOperation("新增订单评论信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "新增订单评论信息") + @PostMapping("/add") + public Dto add(@Valid @RequestBody CtClickOrderAddDto ctClickOrderAddDto) { + + // 保证仅仅 下单成功并且支付失败状态才允许执行 + + CtClickOrder addCtClickOrder = new CtClickOrder(); + addCtClickOrder.setType(OrderTypeEnum.IMPORT.value()); + BeanUtil.copyProperties(ctClickOrderAddDto, addCtClickOrder); + return Dto.returnResult(ctClickOrderService.save(addCtClickOrder)); + } + + /** + * 刷单订单导入 + */ + @ApiOperation("Excel刷单订单导入") + @ApiImplicitParams({ + @ApiImplicitParam(value = "上传文件", name = "file", dataType = "__file", required = true) + }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "Excel刷单订单导入",type = LogActionType.ADD) + @PostMapping("import") + public Dto importOrder(@RequestPart("file") MultipartFile file, HttpServletResponse response)throws Exception{ + + //TODO 对Excel 信息进行检测 如果不符合要求的 最终要导出错误Excel提示 + List ctClickOrderImportList = ExcelUtils.readMultipartFile(file, CtClickOrderImport.class); + if(ObjectUtil.isEmpty(ctClickOrderImportList)){ + return Dto.returnResult(true); + } + + List addCtClickOrderList = new ArrayList<>(); + // 订单id 唯一 + List importOrderIdList = ctClickOrderImportList.stream().map(c->c.getOrderId()).collect(Collectors.toList()); + importOrderIdList = ctClickOrderService.getOrderId(importOrderIdList); + // 判断公司信息是否存在 + List companyNameList = ctClickOrderImportList.stream().map(c->c.getCompanyName()).collect(Collectors.toList()); + Map companyNameMap = ctCompanyService.getNameList(companyNameList); + + List ctClickOrderExportList = new ArrayList<>(); + for(CtClickOrderImport ctClickOrderImport : ctClickOrderImportList) { + CtClickOrderExport ctClickOrderExport = new CtClickOrderExport(); + BeanUtil.copyProperties(ctClickOrderImport, ctClickOrderExport); + + StringBuffer errorStrBuf = new StringBuffer(); + String rowTips = ctClickOrderImport.getRowTips(); + if (ObjectUtil.isNotEmpty((rowTips))) { + errorStrBuf.append(rowTips); + errorStrBuf.append(";"); + } + + String resultStr = checkImportInfo(importOrderIdList, companyNameMap, ctClickOrderImport); + if (ObjectUtil.isNotEmpty(resultStr)) { + errorStrBuf.append(resultStr); + errorStrBuf.append(";"); + } + + Long companyNameId = companyNameMap.entrySet().stream().collect(Collectors.toMap(entity -> entity.getValue(), entity -> entity.getKey())).get(ctClickOrderImport.getCompanyName()); + ctClickOrderImport.setCompanyId(companyNameId); + if (ObjectUtil.isNotEmpty(errorStrBuf)) { + ctClickOrderExport.setError(errorStrBuf.toString()); + ctClickOrderExportList.add(ctClickOrderExport); + } else { + CtClickOrder ctClickOrder = new CtClickOrder(); + BeanUtil.copyProperties(ctClickOrderImport, ctClickOrder); + ctClickOrder.setType(OrderTypeEnum.IMPORT.value()); + addCtClickOrderList.add(ctClickOrder); + } + } + + String returnDataStr = null; + String filePath = propertiesConfig.getUploadImgPath().get(PublicConstant.EXPORT_EXCEL_FILE_TYPE); + String fileName = "刷单订单导入异常信息表-" + snowflake.nextIdStr(); + if(ObjectUtil.isNotEmpty(ctClickOrderExportList)){ + ExcelUtils.exportFile(SystemConfig.IMG_PATH + filePath, fileName, ctClickOrderExportList); + returnDataStr = SystemConfig.FILE_VISIT_ADDR + filePath + fileName + ".xlsx"; + // returnDataStr = "http://localhost:8008/file" + filePath + fileName + ".xlsx"; + } + + if(ObjectUtil.isNotEmpty(addCtClickOrderList)){ + ctClickOrderService.saveBatch(addCtClickOrderList); + } + + return Dto.returnResult(returnDataStr); + } + + + + /** + * Excel订单模版导出 + */ + @ApiOperation("Excel订单模版导出") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "Excel订单模版导出") + @GetMapping("/exportTemp") + @AnonymousAccess + public void exportVpn(HttpServletResponse response) { + ExcelUtils.exportTemplate(response, "订单导入模板", CtClickOrderExportTemple.class, true); + } + + /** + * 补录订单信息 + * 仅仅 下单成功并且支付失败状态才允许执行此接口 + */ + @ApiOperation("补录订单信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3900, message = "刷单信息不存在!"), + @ApiResponse(code = 3903, message = "仅支付成功失败状态才允许补录!") + }) + @Log(value = "补录订单信息") + @PostMapping("/supplement") + public Dto supplementOrder(@Valid @RequestBody CtClickOrderSupplementDto ctClickOrderSupplementDto) { + + // 保证仅仅 下单成功并且支付失败状态才允许执行 + Long clickFarmingId = ctClickOrderSupplementDto.getClickFarmingId(); + CtClickFarming ctClickFarming = ctClickFarmingService.getById(clickFarmingId); + if (ObjectUtil.isEmpty(ctClickFarming)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_CLICKFARMING_INFO); + } + if (!ClickFarmingStatusEnum.PAY_OK_ERROR.value().equals(ctClickFarming.getStatus())) { + return Dto.getInstance(ErrorCodeEnum.ERROR_CLICKFARMING_NOT_SUPPLEMENT); + } + + CtClickOrder ctClickOrder = new CtClickOrder(); + BeanUtil.copyProperties(ctClickOrderSupplementDto, ctClickOrder); + // 补录订单信息 + return Dto.returnResult(ctClickOrderService.supplement(clickFarmingId, ctClickOrder)); + } + + + /** + * 新增评论信息 + */ + @ApiOperation("新增评论信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 4100, message = "订单信息不存在") + }) + @Log(value = "新增评论信息") + @PostMapping("/comment") + public Dto comment(@Valid @RequestBody CtClickOrderCommentDto ctClickOrderCommentDto) { + + // 保证仅仅 下单成功并且支付失败状态才允许执行 + CtClickOrder ctClickOrder = ctClickOrderService.getById(ctClickOrderCommentDto.getId()); + if (ObjectUtil.isEmpty(ctClickOrder)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_CLICK_ORDER_INFO); + } + + CtClickOrder updateCtClickOrder = new CtClickOrder(); + BeanUtil.copyProperties(ctClickOrderCommentDto, updateCtClickOrder); + return Dto.returnResult(ctClickOrderService.updateById(updateCtClickOrder)); + } + + /** + * 导入数据内容检验 + * @param importOrderIdList + * @param companyNameMap + * @param ctClickOrderImport + * @return + */ + public String checkImportInfo(List importOrderIdList, Map companyNameMap, CtClickOrderImport ctClickOrderImport) { + if (ObjectUtil.isNotEmpty(companyNameMap)) { + if (!companyNameMap.containsValue(ctClickOrderImport.getCompanyName())) { + return "对应名称的公司不存在!"; + } + } else if(ObjectUtil.isNotEmpty(ctClickOrderImport)) { + if (importOrderIdList.contains(ctClickOrderImport.getOrderId())) { + return "该笔订单已存在!"; + } + } + return null; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtCompanyController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtCompanyController.java new file mode 100644 index 0000000..88fa0fb --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtCompanyController.java @@ -0,0 +1,187 @@ +package me.zhengjie.modules.group.controller.base; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import me.zhengjie.annotation.FormSubmission; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtBuyer; +import me.zhengjie.entity.CtCompany; +import me.zhengjie.entity.CtOrder; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.group.dto.CtCompanyAddDTO; +import me.zhengjie.modules.group.dto.CtCompanyListDTO; +import me.zhengjie.modules.group.dto.CtCompanyUpdateDTO; +import me.zhengjie.modules.group.dto.IdDTO; +import me.zhengjie.service.CtCompanyService; +import me.zhengjie.service.CtOrderService; +import me.zhengjie.service.vo.CtCompanyInfoVO; +import me.zhengjie.service.vo.CtCompanyVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; + + +/** + * + * @Description 群控管理-公司 控制类 + * @Date 2022-06-23 + * @Author rch + */ +@Validated +@RequestMapping("/api/ctCompany") +@RestController +@Api(tags = "业务:公司信息管理") +public class CtCompanyController { + + @Resource + private CtCompanyService ctCompanyService; + @Resource + private CtOrderService ctOrderService; + + /** + * 分页查询公司信息 + */ + @ApiOperation("分页查询公司信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询公司信息") + @PostMapping("/list") + public Dto getCompanyList(@Valid @RequestBody CtCompanyListDTO dto) { + IPage page = ctCompanyService.page(dto.getiPage(), dto.getWrapper()); + List list = new ArrayList<>(); + for (CtCompany record : page.getRecords()) { + CtCompanyVO ctCompanyVO = new CtCompanyVO(); + BeanUtil.copyProperties(record, ctCompanyVO); + list.add(ctCompanyVO); + } + PageUtils pageUtils = new PageUtils(page.getTotal(),list); + return Dto.returnResult(pageUtils); + } + + /** + * 新增公司信息 + */ + @ApiOperation("新增公司信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "新增公司信息",type = LogActionType.ADD) + @PostMapping("/add") + @FormSubmission + public Dto addCompany(@Valid @RequestBody CtCompanyAddDTO dto) { + CtCompany ctCompany = new CtCompany(); + BeanUtil.copyProperties(dto, ctCompany); + + // TODO 商户码(公司调用api公司唯一标识) -按照一定规则生成 + ctCompany.setNumber("666666"); + // TODO 商户token(公司调用api公司token身份标识)-按照一定规则生成 + ctCompany.setToken("7777777"); + return Dto.returnResult(ctCompanyService.save(ctCompany)); + } + + /** + * 根据id公司信息详情 + */ + @ApiOperation("根据id公司信息详情") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据id公司信息详情详情") + @PostMapping("/getById") + public Dto getCompanyById(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(ctCompanyService.getById(idDTO.getId())); + } + + /** + * 编辑公司信息 + */ + @ApiOperation("编辑公司信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3300, message = "公司信息不存在!") + }) + @Log(value = "编辑公司信息",type = LogActionType.UPDATE) + @PostMapping("/edit") + @FormSubmission + public Dto editCompany(@Valid @RequestBody CtCompanyUpdateDTO dto) { + + // TODO 检验平台ID和平台名称是否一致 + + // 根据id 判断是否存在 + CtCompany ctCompany = ctCompanyService.getById(dto.getId()); + if (ObjectUtil.isEmpty(ctCompany)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_COMPANY); + } + + CtCompany updateCtCompany = new CtCompany(); + BeanUtil.copyProperties(dto, updateCtCompany); + return Dto.returnResult(ctCompanyService.updateById(updateCtCompany)); + } + + /** + * 根据id删除公司信息 + * @author: rch + */ + @ApiOperation("根据id删除公司信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3201, message = "该公司下存在订单信息,不允许删除!") + }) + @Log(value = "根据id删除公司信息",type = LogActionType.DELETE) + @PostMapping("/delete") + public Dto delCompany(@Valid @RequestBody IdDTO idDTO) { + // 判断公司下存在订单信息则不允许删除 + QueryWrapper ctOrderQueryWrapper = new QueryWrapper<>(); + ctOrderQueryWrapper.eq("company_id", idDTO.getId()); + Integer count = ctOrderService.count(ctOrderQueryWrapper); + if (ObjectUtil.isNotEmpty(count) && count > 0) { + return Dto.getInstance(ErrorCodeEnum.ERROR_EXITS_CT_ORDER_INFO); + } + + return Dto.returnResult(ctCompanyService.removeById(idDTO.getId())); + } + + /** + * 获取所有公司信息 (公司id 公司名称) + * 为新增 公司提供公司所属公司服务 + * @return + */ + @ApiOperation("获取所有公司信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "获取所有公司信息") + @GetMapping("/getAll") + public Dto allCompany() { + List ctCompanyList = ctCompanyService.list(); + List ctCompanyInfoVOList = new ArrayList<>(); + if (ObjectUtil.isNotEmpty(ctCompanyList)) { + for (CtCompany ctCompany:ctCompanyList) { + CtCompanyInfoVO ctCompanyInfoVO = new CtCompanyInfoVO(); + BeanUtil.copyProperties(ctCompany, ctCompanyInfoVO); + ctCompanyInfoVOList.add(ctCompanyInfoVO); + } + } + return Dto.returnResult(ctCompanyInfoVOList); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtDhPayController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtDhPayController.java new file mode 100644 index 0000000..1fbf0b9 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtDhPayController.java @@ -0,0 +1,300 @@ +package me.zhengjie.modules.group.controller.base; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.qiniu.util.Json; +import io.swagger.annotations.*; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.FormSubmission; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.config.PropertiesConfig; +import me.zhengjie.config.SystemConfig; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtDhPay; +import me.zhengjie.entity.CtDhPayExport; +import me.zhengjie.entity.CtDhPayExportTemple; +import me.zhengjie.entity.CtDhPayImport; +import me.zhengjie.enums.DhPayStatusEnum; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.group.dto.CtDhPayAddDTO; +import me.zhengjie.modules.group.dto.CtDhPayListDTO; +import me.zhengjie.modules.group.dto.IdDTO; +import me.zhengjie.service.CtDhPayService; +import me.zhengjie.service.vo.CtDhPayDetailVO; +import me.zhengjie.service.vo.CtDhPayListVO; +import me.zhengjie.utils.PageUtils; +import me.zhengjie.utils.excel.ExcelUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + + +/** + * @Description 群控管理-敦煌支付 控制类 + * @Date 2022-06-22 + * @Author rch + */ +@Validated +@RequestMapping("/api/dhPay") +@RestController +@RequiredArgsConstructor +@Api(tags = "业务:敦煌支付管理") +public class CtDhPayController { + + @Resource + private PropertiesConfig propertiesConfig; + @Resource + private Snowflake snowflake; + @Resource + private CtDhPayService ctDhPayService; + + /** + * 分页查询敦煌支付信息 + */ + @ApiOperation("分页查询敦煌支付信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询敦煌支付信息") + @PostMapping("/list") + @AnonymousAccess + public Dto getDhPayList(@Valid @RequestBody CtDhPayListDTO dto) { + PageUtils pageUtilsResult = ctDhPayService.searchPageList(dto.getiPage(), dto.getWrapper()); + return Dto.returnResult(pageUtilsResult); + } + + /** + * 新增敦煌支付信息 + */ + @ApiOperation("新增敦煌支付信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "新增敦煌支付信息", type = LogActionType.ADD) + @PostMapping("/add") + @AnonymousAccess + @FormSubmission + public Dto addDhPay(@Valid @RequestBody CtDhPayAddDTO dto) { + List ctCardList = new ArrayList<>(); + List errCtDhPay = new ArrayList<>(); + String orderIdListStr = dto.getOrderId(); + String[] orderIdList = orderIdListStr.split(","); + List allCtDhPay = ctDhPayService.list(); + for (String orderId : orderIdList) { + CtDhPay ctDhPay = new CtDhPay(); + ctDhPay.setBuyerName(dto.getBuyerName()); + ctDhPay.setOrderId(orderId); + + // TODO 剔除已经存在的 同导入逻辑的检验 + List anyMatchList = allCtDhPay.stream().filter(d -> d.getBuyerName().equals(ctDhPay.getBuyerName()) && d.getOrderId().equals(ctDhPay.getOrderId())).collect(Collectors.toList()); + if (ObjectUtil.isNotEmpty(anyMatchList)) { + errCtDhPay.add(ctDhPay); + } else { + ctCardList.add(ctDhPay); + } + } + if (ObjectUtil.isNotEmpty(errCtDhPay)) { + StringBuffer errStrBuffer = new StringBuffer(); + errStrBuffer.append("该买家对应的订单编号"); + for (int i = 0; i < errCtDhPay.size(); i++) { + CtDhPay errPay = errCtDhPay.get(i); + if (i != 0) { + errStrBuffer.append("、"); + } + errStrBuffer.append(errPay.getOrderId()); + } + errStrBuffer.append("存在重复信息,新增失败"); + if (ObjectUtil.isNotEmpty(ctCardList)) { + ctDhPayService.saveBatch(ctCardList); + } + return Dto.returnErrorResult(errStrBuffer.toString()); + } else { + if (ObjectUtil.isNotEmpty(ctCardList)) { + return Dto.returnResult(ctDhPayService.saveBatch(ctCardList)); + } + } + return Dto.returnResult(true); + } + + /** + * 根据id敦煌支付信息 + */ + @ApiOperation("根据id敦煌支付信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据id敦煌支付信息") + @PostMapping("/getById") + @AnonymousAccess + public Dto getDhPayById(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(ctDhPayService.getById(idDTO.getId())); + } + + + /** + * 根据id删除敦煌支付信息 + * + * @author: rch + */ + @ApiOperation("根据id删除敦煌支付信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3800, message = "敦煌支付信息不存在,或已删除!") + }) + @Log(value = "根据id删除敦煌支付信息", type = LogActionType.DELETE) + @PostMapping("/delete") + @AnonymousAccess + public Dto delDhPay(@Valid @RequestBody IdDTO idDTO) { + + // 先查询 + CtDhPay ctDhPay = ctDhPayService.getById(idDTO.getId()); + if (ObjectUtil.isEmpty(ctDhPay) || DhPayStatusEnum.DEL.eqValue(ctDhPay.getStatus())) { + return Dto.getInstance(ErrorCodeEnum.ERROR_DH_PAY_NOT_FIND_OR_SUCCESS); + } + + CtDhPay updateCtDhPay = new CtDhPay(); + updateCtDhPay.setId(idDTO.getId()); + updateCtDhPay.setStatus(DhPayStatusEnum.DEL.value()); + + return Dto.returnResult(ctDhPayService.updateById(updateCtDhPay)); + } + + + /** + * Excel敦煌支付信息导入 + * @param file + * @param response + * @return + * @throws Exception + */ + @ApiOperation("Excel敦煌支付信息导入") + @ApiImplicitParams({ + @ApiImplicitParam(value = "上传文件", name = "file", dataType = "__file", required = true) + }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "Excel敦煌支付信息导入", type = LogActionType.ADD) + @PostMapping("/import") + public Dto importCard(@RequestPart("file") MultipartFile file, HttpServletResponse response) throws Exception { + + // TODO 对Excel 信息进行检测 如果不符合要求的 最终要导出错误Excel提示 + List ctDhPayImportList = ExcelUtils.readMultipartFile(file, CtDhPayImport.class); + if (ObjectUtil.isEmpty(ctDhPayImportList)) { + return Dto.returnResult(true); + } + + List addCtDhPayList = new ArrayList<>(); + List errCtDhPayList = new ArrayList<>(); + List ctDhPayExportList = new ArrayList<>(); + + List buyerNameList = ctDhPayImportList.stream().map(CtDhPayImport::getBuyerName).collect(Collectors.toList()); + List orderIdList = ctDhPayImportList.stream().map(CtDhPayImport::getOrderId).collect(Collectors.toList()); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("buyer_name", buyerNameList); + queryWrapper.or(); + queryWrapper.in("order_id", orderIdList); + List queryCtDhPay = ctDhPayService.list(queryWrapper); + + for (CtDhPayImport ctDhPayImport : ctDhPayImportList) { + CtDhPayExport ctDhPayExport = new CtDhPayExport(); + BeanUtil.copyProperties(ctDhPayImport, ctDhPayExport); + StringBuffer errorStrBuf = new StringBuffer(); + String rowTips = ctDhPayImport.getRowTips(); + if (ObjectUtil.isNotEmpty(rowTips)) { + errorStrBuf.append(rowTips); + errorStrBuf.append(";"); + } + //判断订单号是否按照规格输入 + String regex = "^[0-9]+(,[0-9]+)*$"; + if (!Pattern.matches(regex, ctDhPayImport.getOrderId())) { + errorStrBuf.append("订单编号格式输入错误,请重新输入"); + } else { + String[] orderIdArr = ctDhPayImport.getOrderId().split(","); + for (String orderId : orderIdArr) { + CtDhPay ctDhPay = new CtDhPay(); + ctDhPay.setBuyerName(ctDhPayImport.getBuyerName()); + ctDhPay.setOrderId(orderId); + + List anyMatchList = queryCtDhPay.stream().filter(d -> d.getBuyerName().equals(ctDhPay.getBuyerName()) && d.getOrderId().equals(ctDhPay.getOrderId())).collect(Collectors.toList()); + if (ObjectUtil.isNotEmpty(anyMatchList)) { + errCtDhPayList.add(ctDhPay); + } else { + addCtDhPayList.add(ctDhPay); + } + } + if (ObjectUtil.isNotEmpty(errCtDhPayList)) { + errorStrBuf.append("该买家对应的订单编号"); + for (int i = 0; i < errCtDhPayList.size(); i++) { + CtDhPay errPay = errCtDhPayList.get(i); + if (i != 0) { + errorStrBuf.append("、"); + } + errorStrBuf.append(errPay.getOrderId()); + } + errorStrBuf.append("存在重复信息,新增失败"); + } + } + + if (ObjectUtil.isNotEmpty(errorStrBuf)) { + ctDhPayExport.setError(errorStrBuf.toString()); + ctDhPayExportList.add(ctDhPayExport); + } + } + + String returnDataStr = null; + String filePath = propertiesConfig.getUploadImgPath().get(PublicConstant.EXPORT_EXCEL_FILE_TYPE); + String fileName = "敦煌支付导入异常信息表-" + snowflake.nextIdStr(); + if (ObjectUtil.isNotEmpty(ctDhPayExportList)) { + ExcelUtils.exportFile(SystemConfig.IMG_PATH + filePath, fileName, ctDhPayExportList); + returnDataStr = SystemConfig.FILE_VISIT_ADDR + filePath + fileName + ".xlsx"; + //returnDataStr = "http://localhost:8008/file" + filePath + fileName + ".xlsx"; + } + + //拆分订单编号,分多条数据存入 + if (ObjectUtil.isNotEmpty(addCtDhPayList)) { + ctDhPayService.saveBatch(addCtDhPayList); + } + + return Dto.returnResult(returnDataStr); + } + + + /** + * Excel敦煌支付信息模版导出 + * @param response + */ + @ApiOperation("Excel敦煌支付信息模版导出") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "Excel敦煌支付信息模版导出") + @GetMapping("/exportTemp") + @AnonymousAccess + public void importCard(HttpServletResponse response) { + ExcelUtils.exportTemplate(response, "敦煌支付模版", CtDhPayExportTemple.class); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtExcelController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtExcelController.java new file mode 100644 index 0000000..eaf3575 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtExcelController.java @@ -0,0 +1,157 @@ +package me.zhengjie.modules.group.controller.base; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.FormSubmission; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtBuyer; +import me.zhengjie.entity.CtExcel; +import me.zhengjie.entity.CtExcelExportTemple; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.group.dto.CtExcelAddDTO; +import me.zhengjie.modules.group.dto.CtExcelListDTO; +import me.zhengjie.modules.group.dto.CtExcelUpdateDTO; +import me.zhengjie.modules.group.dto.IdDTO; +import me.zhengjie.service.CtExcelService; +import me.zhengjie.service.vo.CtExcelVO; +import me.zhengjie.utils.PageUtils; +import me.zhengjie.utils.excel.ExcelUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; + + +/** + * + * @Description Excel相关操作 控制类 + * @Date 2022-06-22 + * @Author rch + */ +@Validated +@RequestMapping("/api/ctExcel") +@RestController +@Api(tags = "业务:Excel管理") +public class CtExcelController { + + @Resource + private CtExcelService ctExcelService; + + /** + * 分页查询Excel信息 + */ + @ApiOperation("分页查询Excel信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询Excel信息") + @PostMapping("/list") + public Dto getExcelList(@Valid @RequestBody CtExcelListDTO dto) { + IPage page = ctExcelService.page(dto.getiPage(), dto.getWrapper()); + List list = new ArrayList<>(); + for (CtExcel record : page.getRecords()) { + CtExcelVO ctExcelVO = new CtExcelVO(); + BeanUtil.copyProperties(record, ctExcelVO); + list.add(ctExcelVO); + } + PageUtils pageUtils = new PageUtils(page.getTotal(),list); + return Dto.returnResult(pageUtils); + } + + /** + * 新增Excel信息 + */ + @ApiOperation("新增Excel信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "新增导入Excel信息",type = LogActionType.ADD) + @PostMapping("/add") + @FormSubmission + public Dto addExcel(@Valid @RequestBody CtExcelAddDTO dto) { + CtExcel ctExcel = new CtExcel(); + BeanUtil.copyProperties(dto, ctExcel); + return Dto.returnResult(ctExcelService.save(ctExcel)); + } + + /** + * 根据id获取Excel信息 + */ + @ApiOperation("根据id获取Excel信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据id获取Excel信息") + @PostMapping("/getById") + public Dto getExcelById(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(ctExcelService.getById(idDTO.getId())); + } + + /** + * 编辑Excel信息 + */ + @ApiOperation("编辑Excel信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3100, message = "卖家信息不存在!") + }) + @Log(value = "编辑Excel信息",type = LogActionType.UPDATE) + @PostMapping("/edit") + @FormSubmission + public Dto editExcel(@Valid @RequestBody CtExcelUpdateDTO dto) { + // 根据id 判断是否存在 + CtExcel ctExcel = ctExcelService.getById(dto.getId()); + if (ObjectUtil.isEmpty(ctExcel)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_EXCEL_USER); + } + + CtExcel updateCtExcel = new CtExcel(); + BeanUtil.copyProperties(dto, updateCtExcel); + return Dto.returnResult(ctExcelService.updateById(updateCtExcel)); + } + + /** + * 根据id删除Excel信息 + * @author: rch + */ + @ApiOperation("根据id删除Excel信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "根据id删除Excel信息",type = LogActionType.DELETE) + @PostMapping("/delete") + public Dto delExcel(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(ctExcelService.removeById(idDTO.getId())); + } + + /** + * Excel模板下载 + */ + @ApiOperation("Excel模板下载") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "Excel模板下载") + @GetMapping("/exportTemp") + public void importExcel(HttpServletResponse response){ + ExcelUtils.exportTemplate(response, "Excel导入模板", CtExcelExportTemple.class); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtExcelInfoController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtExcelInfoController.java new file mode 100644 index 0000000..9606354 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtExcelInfoController.java @@ -0,0 +1,120 @@ +package me.zhengjie.modules.group.controller.base; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import me.zhengjie.annotation.Log; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtBuyer; +import me.zhengjie.entity.CtExcelImportInfo; +import me.zhengjie.modules.group.dto.CtExcelImportInfoListDTO; +import me.zhengjie.modules.group.dto.IdDTO; +import me.zhengjie.service.CtExcelImportInfoService; +import me.zhengjie.service.vo.CtExcelImportInfoVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; + + +/** + * + * @Description Excel导入信息相关操作 控制类 + * @Date 2022-06-22 + * @Author rch + */ +@Validated +@RequestMapping("/api/ctExcelInfo") +@RestController +@Api(tags = "业务:Excel导入信息管理") +public class CtExcelInfoController { + + @Resource + private CtExcelImportInfoService ctExcelImportInfoService; + + /** + * 分页查询ExcelInfo信息 + */ + @ApiOperation("分页查询ExcelInfo信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询ExcelInfo信息") + @PostMapping("/list") + public Dto getExcelInfoList(@Valid @RequestBody CtExcelImportInfoListDTO dto) { + IPage page = ctExcelImportInfoService.page(dto.getiPage(), dto.getWrapper()); + List list = new ArrayList<>(); + for (CtExcelImportInfo record : page.getRecords()) { + CtExcelImportInfoVO ctExcelImportInfoVO = new CtExcelImportInfoVO(); + BeanUtil.copyProperties(record, ctExcelImportInfoVO); + list.add(ctExcelImportInfoVO); + } + PageUtils pageUtils = new PageUtils(page.getTotal(),list); + return Dto.returnResult(pageUtils); + } + + + /** + * 根据id获取ExcelInfo信息 + */ + @ApiOperation("根据id获取ExcelInfo信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据id获取ExcelInfo信息") + @PostMapping("/getById") + public Dto getExcelInfoById(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(ctExcelImportInfoService.getById(idDTO.getId())); + } + +// /** +// * 新增Excel信息 +// */ +// @Log(value = "新增导入Excel信息",type = LogActionType.ADD) +// @PostMapping("/add") +// public Dto addExcelInfo(@Valid @RequestBody CtExcelAddDTO dto) { +// CtExcel ctExcel = new CtExcel(); +// BeanUtil.copyProperties(dto, ctExcel); +// return Dto.returnResult(ctExcelService.save(ctExcel)); +// } + + +// /** +// * 编辑Excel信息 +// */ +// @Log(value = "编辑Excel信息",type = LogActionType.UPDATE) +// @PostMapping("/edit") +// public Dto editExcelInfo(@Valid @RequestBody CtExcelUpdateDTO dto) { +// // 根据id 判断是否存在 +// CtExcel ctExcel = ctExcelService.getById(dto.getId()); +// if (ObjectUtil.isEmpty(ctExcel)) { +// Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_EXCEL_USER); +// } +// +// CtExcel updateCtExcel = new CtExcel(); +// BeanUtil.copyProperties(dto, updateCtExcel); +// return Dto.returnResult(ctExcelService.updateById(updateCtExcel)); +// } + +// /** +// * 根据id删除Excel信息 +// * @author: rch +// */ +// @Log(value = "根据id删除Excel信息",type = LogActionType.DELETE) +// @PostMapping("/delete") +// public Dto delExcelInfo(@Valid @RequestBody IdDTO idDTO) { +// return Dto.returnResult(ctExcelService.removeById(idDTO.getId())); +// } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtOrderController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtOrderController.java new file mode 100644 index 0000000..26e7b31 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtOrderController.java @@ -0,0 +1,165 @@ +package me.zhengjie.modules.group.controller.base; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import me.zhengjie.annotation.Log; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.*; +import me.zhengjie.modules.group.dto.CtOrderListDTO; +import me.zhengjie.modules.group.dto.IdDTO; +import me.zhengjie.service.CtOrderService; +import me.zhengjie.service.CtResponseOrderAddressService; +import me.zhengjie.service.CtResponseOrderProductService; +import me.zhengjie.service.CtResponseOrderService; +import me.zhengjie.service.vo.CtOrderVO; +import me.zhengjie.service.vo.OrderResponStatusVO; +import me.zhengjie.service.vo.PayOrderVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; + + +/** + * + * @Description 群控管理- 敦煌下订单信息 控制类 + * @Date 2022-06-30 + * @Author rch + */ +@Validated +@RequestMapping("/api/dhOrder") +@RestController +@Api(tags = "业务:敦煌下单管理") +public class CtOrderController { + + @Resource + private CtOrderService ctOrderService; + @Resource + private CtResponseOrderService ctResponseOrderService; + @Resource + private CtResponseOrderAddressService ctResponseOrderAddressService; + @Resource + private CtResponseOrderProductService ctResponseOrderProductService; + + /** + * 分页查询敦煌下订单信息 + */ + @ApiOperation("分页查询敦煌下订单信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询敦煌下订单信息") + @PostMapping("/list") + public Dto getOrderList(@Valid @RequestBody CtOrderListDTO dto) { + IPage page = ctOrderService.page(dto.getiPage(), dto.getWrapper()); + List list = new ArrayList<>(); + for (CtOrder record : page.getRecords()) { + CtOrderVO ctOrderVO = new CtOrderVO(); + BeanUtil.copyProperties(record, ctOrderVO); + + // 下单状态转换 + OrderResponStatusVO orderResponStatusVO = JSONUtil.toBean(record.getOrderResponseStatus(), OrderResponStatusVO.class); + ctOrderVO.setOrderResponseStatus(orderResponStatusVO); + // 支付状态转换 + PayOrderVO payOrderVO = JSONUtil.toBean(record.getPayResponseStatus(), PayOrderVO.class); + ctOrderVO.setPayOrderVO(payOrderVO); + + list.add(ctOrderVO); + } + PageUtils pageUtils = new PageUtils(page.getTotal(),list); + return Dto.returnResult(pageUtils); + } + + /** + * 根据id获取敦煌下订单 + */ + @ApiOperation("根据id获取敦煌下订单") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据id获取敦煌下订单") + @PostMapping("/getById") + public Dto getOrderById(@Valid @RequestBody IdDTO idDTO) { + CtOrder ctOrder = ctOrderService.getById(idDTO.getId()); + if (ObjectUtil.isEmpty(ctOrder)) { + return Dto.returnResult(ctOrder); + } + CtOrderVO ctOrderVO = new CtOrderVO(); + BeanUtil.copyProperties(ctOrder, ctOrderVO); + + // 下单状态转换 + OrderResponStatusVO orderResponStatusVO = JSONUtil.toBean(ctOrder.getOrderResponseStatus(), OrderResponStatusVO.class); + ctOrderVO.setOrderResponseStatus(orderResponStatusVO); + // 支付状态转换 + PayOrderVO payOrderVO = JSONUtil.toBean(ctOrder.getPayResponseStatus(), PayOrderVO.class); + ctOrderVO.setPayOrderVO(payOrderVO); + + return Dto.returnResult(ctOrderVO); + } + + + + /** + * 根据id敦煌响应订单信息 + * @param idDTO + * @return + */ + @ApiOperation("根据id敦煌响应订单信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据id敦煌响应订单信息") + @PostMapping("/getOrderInfoById") + public Dto getOrderInfoById(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(ctResponseOrderService.getById(idDTO.getId())); + } + + + /** + * 根据id敦煌订单收件信息 + * @param idDTO + * @return + */ + @ApiOperation("根据id敦煌订单收件信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据id敦煌订单收件信息") + @PostMapping("/getOrderAddressById") + public Dto getOrderAddressById(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(ctResponseOrderAddressService.getById(idDTO.getId())); + } + + /** + * 根根据id敦煌订单产品信息 + * @param idDTO + * @return + */ + @ApiOperation("根据id敦煌订单产品信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据id敦煌订单产品信息") + @PostMapping("/getOrderProductById") + public Dto getOrderProductById(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(ctResponseOrderProductService.getById(idDTO.getId())); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtPlatformController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtPlatformController.java new file mode 100644 index 0000000..f78a278 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtPlatformController.java @@ -0,0 +1,136 @@ +//package me.zhengjie.modules.group.controller; +// +//import cn.hutool.core.bean.BeanUtil; +//import cn.hutool.core.util.ObjectUtil; +//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +//import com.baomidou.mybatisplus.core.metadata.IPage; +//import me.zhengjie.annotation.Log; +//import me.zhengjie.annotation.type.LogActionType; +//import me.zhengjie.dto.Dto; +//import me.zhengjie.entity.CtBuyer; +//import me.zhengjie.entity.CtCompany; +//import me.zhengjie.entity.CtPlatform; +//import me.zhengjie.error.ErrorCodeEnum; +//import me.zhengjie.modules.group.dto.*; +//import me.zhengjie.service.CtCompanyService; +//import me.zhengjie.service.CtPlatformService; +//import me.zhengjie.service.vo.CtPlatformInfoVO; +//import me.zhengjie.service.vo.CtPlatformVO; +//import me.zhengjie.utils.PageUtils; +//import org.springframework.context.annotation.Bean; +//import org.springframework.validation.annotation.Validated; +//import org.springframework.web.bind.annotation.*; +// +//import javax.annotation.Resource; +//import javax.validation.Valid; +//import java.util.ArrayList; +//import java.util.List; +// +// +///** +// * +// * @Description 群控管理-平台 控制类 +// * @Date 2022-06-23 +// * @Author rch +// */ +//@Validated +//@RequestMapping("/api/ctPlatform") +//@RestController +//public class CtPlatformController { +// +// @Resource +// private CtPlatformService ctPlatformService; +// @Resource +// private CtCompanyService ctCompanyService; +// +// /** +// * 分页查询平台信息 +// */ +// @Log("分页查询平台信息") +// @PostMapping("/list") +// public Dto getPlatformList(@Valid @RequestBody CtPlatformListDTO dto) { +// IPage page = ctPlatformService.page(dto.getiPage(), dto.getWrapper()); +// List list = new ArrayList<>(); +// for (CtPlatform record : page.getRecords()) { +// CtPlatformVO ctPlatformVO = new CtPlatformVO(); +// BeanUtil.copyProperties(record, ctPlatformVO); +// list.add(ctPlatformVO); +// } +// PageUtils pageUtils = new PageUtils(page.getTotal(),list); +// return Dto.returnResult(pageUtils); +// } +// +// /** +// * 新增平台信息 +// */ +// @Log(value = "新增平台信息",type = LogActionType.ADD) +// @PostMapping("/add") +// public Dto addPlatform(@Valid @RequestBody CtPlatformAddDTO dto) { +// CtPlatform ctPlatform = new CtPlatform(); +// BeanUtil.copyProperties(dto, ctPlatform); +// return Dto.returnResult(ctPlatformService.save(ctPlatform)); +// } +// +// /** +// * 根据id平台信息详情详情 +// */ +// @Log("根据id平台信息详情详情") +// @PostMapping("/getById") +// public Dto getPlatformById(@Valid @RequestBody IdDTO idDTO) { +// return Dto.returnResult(ctPlatformService.getById(idDTO.getId())); +// } +// +// /** +// * 编辑平台信息 +// */ +// @Log(value = "编辑平台信息",type = LogActionType.UPDATE) +// @PostMapping("/edit") +// public Dto editPlatform(@Valid @RequestBody CtBuyerUpdateDTO dto) { +// // 根据id 判断是否存在 +// CtPlatform ctPlatform = ctPlatformService.getById(dto.getId()); +// if (ObjectUtil.isEmpty(ctPlatform)) { +// Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_BUYER_USER); +// } +// +// CtPlatform updateCtPlatform = new CtPlatform(); +// BeanUtil.copyProperties(dto, updateCtPlatform); +// return Dto.returnResult(ctPlatformService.updateById(updateCtPlatform)); +// } +// +// /** +// * 根据id删除平台信息 +// * @author: rch +// */ +// @Log(value = "根据id删除平台信息",type = LogActionType.DELETE) +// @PostMapping("/delete") +// public Dto delPlatform(@Valid @RequestBody IdDTO idDTO) { +// // 判断平台下有公司则不允许删除 +// QueryWrapper ctCompanyQueryWrapper = new QueryWrapper<>(); +// ctCompanyQueryWrapper.eq("platform_id", idDTO.getId()); +// Integer count = ctCompanyService.count(ctCompanyQueryWrapper); +// if (ObjectUtil.isNotEmpty(count) && count > 0) { +// Dto.getInstance(ErrorCodeEnum.ERROR_EXITS_COMPANY_INFO); +// } +// return Dto.returnResult(ctPlatformService.removeById(idDTO.getId())); +// } +// +// /** +// * 获取所有平台信息 (平台id 平台名称) +// * 为新增 公司提供公司所属平台服务 +// * @return +// */ +// @Log(value = "获取所有平台信息") +// @GetMapping("/getAll") +// public Dto allPlatform() { +// List ctPlatformList = ctPlatformService.list(); +// List ctPlatformInfoVOList = new ArrayList<>(); +// if (ObjectUtil.isNotEmpty(ctPlatformList)) { +// CtPlatformInfoVO ctPlatformInfoVO = new CtPlatformInfoVO(); +// for (CtPlatform ctPlatform:ctPlatformList) { +// BeanUtil.copyProperties(ctPlatform, ctPlatformInfoVO); +// ctPlatformInfoVOList.add(ctPlatformInfoVO); +// } +// } +// return Dto.returnResult(ctPlatformInfoVOList); +// } +//} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtRebotController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtRebotController.java new file mode 100644 index 0000000..d520076 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtRebotController.java @@ -0,0 +1,214 @@ +package me.zhengjie.modules.group.controller.base; + +import cn.hutool.core.bean.BeanUtil; +import io.swagger.annotations.*; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.FormSubmission; +import me.zhengjie.annotation.Log; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtRebot; +import me.zhengjie.entity.CtRebotExportTemple; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.group.dto.*; +import me.zhengjie.service.CtRebotService; +import me.zhengjie.service.vo.CtRebotListVO; +import me.zhengjie.utils.PageUtils; +import me.zhengjie.utils.excel.ExcelUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; + +/** + * 影刀机器人(ct_rebot) 控制层 + * + * @Author zhw + * @Date 2022-07-23 + */ +@Validated +@RequestMapping("/api/ctRebot") +@RestController +@Api(tags = "业务:机器人管理") +public class CtRebotController { + + @Resource + private CtRebotService ctRebotService; + + /** + * 分页查询 影刀机器人信息 + * @param dto + * @return Dto + */ + @ApiOperation("分页查询影刀机器人信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询影刀机器人信息") + @PostMapping("/list") + public Dto getRebotList(@Valid @RequestBody CtRebotListDTO dto){ + PageUtils pageUtils = ctRebotService.searchPageList(dto.getiPage(),dto.getWrapper()); + return Dto.returnResult(pageUtils); + } + + /** + * 分页查询未占有状态机器人信息 + */ + @ApiOperation("分页查询未占有状态机器人信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询未占有状态机器人信息") + @PostMapping("freeList") + public Dto getFreeRebotList(@Valid @RequestBody CtRebotListDTO dto){ + PageUtils pageUtils = ctRebotService.searchPageList(dto.getiPage(),dto.getWrapper()); + List allRebotList = pageUtils.getList(); + List freeRebotList = new ArrayList<>(); + long freeTotal = 0L; + for(CtRebotListVO record : allRebotList){ + if(record.getStatus()==0){ + freeTotal++; + freeRebotList.add(record); + } + } + PageUtils freePageUtils = new PageUtils<>(freeTotal, freeRebotList); + return Dto.returnResult(freePageUtils); + } + + /** + * 新增影刀机器人信息 + * @param dto + * @return Dto + */ + @ApiOperation("新增影刀机器人信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("新增影刀机器人信息") + @PostMapping("/add") + @FormSubmission + public Dto addCtRebot(@Valid @RequestBody CtRebotAddDTO dto){ + CtRebot ctRebot = new CtRebot(); + BeanUtil.copyProperties(dto,ctRebot); + return Dto.returnResult(ctRebotService.save(ctRebot)); + } + + /** + * 根据ID删除影刀机器人信息 + * @param idDTO + * @return Dto + */ + @ApiOperation("根据ID删除影刀机器人信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据ID删除影刀机器人信息") + @PostMapping("/delete") + public Dto delCtRebotById(@Valid @RequestBody IdDTO idDTO){ + return Dto.returnResult(ctRebotService.removeById(idDTO.getId())); + } + + /** + * 根据ID修改影刀机器人信息 + * @param dto + * @return Dto + */ + @ApiOperation("据ID修改影刀机器人信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据ID修改影刀机器人信息") + @PostMapping("/edit") + @FormSubmission + public Dto editCtRebotById(@Valid @RequestBody CtRebotUpdateDTO dto){ + CtRebot ctRebotIsExist = ctRebotService.getById(dto.getId()); + if(ctRebotIsExist == null){ + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_REBOT); + } + CtRebot updateCtRebot = new CtRebot(); + BeanUtil.copyProperties(dto,updateCtRebot); + return Dto.returnResult(ctRebotService.updateById(updateCtRebot)); + } + + /** + * 根据Id查找影刀机器人信息 + * @param iddto + * @return Dto + */ + @ApiOperation("根据Id查找影刀机器人信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据ID查找影刀机器人信息") + @PostMapping("getById") + public Dto getById(@Valid @RequestBody IdDTO iddto){ + return Dto.returnResult(ctRebotService.getById(iddto.getId())); + } + + + /** + * TODO 这里只是测试方便使用 + * @param dto + * @return Dto + */ + @ApiOperation("重置机器人状态") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("重置机器人状态") + @PostMapping("updateStatus") + public Dto updateStatus(@Valid @RequestBody CtRebotUpdateStatusDTO dto){ + CtRebot ctRebot = new CtRebot(); + ctRebot.setId(dto.getId()); + ctRebot.setStatus(0); + return Dto.returnResult(ctRebotService.updateById(ctRebot)); + } + + /** + * EXCEL导入机器人信息 + * @param file + * @param response + * @return Dto + * @throws Exception + */ + @ApiOperation("EXCEL导入机器人信息") + @ApiImplicitParams({ + @ApiImplicitParam(value = "上传文件", name = "file", dataType = "__file", required = true) + }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("EXCEL导入机器人信息") + @PostMapping("/import") + public Dto importRebot(@RequestPart("file") MultipartFile file, HttpServletResponse response)throws Exception{ + return ctRebotService.importRebot(file, response); + } + + /** + * EXCEL导出机器人导入模板 + */ + @ApiOperation("EXCEL导出机器人导入模板") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("EXCEL导出机器人导入模板") + @GetMapping("/exportTemp") + @AnonymousAccess + public void exportRebot(HttpServletResponse response){ + ExcelUtils.exportTemplate(response, "机器人导入模板", CtRebotExportTemple.class); + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtVpnController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtVpnController.java new file mode 100644 index 0000000..9d9eab7 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/CtVpnController.java @@ -0,0 +1,261 @@ +package me.zhengjie.modules.group.controller.base; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.swagger.annotations.*; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.FormSubmission; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.config.PropertiesConfig; +import me.zhengjie.config.SystemConfig; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtVpn; +import me.zhengjie.entity.CtVpnExport; +import me.zhengjie.entity.CtVpnExportTemple; +import me.zhengjie.entity.CtVpnImport; +import me.zhengjie.enums.VpnStatusEnum; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.group.dto.CtVpnAddDTO; +import me.zhengjie.modules.group.dto.CtVpnListDTO; +import me.zhengjie.modules.group.dto.CtVpnUpdateDTO; +import me.zhengjie.modules.group.dto.IdDTO; +import me.zhengjie.service.CtVpnService; +import me.zhengjie.service.vo.CtVpnInfoVO; +import me.zhengjie.service.vo.CtVpnVO; +import me.zhengjie.utils.PageUtils; +import me.zhengjie.utils.excel.ExcelUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; + +/** + * @Description + * @Date 2022/7/7 + * @Author zhw + */ +@Validated +@RequestMapping("/api/ctVpn") +@RestController +@Api(tags = "业务:Vpn管理") +public class CtVpnController { + + @Resource + private CtVpnService ctVpnService; + @Resource + private PropertiesConfig propertiesConfig; + @Resource + private Snowflake snowflake; + + /** + * 分页查询VPN信息 + */ + @ApiOperation("分页查询VPN信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询VPN信息") + @PostMapping("/list") + public Dto getVpnList(@Valid @RequestBody CtVpnListDTO dto){ + IPage page = ctVpnService.page(dto.getiPage(),dto.getWrapper()); + List list = new ArrayList<>(); + for(CtVpn record : page.getRecords()){ + CtVpnVO ctVpnVO = new CtVpnVO(); + BeanUtil.copyProperties(record, ctVpnVO); + list.add(ctVpnVO); + } + PageUtils pageUtils = new PageUtils(page.getTotal(),list); + return Dto.returnResult(pageUtils); + } + + /** + * 新增VPN信息 + */ + @ApiOperation("新增VPN信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "新增VPN信息",type = LogActionType.ADD) + @PostMapping("/add") + @FormSubmission + public Dto addVpn(@Valid @RequestBody CtVpnAddDTO dto){ + CtVpn ctVpn = new CtVpn(); + BeanUtil.copyProperties(dto,ctVpn); + ctVpn.setStatus(VpnStatusEnum.AVAILABLE.value()); + //新增规则 + return Dto.returnResult(ctVpnService.save(ctVpn)); + } + + /** + * 根据ID查VPN详情 + */ + @ApiOperation("根据ID查VPN详情") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据ID查询VPN详情") + @PostMapping("/getById") + public Dto getVpnById(@Valid @RequestBody IdDTO idDTO){ + return Dto.returnResult(ctVpnService.getById(idDTO.getId())); + } + + /** + * 编辑VPN信息 + */ + @ApiOperation("编辑VPN信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 2000, message = "VPN信息不存在,或者已删除!") + }) + @Log(value = "编辑VPN信息",type = LogActionType.UPDATE) + @PostMapping("/edit") + @FormSubmission + public Dto editVpn(@Valid @RequestBody CtVpnUpdateDTO dto){ + //编辑规则 + //根据ID判断是否存在 + CtVpn ctVpn = ctVpnService.getById(dto.getId()); + if(ObjectUtil.isEmpty(ctVpn)){ + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_VPN); + } + + CtVpn updataCtVpn = new CtVpn(); + BeanUtil.copyProperties(dto,updataCtVpn); + return Dto.returnResult(ctVpnService.updateById(updataCtVpn)); + } + + /** + * 根据ID删除VPN信息 + */ + @ApiOperation("根据ID删除VPN信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 2000, message = "VPN信息不存在,或者已删除!") + }) + @Log(value = "根据ID删除VPN信息",type = LogActionType.DELETE) + @PostMapping("/delete") + public Dto delVpn(@Valid @RequestBody IdDTO idDTO){ + //判断删除规则 + //根据ID判断是否存在 + CtVpn ctVpn = ctVpnService.getById(idDTO.getId()); + if(ObjectUtil.isEmpty(ctVpn)){ + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_VPN); + } + return Dto.returnResult(ctVpnService.removeById(idDTO.getId())); + } + + /** + * 获取所有VPN信息 (VPNid VPN名称) + */ + @ApiOperation("获取所有VPN信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "获取所有VPN信息") + @GetMapping("/getAll") + public Dto allVpn() { + List ctVpnList = ctVpnService.list(); + List ctVpnInfoVOList = new ArrayList<>(); + if (ObjectUtil.isNotEmpty(ctVpnList)) { + for (CtVpn ctvpn:ctVpnList) { + CtVpnInfoVO ctVpnInfoVO = new CtVpnInfoVO(); + BeanUtil.copyProperties(ctvpn, ctVpnInfoVO); + ctVpnInfoVOList.add(ctVpnInfoVO); + } + } + return Dto.returnResult(ctVpnInfoVOList); + } + + /** + * EXCEL导入VPN信息 + */ + @ApiOperation("EXCEL导入VPN信息") + @ApiImplicitParams({ + @ApiImplicitParam(value = "上传文件", name = "file", dataType = "__file", required = true) + }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "EXCEL导入VPN信息",type = LogActionType.ADD) + @PostMapping("import") + public Dto importVpn(@RequestPart("file") MultipartFile file, HttpServletResponse response)throws Exception{ + + //TODO 对Excel 信息进行检测 如果不符合要求的 最终要导出错误Excel提示 + List ctVpnImportList = ExcelUtils.readMultipartFile(file,CtVpnImport.class); + if(ObjectUtil.isEmpty(ctVpnImportList)){ + return Dto.returnResult(true); + } + + List addCtVpnList = new ArrayList<>(); + List ipValueList = ctVpnService.getIpList(); + List ctVpnExportList = new ArrayList<>(); + for(CtVpnImport ctVpnImport : ctVpnImportList) { + CtVpnExport ctVpnExport = new CtVpnExport(); + BeanUtil.copyProperties(ctVpnImport, ctVpnExport); + + StringBuffer errorStrBuf = new StringBuffer(); + String rowTips = ctVpnImport.getRowTips(); + if (ObjectUtil.isNotEmpty((rowTips))) { + errorStrBuf.append(rowTips); + errorStrBuf.append(";"); + } + if (ipValueList.contains(ctVpnImport.getIpAddress())) { + errorStrBuf.append("平台已经存在该IP地址对应的VPN信息"); + } + if (ObjectUtil.isNotEmpty(errorStrBuf)) { + ctVpnExport.setError(errorStrBuf.toString()); + ctVpnExportList.add(ctVpnExport); + } else { + CtVpn ctVpn = new CtVpn(); + ctVpn.setStatus(VpnStatusEnum.AVAILABLE.value()); + BeanUtil.copyProperties(ctVpnImport, ctVpn); + addCtVpnList.add(ctVpn); + } + } + + String returnDataStr = null; + String filePath = propertiesConfig.getUploadImgPath().get(PublicConstant.EXPORT_EXCEL_FILE_TYPE); + String fileName = "VPN导入异常信息表-" + snowflake.nextIdStr(); + if(ObjectUtil.isNotEmpty(ctVpnExportList)){ + ExcelUtils.exportFile(SystemConfig.IMG_PATH + filePath, fileName, ctVpnExportList); + returnDataStr = SystemConfig.FILE_VISIT_ADDR + filePath + fileName + ".xlsx"; +// returnDataStr = "http://localhost:8008/file" + filePath + fileName + ".xlsx"; + } + + if(ObjectUtil.isNotEmpty(addCtVpnList)){ + ctVpnService.saveBatch(addCtVpnList); + } + + return Dto.returnResult(returnDataStr); + } + + /** + * Excel导出VPN导入模板 + */ + @ApiOperation("Excel导出VPN导入模板") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "Excel导出VPN导入模板") + @GetMapping("/exportTemp") + @AnonymousAccess + public void exportVpn(HttpServletResponse response) { + ExcelUtils.exportTemplate(response, "VPN导入模板", CtVpnExportTemple.class, true); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/DhAddCarCatchController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/DhAddCarCatchController.java new file mode 100644 index 0000000..224eb9b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/DhAddCarCatchController.java @@ -0,0 +1,409 @@ +package me.zhengjie.modules.group.controller.base; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.DhAddCarOrder; +import me.zhengjie.modules.group.dto.IdDTO; +import me.zhengjie.service.DhAddCarOrderService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * + * @Description 群控管理-敦煌加购-抓单 控制类 + * @Date 2022-06-22 + * @Author rch + */ +@Validated +@RequestMapping("/api/dhAddCarCatch") +@RestController +@RequiredArgsConstructor +@Api(tags = "业务:敦煌加购-抓单管理") +public class DhAddCarCatchController { + + @Resource + private DhAddCarOrderService dhAddCarOrderService; + +// /** +// * 分页查询敦煌加购-抓单 +// */ +// @ApiOperation("分页查询敦煌加购-抓单") +// @ApiResponses(value = { +// @ApiResponse(code = 200, message = "响应成功"), +// @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") +// }) +// @Log("分页查询敦煌加购-抓单") +// @PostMapping("/list") +// public Dto getDhAddCardList(@Valid @RequestBody DhAddCarListDTO dto) { +// PageUtils pageUtilsResult = dhAddCarService.searchPageList(dto.getiPage(), dto.getWrapper()); +// return Dto.returnResult(pageUtilsResult); +// } + +// /** +// * 新增敦煌加购-抓单 +// */ +// @ApiOperation("新增敦煌加购-抓单") +// @ApiResponses(value = { +// @ApiResponse(code = 200, message = "响应成功"), +// @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") +// }) +// @Log(value = "新增敦煌加购-抓单",type = LogActionType.ADD) +// @PostMapping("/add") +// @FormSubmission +// public Dto addDhCar(@Valid @RequestBody DhAddCarAddDTO dto) { +// +// Integer paramsType = dto.getParamsType(); +// List dhCarGoodList = new ArrayList<>(); +// if (ParamsTypeEnum.KEY_WORD.eqValue(paramsType)) { +// List DhCarGoodKeyList = dto.getCarGoodKeys(); +// if (ObjectUtil.isEmpty(DhCarGoodKeyList)) { +// return Dto.getInstance(ErrorCodeEnum.ERROR_ADD_CAR_KEY_NULL); +// } else { +// for (DhCarGoodKeyAddDTO dhCarGoodKeyDTO:DhCarGoodKeyList) { +// DhCarGoods dhCarGoods = new DhCarGoods(); +// BeanUtil.copyProperties(dhCarGoodKeyDTO, dhCarGoods); +// dhCarGoodList.add(dhCarGoods); +// } +// } +// } else if (ParamsTypeEnum.LINK.eqValue(paramsType)) { +// List DhCarGoodLinkList = dto.getCarGoodLinks(); +// if (ObjectUtil.isEmpty(DhCarGoodLinkList)) { +// return Dto.getInstance(ErrorCodeEnum.ERROR_ADD_CAR_LINK_NULL); +// } else { +// for (DhCarGoodLinkAddDTO dhCarGoodLinkDTO:DhCarGoodLinkList) { +// DhCarGoods dhCarGoods = new DhCarGoods(); +// BeanUtil.copyProperties(dhCarGoodLinkDTO, dhCarGoods); +// dhCarGoodList.add(dhCarGoods); +// } +// } +// } else { +// return Dto.getInstance(ErrorCodeEnum.ERROR_ADD_CAR_GOODS_NULL); +// } +// +// // service 层 分别存储两个表信息 +// Boolean resultBoolean = dhCarGoodsService.saveBatch(dhCarGoodList); +// if (resultBoolean) { +// List goodsIdList = dhCarGoodList.stream().map(DhCarGoods::getId).collect(Collectors.toList()); +// +// DhAddCar dhAddCar = new DhAddCar(); +// BeanUtil.copyProperties(dto, dhAddCar); +// dhAddCar.setCarGoodIds(Joiner.on(",").join(goodsIdList)); +// resultBoolean = dhAddCarService.save(dhAddCar); +// } +// +// return Dto.returnResult(resultBoolean); +// } + + /** + * 根据id获取刷单信息 + */ + @ApiOperation("根据id获取刷单信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据id获取刷单信息") + @PostMapping("/getById") + public Dto getById(@Valid @RequestBody IdDTO idDTO) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("add_car_id", idDTO.getId()); + return Dto.returnResult(dhAddCarOrderService.getOne(queryWrapper)); + } + +// /** +// * 根据id获取修改回显信息 +// */ +// @ApiOperation("根据id获取修改回显信息") +// @ApiResponses(value = { +// @ApiResponse(code = 200, message = "响应成功"), +// @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") +// }) +// @Log("根据id获取修改回显信息") +// @PostMapping("/getEditDetailById") +// public Dto getEditDetailById(@Valid @RequestBody IdDTO idDTO) { +// return Dto.returnResult(dhAddCarService.getDetailById(idDTO.getId())); +// } +// +// /** +// * 根据id删除刷单信息 +// * @author: rch +// */ +// @ApiOperation("根据id删除敦煌加购-抓单") +// @ApiResponses(value = { +// @ApiResponse(code = 200, message = "响应成功"), +// @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), +// @ApiResponse(code = 4404, message = "敦煌加购-抓单信息不存在,或者已删除或异常!"), +// @ApiResponse(code = 3901, message = "只有待执行的刷单信息才允许删除!") +// }) +// @Log(value = "根据id删除刷单信息",type = LogActionType.DELETE) +// @PostMapping("/delete") +// public Dto delClickFarming(@Valid @RequestBody IdDTO idDTO) { +// +// // 先查询 +// DhAddCar dhAddCar = dhAddCarService.getById(idDTO.getId()); +// if (ObjectUtil.isEmpty(dhAddCar)) { +// return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_ADD_CAR_INFO); +// } +// +// if (!DhAddCarStatusEnum.TOBE_EXECUTION.eqValue(dhAddCar.getStatus())) { +// return Dto.getInstance(ErrorCodeEnum.ERROR_DEL_ADD_CAR_INFO); +// } +// +// Boolean resultBoolean = false; +// if (dhAddCarService.removeById(idDTO.getId())) { +// String goodIds = dhAddCar.getCarGoodIds(); +// List goodIdList = new ArrayList<>(); +// if (goodIds.contains(",")){ +// goodIdList = Arrays.asList(goodIds.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList()); +// }else { +// goodIdList.add(Long.valueOf(goodIds)); +// } +// resultBoolean = dhCarGoodsService.removeByIds(goodIdList); +// } +// +// return Dto.returnResult(resultBoolean); +// } +// +// /** +// * 编辑刷单信息 +// */ +// @ApiOperation("编辑敦煌加购-抓单") +// @ApiResponses(value = { +// @ApiResponse(code = 200, message = "响应成功"), +// @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), +// @ApiResponse(code = 4404, message ="敦煌加购-抓单信息不存在!") +// }) +// @Log(value = "编辑敦煌加购-抓单",type = LogActionType.UPDATE) +// @PostMapping("/edit") +// @FormSubmission +// public Dto editDhAddCar(@Valid @RequestBody DhAddCarEditDTO dto) { +// +// DhAddCar dhAddCar = dhAddCarService.getById(dto.getId()); +// if (ObjectUtil.isEmpty(dhAddCar)) { +// return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_ADD_CAR_INFO); +// } +// +// if (!DhAddCarStatusEnum.TOBE_EXECUTION.eqValue(dhAddCar.getStatus())) { +// return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_EDIT_ADD_CAR_INFO); +// } +// +// // 关键词 +// BeanUtil.copyProperties(dto, dhAddCar); +// List dhCarGoodList = new ArrayList<>(); +// Boolean result = false; +// if (ParamsTypeEnum.KEY_WORD.value().equals(dto.getParamsType())) { +// List carGoodKeys = dto.getCarGoodKeys(); +// for (DhCarGoodKeyEditDTO dhCarGoodKeyEditDTO:carGoodKeys) { +// DhCarGoods dhCarGoods = new DhCarGoods(); +// BeanUtil.copyProperties(dhCarGoodKeyEditDTO, dhCarGoods); +// dhCarGoodList.add(dhCarGoods); +// } +// } +// // 链接 +// if (ParamsTypeEnum.LINK.value().equals(dto.getParamsType())) { +// List carGoodLinks = dto.getCarGoodLinks(); +// for (DhCarGoodLinkEditDTO dhCarGoodLinkEditDTO:carGoodLinks) { +// DhCarGoods dhCarGoods = new DhCarGoods(); +// BeanUtil.copyProperties(dhCarGoodLinkEditDTO, dhCarGoods); +// dhCarGoodList.add(dhCarGoods); +// } +// } +// if (ObjectUtil.isNotEmpty(dhCarGoodList)) { +// if (dhCarGoodsService.saveOrUpdateBatch(dhCarGoodList)) { +// String dhCarGoodIdStr = Joiner.on(",").join(dhCarGoodList.stream().map(DhCarGoods::getId).collect(Collectors.toList())); +// dhAddCar.setCarGoodIds(dhCarGoodIdStr); +// result = dhAddCarService.updateById(dhAddCar); +// } +// } +// +// return Dto.returnResult(result); +// } +// +// +// /** +// * 下单成功(加购-抓单成功状态 手动转下单成功) +// * @param idDTO +// * @return +// */ +// @ApiOperation("下单成功") +// @ApiResponses(value = { +// @ApiResponse(code = 200, message = "响应成功"), +// @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), +// @ApiResponse(code = 4404, message ="敦煌加购-抓单信息不存在!") +// }) +// @Log(value = "下单成功",type = LogActionType.UPDATE) +// @PostMapping("/orderSuccess") +// @FormSubmission +// public Dto orderSuccess(@Valid @RequestBody IdDTO idDTO) { +// DhAddCar dhAddCar = dhAddCarService.getByIdLock(idDTO.getId()); +// if (ObjectUtil.isEmpty(dhAddCar)) { +// return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_ADD_CAR_INFO); +// } +// +// DhAddCar updateDhAddCar = new DhAddCar(); +// updateDhAddCar.setId(dhAddCar.getId()); +// updateDhAddCar.setStatus(DhAddCarStatusEnum.ORDER_SUCCESS.value()); +// return Dto.returnResult(dhAddCarService.updateById(updateDhAddCar)); +// } +// +// /** +// * 支付成功(下单成功状态 手动转支付成功) +// * @param idDTO +// * @return +// */ +// @ApiOperation("支付成功") +// @ApiResponses(value = { +// @ApiResponse(code = 200, message = "响应成功"), +// @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), +// @ApiResponse(code = 4404, message ="敦煌加购-抓单信息不存在!") +// }) +// @Log(value = "支付成功",type = LogActionType.UPDATE) +// @PostMapping("/toBeCatch") +// @FormSubmission +// public Dto toBeCatch(@Valid @RequestBody IdDTO idDTO) { +// DhAddCar dhAddCar = dhAddCarService.getByIdLock(idDTO.getId()); +// if (ObjectUtil.isEmpty(dhAddCar)) { +// return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_ADD_CAR_INFO); +// } +// +// DhAddCar updateDhAddCar = new DhAddCar(); +// updateDhAddCar.setId(dhAddCar.getId()); +// updateDhAddCar.setStatus(DhAddCarStatusEnum.TO_BE_CATCH_ORDER.value()); +// return Dto.returnResult(dhAddCarService.updateById(updateDhAddCar)); +// } + +// +// /** +// * +// * @param file +// * @param response +// * @return +// * @throws Exception +// */ +// @ApiOperation("Excel刷单信息导入") +// @ApiImplicitParams({ +// @ApiImplicitParam(value = "上传文件", name = "file", dataType = "__file", required = true) +// }) +// @ApiResponses(value = { +// @ApiResponse(code = 200, message = "响应成功"), +// @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") +// }) +// @Log(value = "Excel刷单信息导入",type = LogActionType.ADD) +// @PostMapping("/import") +// public Dto importClickFarming(@RequestPart("file")MultipartFile file, HttpServletResponse response) throws Exception { +// +// // TODO 对Excel 信息进行检测 如果不符合要求的 最终要导出错误Excel提示 +// List ctClickFarmingImportList = ExcelUtils.readMultipartFile(file, CtClickFarmingImport.class); +// if (ObjectUtil.isEmpty(ctClickFarmingImportList)) { +// return Dto.returnResult(true); +// } +// +// List addCtClickFarmingList = new ArrayList<>(); +// List ctClickFarmingExportList = new ArrayList<>(); +// +// // 买家id +// List buyerAccountList = ctClickFarmingImportList.stream().map(c->c.getAccount()).collect(Collectors.toList()); +// Map buyerMap = ctBuyerService.getBuyerList(buyerAccountList); +// +// for (CtClickFarmingImport ctClickFarmingImport:ctClickFarmingImportList) { +// CtClickFarmingExport ctClickFarmingExport = new CtClickFarmingExport(); +// BeanUtil.copyProperties(ctClickFarmingImport, ctClickFarmingExport); +// +// StringBuffer errorStrBuf = new StringBuffer(); +// String rowTips = ctClickFarmingImport.getRowTips(); +// if (ObjectUtil.isNotEmpty(rowTips)) { +// errorStrBuf.append(rowTips); +// errorStrBuf.append(";"); +// } +// +// if (ObjectUtil.isEmpty(ctClickFarmingImport.getSpecification())) { +// errorStrBuf.append("规格-必填!"); +// errorStrBuf.append(";"); +// } +// if (ObjectUtil.isEmpty(ctClickFarmingImport.getColor())) { +// errorStrBuf.append("颜色-必填!"); +// errorStrBuf.append(";"); +// } +// if (ObjectUtil.isEmpty(ctClickFarmingImport.getExchange())) { +// errorStrBuf.append("优惠劵-必填!"); +// errorStrBuf.append(";"); +// } +// +// // 判断类型 +// if (ParamsTypeEnum.KEY_WORD.eqValue(ctClickFarmingImport.getParamsType())) { +// if (ObjectUtil.isEmpty(ctClickFarmingImport.getKeyWord())) { +// errorStrBuf.append("关键词-必填!"); +// errorStrBuf.append(";"); +// } +// if (ObjectUtil.isEmpty(ctClickFarmingImport.getTitle())) { +// errorStrBuf.append("标题-必填!"); +// errorStrBuf.append(";"); +// } +// if (ObjectUtil.isEmpty(ctClickFarmingImport.getItem())) { +// errorStrBuf.append("item-必填!"); +// errorStrBuf.append(";"); +// } +// } else { +// if (ObjectUtil.isEmpty(ctClickFarmingImport.getLink())) { +// errorStrBuf.append("链接-必填!"); +// errorStrBuf.append(";"); +// } +// } +// +// if (ObjectUtil.isEmpty(buyerMap) || !buyerMap.containsKey(ctClickFarmingImport.getAccount())) { +// errorStrBuf.append("买家信息不存在!"); +// errorStrBuf.append(";"); +// } else { +// Long buyerId = buyerMap.entrySet().stream().collect(Collectors.toMap(entity -> entity.getKey(), entity -> entity.getValue())).get(ctClickFarmingImport.getAccount()).getId(); +// ctClickFarmingImport.setBuyerId(buyerId); +// } +// if (ObjectUtil.isNotEmpty(errorStrBuf)) { +// ctClickFarmingExport.setError(errorStrBuf.toString()); +// ctClickFarmingExportList.add(ctClickFarmingExport); +// } else { +// CtClickFarming ctClickFarming = new CtClickFarming(); +// BeanUtils.copyProperties(ctClickFarmingImport, ctClickFarming); +// addCtClickFarmingList.add(ctClickFarming); +// } +// } +// +// String returnDataStr = null; +// String filePath = propertiesConfig.getUploadImgPath().get(PublicConstant.EXPORT_EXCEL_FILE_TYPE); +// String fileName = "刷单信息导入异常信息表-" + snowflake.nextIdStr(); +// if (ObjectUtil.isNotEmpty(ctClickFarmingExportList)) { +// ExcelUtils.exportFile(SystemConfig.IMG_PATH + filePath, fileName, ctClickFarmingExportList); +// returnDataStr = SystemConfig.FILE_VISIT_ADDR + filePath + fileName + ".xlsx"; +//// returnDataStr = "http://localhost:8008/file" + filePath + fileName + ".xlsx"; +// } +// +// if (ObjectUtil.isNotEmpty(addCtClickFarmingList)) { +// ctClickFarmingService.saveBatch(addCtClickFarmingList); +// } +// +// return Dto.returnResult(returnDataStr); +// } +// +// @ApiOperation("Excel刷单信息模版导出") +// @ApiResponses(value = { +// @ApiResponse(code = 200, message = "响应成功"), +// @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") +// }) +// @Log(value = "Excel刷单信息模版导出") +// @GetMapping("/exportTemp") +// @AnonymousAccess +// public void importClickFarming(HttpServletResponse response) { +// ExcelUtils.exportTemplate(response, "刷单信息模版", CtClickFarmingExportTemp.class); +// } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/DhAddCarController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/DhAddCarController.java new file mode 100644 index 0000000..dfc9a72 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/DhAddCarController.java @@ -0,0 +1,466 @@ +package me.zhengjie.modules.group.controller.base; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import com.google.common.base.Joiner; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.FormSubmission; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.DhAddCar; +import me.zhengjie.entity.DhCarGoods; +import me.zhengjie.enums.DhAddCarStatusEnum; +import me.zhengjie.enums.ParamsTypeEnum; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.group.dto.DhCarWellReceivedDTO; +import me.zhengjie.modules.group.dto.IdDTO; +import me.zhengjie.modules.group.dto.DhCarGoodWellReceivedDTO; +import me.zhengjie.modules.group.dto.dhaddcar.DhAddCarAddDTO; +import me.zhengjie.modules.group.dto.dhaddcar.DhAddCarEditDTO; +import me.zhengjie.modules.group.dto.dhaddcar.DhAddCarListDTO; +import me.zhengjie.modules.group.dto.dhcargood.*; +import me.zhengjie.service.DhAddCarService; +import me.zhengjie.service.DhCarGoodsService; +import me.zhengjie.service.vo.dhaddcar.DhAddCarListVO; +import me.zhengjie.service.vo.dhaddcar.DhAddCarVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * + * @Description 群控管理-敦煌加购 控制类 + * @Date 2022-06-22 + * @Author rch + */ +@Validated +@RequestMapping("/api/dhAddCar") +@RestController +@RequiredArgsConstructor +@Api(tags = "业务:敦煌加购管理") +public class DhAddCarController { + + @Resource + private DhCarGoodsService dhCarGoodsService; + @Resource + private DhAddCarService dhAddCarService; + + /** + * 分页查询敦煌加购 + */ + @ApiOperation("分页查询敦煌加购") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询敦煌加购") + @PostMapping("/list") + public Dto getDhAddCardList(@Valid @RequestBody DhAddCarListDTO dto) { + PageUtils pageUtilsResult = dhAddCarService.searchPageList(dto.getiPage(), dto.getWrapper()); + return Dto.returnResult(pageUtilsResult); + } + + /** + * 新增敦煌加购 + */ + @ApiOperation("新增敦煌加购") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log(value = "新增敦煌加购",type = LogActionType.ADD) + @PostMapping("/add") + @FormSubmission + public Dto addDhCar(@Valid @RequestBody DhAddCarAddDTO dto) { + + Integer paramsType = dto.getParamsType(); + List dhCarGoodList = new ArrayList<>(); + if (ParamsTypeEnum.KEY_WORD.eqValue(paramsType)) { + List DhCarGoodKeyList = dto.getCarGoodKeys(); + if (ObjectUtil.isEmpty(DhCarGoodKeyList)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_ADD_CAR_KEY_NULL); + } else { + for (DhCarGoodKeyAddDTO dhCarGoodKeyDTO:DhCarGoodKeyList) { + DhCarGoods dhCarGoods = new DhCarGoods(); + BeanUtil.copyProperties(dhCarGoodKeyDTO, dhCarGoods); + dhCarGoodList.add(dhCarGoods); + } + } + } else if (ParamsTypeEnum.LINK.eqValue(paramsType)) { + List DhCarGoodLinkList = dto.getCarGoodLinks(); + if (ObjectUtil.isEmpty(DhCarGoodLinkList)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_ADD_CAR_LINK_NULL); + } else { + for (DhCarGoodLinkAddDTO dhCarGoodLinkDTO:DhCarGoodLinkList) { + DhCarGoods dhCarGoods = new DhCarGoods(); + BeanUtil.copyProperties(dhCarGoodLinkDTO, dhCarGoods); + dhCarGoodList.add(dhCarGoods); + } + } + } else { + return Dto.getInstance(ErrorCodeEnum.ERROR_ADD_CAR_GOODS_NULL); + } + + // service 层 分别存储两个表信息 + Boolean resultBoolean = dhCarGoodsService.saveBatch(dhCarGoodList); + if (resultBoolean) { + List goodsIdList = dhCarGoodList.stream().map(DhCarGoods::getId).collect(Collectors.toList()); + + DhAddCar dhAddCar = new DhAddCar(); + BeanUtil.copyProperties(dto, dhAddCar); + dhAddCar.setCarGoodIds(Joiner.on(",").join(goodsIdList)); + resultBoolean = dhAddCarService.save(dhAddCar); + } + + return Dto.returnResult(resultBoolean); + } + +// /** +// * 根据id获取刷单信息 +// */ +// @ApiOperation("根据id获取刷单信息") +// @ApiResponses(value = { +// @ApiResponse(code = 200, message = "响应成功"), +// @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") +// }) +// @Log("根据id获取刷单信息") +// @PostMapping("/getById") +// public Dto getById(@Valid @RequestBody IdDTO idDTO) { +// return Dto.returnResult(ctClickFarmingService.getDetailById(idDTO.getId())); +// } +// + /** + * 根据id获取修改回显信息 + */ + @ApiOperation("根据id获取修改回显信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据id获取修改回显信息") + @PostMapping("/getEditDetailById") + public Dto getEditDetailById(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(dhAddCarService.getDetailById(idDTO.getId())); + } + + /** + * 根据id删除刷单信息 + * @author: rch + */ + @ApiOperation("根据id删除敦煌加购") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 4404, message = "敦煌加购信息不存在,或者已删除或异常!"), + @ApiResponse(code = 3901, message = "只有待执行的刷单信息才允许删除!") + }) + @Log(value = "根据id删除刷单信息",type = LogActionType.DELETE) + @PostMapping("/delete") + public Dto delClickFarming(@Valid @RequestBody IdDTO idDTO) { + + // 先查询 + DhAddCar dhAddCar = dhAddCarService.getById(idDTO.getId()); + if (ObjectUtil.isEmpty(dhAddCar)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_ADD_CAR_INFO); + } + + if (!DhAddCarStatusEnum.TOBE_EXECUTION.eqValue(dhAddCar.getStatus())) { + return Dto.getInstance(ErrorCodeEnum.ERROR_DEL_ADD_CAR_INFO); + } + + Boolean resultBoolean = false; + if (dhAddCarService.removeById(idDTO.getId())) { + String goodIds = dhAddCar.getCarGoodIds(); + List goodIdList = new ArrayList<>(); + if (goodIds.contains(",")){ + goodIdList = Arrays.asList(goodIds.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList()); + }else { + goodIdList.add(Long.valueOf(goodIds)); + } + resultBoolean = dhCarGoodsService.removeByIds(goodIdList); + } + + return Dto.returnResult(resultBoolean); + } + + /** + * 编辑刷单信息 + */ + @ApiOperation("编辑敦煌加购") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 4404, message ="敦煌加购信息不存在!") + }) + @Log(value = "编辑敦煌加购",type = LogActionType.UPDATE) + @PostMapping("/edit") + @FormSubmission + public Dto editDhAddCar(@Valid @RequestBody DhAddCarEditDTO dto) { + + DhAddCar dhAddCar = dhAddCarService.getById(dto.getId()); + if (ObjectUtil.isEmpty(dhAddCar)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_ADD_CAR_INFO); + } + + if (!DhAddCarStatusEnum.TOBE_EXECUTION.eqValue(dhAddCar.getStatus())) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_EDIT_ADD_CAR_INFO); + } + + // 关键词 + BeanUtil.copyProperties(dto, dhAddCar); + List dhCarGoodList = new ArrayList<>(); + Boolean result = false; + if (ParamsTypeEnum.KEY_WORD.value().equals(dto.getParamsType())) { + List carGoodKeys = dto.getCarGoodKeys(); + for (DhCarGoodKeyEditDTO dhCarGoodKeyEditDTO:carGoodKeys) { + DhCarGoods dhCarGoods = new DhCarGoods(); + BeanUtil.copyProperties(dhCarGoodKeyEditDTO, dhCarGoods); + dhCarGoodList.add(dhCarGoods); + } + } + // 链接 + if (ParamsTypeEnum.LINK.value().equals(dto.getParamsType())) { + List carGoodLinks = dto.getCarGoodLinks(); + for (DhCarGoodLinkEditDTO dhCarGoodLinkEditDTO:carGoodLinks) { + DhCarGoods dhCarGoods = new DhCarGoods(); + BeanUtil.copyProperties(dhCarGoodLinkEditDTO, dhCarGoods); + dhCarGoodList.add(dhCarGoods); + } + } + if (ObjectUtil.isNotEmpty(dhCarGoodList)) { + if (dhCarGoodsService.saveOrUpdateBatch(dhCarGoodList)) { + String dhCarGoodIdStr = Joiner.on(",").join(dhCarGoodList.stream().map(DhCarGoods::getId).collect(Collectors.toList())); + dhAddCar.setCarGoodIds(dhCarGoodIdStr); + result = dhAddCarService.updateById(dhAddCar); + } + } + + return Dto.returnResult(result); + } + + + /** + * 下单成功(加购成功状态 手动转下单成功) + * @param idDTO + * @return + */ + @ApiOperation("下单成功") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 4404, message ="敦煌加购信息不存在!") + }) + @Log(value = "下单成功",type = LogActionType.UPDATE) + @PostMapping("/orderSuccess") + @FormSubmission + public Dto orderSuccess(@Valid @RequestBody IdDTO idDTO) { + DhAddCar dhAddCar = dhAddCarService.getByIdLock(idDTO.getId()); + if (ObjectUtil.isEmpty(dhAddCar)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_ADD_CAR_INFO); + } + + DhAddCar updateDhAddCar = new DhAddCar(); + updateDhAddCar.setId(dhAddCar.getId()); + updateDhAddCar.setStatus(DhAddCarStatusEnum.ORDER_SUCCESS.value()); + return Dto.returnResult(dhAddCarService.updateById(updateDhAddCar)); + } + + /** + * 支付成功(下单成功状态 手动转支付成功) + * @param idDTO + * @return + */ + @ApiOperation("支付成功") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 4404, message ="敦煌加购信息不存在!") + }) + @Log(value = "支付成功",type = LogActionType.UPDATE) + @PostMapping("/toBeCatch") + @FormSubmission + public Dto toBeCatch(@Valid @RequestBody IdDTO idDTO) { + DhAddCar dhAddCar = dhAddCarService.getByIdLock(idDTO.getId()); + if (ObjectUtil.isEmpty(dhAddCar)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_ADD_CAR_INFO); + } + + DhAddCar updateDhAddCar = new DhAddCar(); + updateDhAddCar.setId(dhAddCar.getId()); + updateDhAddCar.setStatus(DhAddCarStatusEnum.TO_BE_CATCH_ORDER.value()); + return Dto.returnResult(dhAddCarService.updateById(updateDhAddCar)); + } + + /** + * 好评 + * @param dto + * @return + */ + @ApiOperation("好评") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 4404, message ="敦煌加购信息不存在!") + }) + @Log(value = "好评",type = LogActionType.UPDATE) + @PostMapping("/wellReceive") + @FormSubmission + public Dto wellReceived(@Valid @RequestBody DhCarWellReceivedDTO dto) { + + + DhAddCar dhAddCar = dhAddCarService.getByIdLock(dto.getId()); + if (ObjectUtil.isEmpty(dhAddCar)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_ADD_CAR_INFO); + } + + if (!DhAddCarStatusEnum.CATCH_ORDER_SUCCESS.eqValue(dhAddCar.getStatus())) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_WELL_RECEIVED_ADD_CAR_INFO); + } + + List goods = dto.getDialogWellReceivedGoods(); + List dhCarGoodsList = new ArrayList<>(); + for (DhCarGoodWellReceivedDTO good :goods) { + DhCarGoods dhCarGoods = new DhCarGoods(); + BeanUtil.copyProperties(good, dhCarGoods); + dhCarGoodsList.add(dhCarGoods); + } + return Dto.returnResult(dhCarGoodsService.updateBatchById(dhCarGoodsList)); + } +// +// /** +// * +// * @param file +// * @param response +// * @return +// * @throws Exception +// */ +// @ApiOperation("Excel刷单信息导入") +// @ApiImplicitParams({ +// @ApiImplicitParam(value = "上传文件", name = "file", dataType = "__file", required = true) +// }) +// @ApiResponses(value = { +// @ApiResponse(code = 200, message = "响应成功"), +// @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") +// }) +// @Log(value = "Excel刷单信息导入",type = LogActionType.ADD) +// @PostMapping("/import") +// public Dto importClickFarming(@RequestPart("file")MultipartFile file, HttpServletResponse response) throws Exception { +// +// // TODO 对Excel 信息进行检测 如果不符合要求的 最终要导出错误Excel提示 +// List ctClickFarmingImportList = ExcelUtils.readMultipartFile(file, CtClickFarmingImport.class); +// if (ObjectUtil.isEmpty(ctClickFarmingImportList)) { +// return Dto.returnResult(true); +// } +// +// List addCtClickFarmingList = new ArrayList<>(); +// List ctClickFarmingExportList = new ArrayList<>(); +// +// // 买家id +// List buyerAccountList = ctClickFarmingImportList.stream().map(c->c.getAccount()).collect(Collectors.toList()); +// Map buyerMap = ctBuyerService.getBuyerList(buyerAccountList); +// +// for (CtClickFarmingImport ctClickFarmingImport:ctClickFarmingImportList) { +// CtClickFarmingExport ctClickFarmingExport = new CtClickFarmingExport(); +// BeanUtil.copyProperties(ctClickFarmingImport, ctClickFarmingExport); +// +// StringBuffer errorStrBuf = new StringBuffer(); +// String rowTips = ctClickFarmingImport.getRowTips(); +// if (ObjectUtil.isNotEmpty(rowTips)) { +// errorStrBuf.append(rowTips); +// errorStrBuf.append(";"); +// } +// +// if (ObjectUtil.isEmpty(ctClickFarmingImport.getSpecification())) { +// errorStrBuf.append("规格-必填!"); +// errorStrBuf.append(";"); +// } +// if (ObjectUtil.isEmpty(ctClickFarmingImport.getColor())) { +// errorStrBuf.append("颜色-必填!"); +// errorStrBuf.append(";"); +// } +// if (ObjectUtil.isEmpty(ctClickFarmingImport.getExchange())) { +// errorStrBuf.append("优惠劵-必填!"); +// errorStrBuf.append(";"); +// } +// +// // 判断类型 +// if (ParamsTypeEnum.KEY_WORD.eqValue(ctClickFarmingImport.getParamsType())) { +// if (ObjectUtil.isEmpty(ctClickFarmingImport.getKeyWord())) { +// errorStrBuf.append("关键词-必填!"); +// errorStrBuf.append(";"); +// } +// if (ObjectUtil.isEmpty(ctClickFarmingImport.getTitle())) { +// errorStrBuf.append("标题-必填!"); +// errorStrBuf.append(";"); +// } +// if (ObjectUtil.isEmpty(ctClickFarmingImport.getItem())) { +// errorStrBuf.append("item-必填!"); +// errorStrBuf.append(";"); +// } +// } else { +// if (ObjectUtil.isEmpty(ctClickFarmingImport.getLink())) { +// errorStrBuf.append("链接-必填!"); +// errorStrBuf.append(";"); +// } +// } +// +// if (ObjectUtil.isEmpty(buyerMap) || !buyerMap.containsKey(ctClickFarmingImport.getAccount())) { +// errorStrBuf.append("买家信息不存在!"); +// errorStrBuf.append(";"); +// } else { +// Long buyerId = buyerMap.entrySet().stream().collect(Collectors.toMap(entity -> entity.getKey(), entity -> entity.getValue())).get(ctClickFarmingImport.getAccount()).getId(); +// ctClickFarmingImport.setBuyerId(buyerId); +// } +// if (ObjectUtil.isNotEmpty(errorStrBuf)) { +// ctClickFarmingExport.setError(errorStrBuf.toString()); +// ctClickFarmingExportList.add(ctClickFarmingExport); +// } else { +// CtClickFarming ctClickFarming = new CtClickFarming(); +// BeanUtils.copyProperties(ctClickFarmingImport, ctClickFarming); +// addCtClickFarmingList.add(ctClickFarming); +// } +// } +// +// String returnDataStr = null; +// String filePath = propertiesConfig.getUploadImgPath().get(PublicConstant.EXPORT_EXCEL_FILE_TYPE); +// String fileName = "刷单信息导入异常信息表-" + snowflake.nextIdStr(); +// if (ObjectUtil.isNotEmpty(ctClickFarmingExportList)) { +// ExcelUtils.exportFile(SystemConfig.IMG_PATH + filePath, fileName, ctClickFarmingExportList); +// returnDataStr = SystemConfig.FILE_VISIT_ADDR + filePath + fileName + ".xlsx"; +//// returnDataStr = "http://localhost:8008/file" + filePath + fileName + ".xlsx"; +// } +// +// if (ObjectUtil.isNotEmpty(addCtClickFarmingList)) { +// ctClickFarmingService.saveBatch(addCtClickFarmingList); +// } +// +// return Dto.returnResult(returnDataStr); +// } +// +// @ApiOperation("Excel刷单信息模版导出") +// @ApiResponses(value = { +// @ApiResponse(code = 200, message = "响应成功"), +// @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") +// }) +// @Log(value = "Excel刷单信息模版导出") +// @GetMapping("/exportTemp") +// @AnonymousAccess +// public void importClickFarming(HttpServletResponse response) { +// ExcelUtils.exportTemplate(response, "刷单信息模版", CtClickFarmingExportTemp.class); +// } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/DhAddCarOrderController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/DhAddCarOrderController.java new file mode 100644 index 0000000..0617e82 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/DhAddCarOrderController.java @@ -0,0 +1,57 @@ +package me.zhengjie.modules.group.controller.base; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.dto.Dto; +import me.zhengjie.modules.group.dto.dhaddcar.DhAddCarListDTO; +import me.zhengjie.modules.group.dto.dhcarorder.DhAddCarOrderListDTO; +import me.zhengjie.service.DhAddCarOrderService; +import me.zhengjie.service.DhAddCarService; +import me.zhengjie.service.DhCarGoodsService; +import me.zhengjie.service.vo.dhaddcar.DhAddCarListVO; +import me.zhengjie.service.vo.dhcarorder.DhAddCarOrderListVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * + * @Description 群控管理-敦煌加购-订单 控制类 + * @Date 2022-06-22 + * @Author rch + */ +@Validated +@RequestMapping("/api/dhAddCarOrder") +@RestController +@RequiredArgsConstructor +@Api(tags = "业务:敦煌加购订单管理") +public class DhAddCarOrderController { + + @Resource + private DhAddCarOrderService dhAddCarOrderService; + + /** + * 分页查询敦煌加购 + */ + @ApiOperation("分页查询敦煌加购") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询敦煌加购") + @PostMapping("/list") + public Dto getDhAddCardList(@Valid @RequestBody DhAddCarOrderListDTO dto) { + PageUtils pageUtilsResult = dhAddCarOrderService.searchPageList(dto.getiPage(), dto.getWrapper()); + return Dto.returnResult(pageUtilsResult); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/QuartzLogController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/QuartzLogController.java new file mode 100644 index 0000000..5f3ed6c --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/QuartzLogController.java @@ -0,0 +1,55 @@ +package me.zhengjie.modules.group.controller.base; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.dto.Dto; +import me.zhengjie.modules.group.dto.SysQuartzLogListDTO; +import me.zhengjie.service.SysQuartzLogService; +import me.zhengjie.service.vo.SysQuartzLogListVO; +import me.zhengjie.utils.PageUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + + +/** + * + * @Description 群控管理-影刀定时器-日志模块 + * @Date 2022-07-20 + * @Author rch + */ +@Validated +@RequestMapping("/api/quartzLog") +@RestController +@RequiredArgsConstructor +@Api(tags = "业务:影刀定时任务日志管理") +public class QuartzLogController { + + @Resource + private SysQuartzLogService sysQuartzLogService; + /** + * 分页查询影刀日志信息 + */ + @ApiOperation("分页查询影刀日志信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询影刀任务信息") + @AnonymousAccess + @PostMapping("/list") + public Dto getLogsList(@Valid @RequestBody SysQuartzLogListDTO dto) { + PageUtils pageUtilsResult= sysQuartzLogService.searchPageList(dto.getiPage(), dto.getWrapper()); + return Dto.returnResult(pageUtilsResult); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/SdsController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/SdsController.java new file mode 100644 index 0000000..83943bf --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/SdsController.java @@ -0,0 +1,320 @@ +package me.zhengjie.modules.group.controller.base; + + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.dto.Dto; +import me.zhengjie.service.vo.CtApplyListVO; +import me.zhengjie.utils.HttpClientUtil; +import me.zhengjie.utils.MD5Util; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +/** + * Author: rch + * Data: 2022-11-21 + * Description SDS验签 + */ +@Validated +@RequestMapping("/api/sds") +@RestController +@Api(tags = "业务:SDS验签") +public class SdsController { + + String sdsUrlPro = "https://merchantapi.sdspod.com"; + String sdsUrlTest = "https://merchantapitest.sdspod.com"; + String appId = "LPE3NKxile1dr0TGW5hOyFzfc8S4tBUR"; + String appsecret = "DNZlt9UYOAcwCx3evHEM7nr8kuz1XRGsWjJyQpKFq5SdPf0oabBm46hVgiT2LIHViRkIFojPUV7O4FM5SQZsivJ734X7YgPBuYgyH85OUoGzbzj9Wa1Smd1AYC4GyUHA"; + + // 上传图片接口 +// @ApiOperation("上传图片接口") +// @Log("上传图片接口") +// @PostMapping("/url") +// @AnonymousAccess +// public Dto url(@Valid @RequestBody ImageUrlDTO dto){ +// +// return Dto.returnErrorResult("true"); +// } + + @ApiOperation("获取可设计产品的信息") + @Log("获取可设计产品的信息") + @GetMapping("/products") + @AnonymousAccess + public Dto products(@RequestParam(value = "page") Integer page, + @RequestParam(value = "size") Integer size){ + + // sdsUrlTest + Long millisTime = System.currentTimeMillis(); + String url = "/gateway/products/design_infos"; + Map map = new HashMap<>(); + map.put("page", page); + map.put("size", size); + map.put("_timestamp", millisTime); + + String sign = getSign(map); + System.out.println("生成sign的url:" + sign); + String md5Sign = MD5Util.md5(sign); + System.out.println("生成的sign:" + md5Sign); + map.clear(); + map.put("_appid", appId); + map.put("_timestamp", millisTime); + map.put("_sign", md5Sign); + map.put("page", page); + map.put("size", size); + + String realStrUrl = sdsUrlPro + url; + String returnStr = HttpClientUtil.getHttp(realStrUrl, map); + System.out.println("获取可设计产品的信息:" + returnStr); + return Dto.returnErrorResult(returnStr); + } + + @ApiOperation("获取产品详情") + @Log("获取产品详情") + @GetMapping("/productsDetail") + @AnonymousAccess + public Dto products(@RequestParam Integer id){ + + // sdsUrlTest + Long millisTime = System.currentTimeMillis(); + String url = "/gateway/products/" + id; + Map map = new HashMap<>(); + map.put("_timestamp", millisTime); + + String sign = getSign(map); + System.out.println("生成sign的url:" + sign); + String md5Sign = MD5Util.md5(sign); + System.out.println("生成的sign:" + md5Sign); + map.clear(); + map.put("_sign", md5Sign); + map.put("_timestamp", millisTime); + map.put("_appid", appId); + + String realStrUrl = sdsUrlPro + url; + String returnStr = HttpClientUtil.getHttp(realStrUrl, map); + System.out.println("获取产品详情:" + returnStr); + return Dto.returnErrorResult(returnStr); + } + + + @ApiOperation("获取成品列表") + @Log("获取成品列表") + @GetMapping("/endproducts") + @AnonymousAccess + public Dto endproducts(@RequestParam(value = "page") Integer page, + @RequestParam(value = "size") Integer size, + @RequestParam(value = "userId", required = false) Long userId, + @RequestParam(value = "designProductType", required = false) String designProductType){ + + // sdsUrlTest + Long millisTime = System.currentTimeMillis(); + String url = "/gateway/endproducts"; + Map map = new HashMap<>(); + map.put("page", page); + map.put("size", size); + map.put("_timestamp", millisTime); +// map.put("userId", page); +// map.put("designProductType", "SINGLE"); + + String sign = getSign(map); + System.out.println("生成sign的url:" + sign); + String md5Sign = MD5Util.md5(sign); + System.out.println("生成的sign:" + md5Sign); + map.clear(); + map.put("_appid", appId); + map.put("_timestamp", millisTime); + map.put("_sign", md5Sign); + map.put("page", page); + map.put("size", size); +// map.put("designProductType", "SINGLE"); + + String realStrUrl = sdsUrlPro + url; + String returnStr = HttpClientUtil.getHttp(realStrUrl, map); + System.out.println("获取成品列表响应:" + returnStr); + return Dto.returnErrorResult(returnStr); + } + + + // url getUrlHttp + @ApiOperation("获取成品列表Url") + @Log("获取成品列表Url") + @GetMapping("/endproductsUrl") + @AnonymousAccess + public Dto endproductsUrl(@RequestParam(value = "page") Integer page, + @RequestParam(value = "size") Integer size, + @RequestParam(value = "userId", required = false) Long userId, + @RequestParam(value = "designProductType", required = false) String designProductType){ + + // sdsUrlTest + Long millisTime = System.currentTimeMillis(); + String url = "/gateway/endproducts"; + Map map = new HashMap<>(); + map.put("page", page); + map.put("size", size); + map.put("_timestamp", millisTime); +// map.put("userId", page); +// map.put("designProductType", "SINGLE"); + + String sign = getSign(map); + System.out.println("生成sign的url:" + sign); + String md5Sign = MD5Util.md5(sign); + System.out.println("生成的sign:" + md5Sign); + map.clear(); + + map.put("_appid", appId); + map.put("_timestamp", millisTime); + map.put("_sign", md5Sign); + map.put("page", page); + map.put("size", size); +// map.put("designProductType", "SINGLE"); + + String realStrUrl = sdsUrlPro + url + "?page=" + page + "&size=" + size + "&_appid=" + appId + "&_sign=" + md5Sign + "&_timestamp=" + millisTime; + System.out.println("realStrUrl:" + realStrUrl); + String returnStr = HttpClientUtil.getUrlHttp(realStrUrl); + System.out.println("获取成品列表响应:" + returnStr); + return Dto.returnErrorResult(returnStr); + } + + @ApiOperation("根据成品ID获取成品信息") + @Log("根据成品ID获取成品信息") + @GetMapping("/endproductsById") + @AnonymousAccess + public Dto endproductsById(@RequestParam(value = "id") String id){ + // sdsUrlTest + Long millisTime = System.currentTimeMillis(); + String url = "/gateway/endproducts/" + id; + Map map = new HashMap<>(); + map.put("_timestamp", millisTime); + + String sign = getSign(map); + System.out.println("生成sign的url:" + sign); + String md5Sign = MD5Util.md5(sign); + System.out.println("生成的sign:" + md5Sign); + map.clear(); + map.put("_sign", md5Sign); + map.put("_timestamp", millisTime); + map.put("_appid", appId); + + String realStrUrl = sdsUrlPro + url; + String returnStr = HttpClientUtil.getHttp(realStrUrl, map); + System.out.println("根据成品ID获取成品信息:" + returnStr); + return Dto.returnErrorResult(returnStr); + } + + + @ApiOperation("根据成品ID获取成品详细信息包含产品详细信息") + @Log("根据成品ID获取成品详细信息包含产品详细信息") + @GetMapping("/endproductsDetailById") + @AnonymousAccess + public Dto endproductsDetailById(@RequestParam(value = "id") String id){ + // sdsUrlTest + Long millisTime = System.currentTimeMillis(); + String url = "/gateway/endproducts/" + id + "/huajuDetail"; + Map map = new HashMap<>(); + map.put("_timestamp", millisTime); + + String sign = getSign(map); + System.out.println("生成sign的url:" + sign); + String md5Sign = MD5Util.md5(sign); + System.out.println("生成的sign:" + md5Sign); + map.clear(); + map.put("_sign", md5Sign); + map.put("_timestamp", millisTime); + map.put("_appid", appId); + + String realStrUrl = sdsUrlPro + url; + String returnStr = HttpClientUtil.getHttp(realStrUrl, map); + System.out.println("根据成品ID获取成品详细信息包含产品详细信息:" + returnStr); + return Dto.returnErrorResult(returnStr); + } + + + @ApiOperation("地址") + @Log("地址") + @GetMapping("/areas") + @AnonymousAccess + public Dto areas(@RequestParam(value = "area_code", required = false) Long areaCode){ + + // sdsUrlTest + Long millisTime = System.currentTimeMillis(); + String url = "/gateway/areas/" + areaCode + "/items"; + Map map = new HashMap<>(); +// map.put("area_code", areaCode); + map.put("_timestamp", millisTime); + String sign = getSign(map); + String md5Sign = MD5Util.md5(sign); + map.clear(); + map.put("_sign", md5Sign); + map.put("_timestamp", millisTime); + map.put("_appid", appId); + + String realStrUrl = sdsUrlPro + url; + String returnStr = HttpClientUtil.getHttp(realStrUrl, map); + System.out.println("地址:" + returnStr); + return Dto.returnErrorResult(returnStr); + } + + + @ApiOperation("素材") + @Log("素材") + @GetMapping("/gateway/materials") + @AnonymousAccess + public Dto materials(@RequestParam(value = "page") Integer page, + @RequestParam(value = "size") Integer size, + @RequestParam(value = "userId", required = false) Long userId){ + + // sdsUrlTest + Long millisTime = System.currentTimeMillis(); + String url = "/gateway/materials"; + Map map = new HashMap<>(); + map.put("page", page); + map.put("size", size); + map.put("_timestamp", millisTime); +// map.put("userId", page); +// map.put("designProductType", "SINGLE"); + + String sign = getSign(map); + System.out.println("生成sign的url:" + sign); + String md5Sign = MD5Util.md5(sign); + System.out.println("生成的sign:" + md5Sign); + map.clear(); + + map.put("_appid", appId); + map.put("_timestamp", millisTime); + map.put("_sign", md5Sign); + map.put("page", page); + map.put("size", size); +// map.put("designProductType", "SINGLE"); + + String realStrUrl = sdsUrlPro + url + "?page=" + page + "&size=" + size + "&_appid=" + appId + "&_sign=" + md5Sign + "&_timestamp=" + millisTime; + System.out.println("realStrUrl:" + realStrUrl); + String returnStr = HttpClientUtil.getUrlHttp(realStrUrl); + System.out.println("获取成品列表响应:" + returnStr); + return Dto.returnErrorResult(returnStr); + } + + // Get验签 + public String getSign(Map map) { + + map.put("_appid", appId); + map.put("_appsecret", appsecret); + + + TreeMap params = new TreeMap(); + params.putAll(map); + + StringBuilder strBuilder = new StringBuilder(); + for (String key : params.keySet()) { + strBuilder.append(key).append("=").append(params.get(key)).append("&"); + } + strBuilder.deleteCharAt(strBuilder.length() - 1); + System.out.println(strBuilder); + return strBuilder.toString(); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/SysQuartzJobController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/SysQuartzJobController.java new file mode 100644 index 0000000..7e5a4d3 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/SysQuartzJobController.java @@ -0,0 +1,206 @@ +package me.zhengjie.modules.group.controller.base; + + +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.ObjectUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.FormSubmission; +import me.zhengjie.annotation.Log; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtApply; +import me.zhengjie.entity.SysQuartzJob; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.modules.group.dto.IdDTO; +import me.zhengjie.modules.group.dto.SysQuartzJobAddDTO; +import me.zhengjie.modules.group.dto.SysQuartzJobListDTO; +import me.zhengjie.modules.group.dto.SysQuartzJobUpdateDTO; +import me.zhengjie.modules.quartz.service.SysQuartzJobService; +import me.zhengjie.service.CtApplyService; +import me.zhengjie.utils.StringUtils; +import me.zhengjie.utils.YdParamsCheck; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * @Description 群控管理-影刀定时任务 + * @Date 2022/7/21 + * @Author zhw + */ +@Validated +@RequestMapping("/api/quartzJob") +@RestController +@Api(tags = "业务:影刀定时任务管理") +public class SysQuartzJobController { + @Resource + private SysQuartzJobService sysQuartzJobService; + @Resource + private CtApplyService ctApplyService; + @Resource + private Snowflake snowflake; + + + /** + * 分页查询影刀任务信息 + */ + @ApiOperation("分页查询影刀任务信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("分页查询影刀任务信息") + @AnonymousAccess + @PostMapping("/list") + public Dto getQuartzJobList(@Valid @RequestBody SysQuartzJobListDTO dto) { + return Dto.returnResult(sysQuartzJobService.searchPageList(dto.getiPage(), dto.getWrapper())); + } + + /** + * 新增影刀任务信息 + */ + @ApiOperation("新增影刀任务信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3401, message = "影刀应用信息异常, 请检查后重试!") + }) + @Log("新增影刀任务信息") + @AnonymousAccess + @PostMapping("/add") + @FormSubmission + @Transactional(rollbackFor = Exception.class) + public Dto addQuartzJob(@Valid @RequestBody SysQuartzJobAddDTO dto) { + + // TODO 应用已后台添加的枚举 TaskInfoEnum 为准 根据 taskName 区分应用 逻辑 匹配params + CtApply ctApply = ctApplyService.getById(dto.getApplyId()); + if (ObjectUtil.isEmpty(ctApply)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_TASK); + } + + String taskName = ctApply.getTaskName(); + String params = dto.getParams(); + Long taskNum = snowflake.nextId(); + dto.setTaskNum(taskNum); + // TODO 客户端处理 走 param模式还是 回显模式 这里先设置未null + if (!YdParamsCheck.paramIsJson(params)) { + // 测试的第一个应用 刷单 拼装params + String assemblyParams = sysQuartzJobService.assemblyParamAccordingToItem(params, taskName, taskNum); + if (StringUtils.isEmpty(assemblyParams)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_TASK); + } else { + dto.setParams(assemblyParams); + } + } + + return sysQuartzJobService.addQuartzJob(dto); + } + + /** + * 根据ID删除影刀任务信息 + */ + @ApiOperation("根据ID删除影刀任务信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据ID删除影刀任务信息") + @PostMapping("/delete") + public Dto deleteQuartzJob(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(sysQuartzJobService.deleteQuartzJobById(idDTO.getId())); + } + + /** + * 编辑影刀任务信息 + */ + @ApiOperation("编辑影刀任务信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3401, message = "影刀应用信息异常, 请检查后重试!") + }) + @Log("编辑影刀任务信息") + @PostMapping("/edit") + @FormSubmission + public Dto updateQuartzJob(@Valid @RequestBody SysQuartzJobUpdateDTO dto) { + CtApply ctApply = ctApplyService.getById(dto.getApplyId()); + if (ObjectUtil.isEmpty(ctApply)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_TASK); + } + String taskName = ctApply.getTaskName(); + String params = dto.getParams(); + // TODO 客户端处理 走 param模式还是 回显模式 这里先设置未null + if (!YdParamsCheck.paramIsJson(params)) { + // TODO 先这样吧,先不回头去调整了。先能弄不考虑其他 + SysQuartzJob sysQuartzJob = sysQuartzJobService.getById(dto.getJobId()); + // 测试的第一个应用 刷单 拼装params + String assemblyParams = sysQuartzJobService.assemblyParamAccordingToItem(params, taskName, sysQuartzJob.getTaskNum()); + if (StringUtils.isEmpty(assemblyParams)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_TASK); + } else { + dto.setParams(assemblyParams); + } + } + return sysQuartzJobService.updateQuartzJobById(dto); + } + + /** + * 根据ID查询影刀任务信息 + */ + @ApiOperation("根据ID查询影刀任务信息") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据ID查询影刀任务信息") + @PostMapping("/getById") + public Dto getQuartzJobById(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(sysQuartzJobService.getById(idDTO.getId())); + } + + /** + * 根据ID修改任务状态 + * @param idDTO + * @return + */ + @ApiOperation("根据ID修改任务状态") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("根据ID修改任务状态") + @PostMapping("/modifyStatus") + public Dto modifyJobStatus(@Valid @RequestBody IdDTO idDTO) { + return Dto.returnResult(sysQuartzJobService.modifyJobStatus(idDTO.getId())); + } + + /** + * 执行影刀任务 + * + * + * @param idDTO + * @return Dto + */ + @ApiOperation("执行影刀任务") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!") + }) + @Log("执行定时任务") + @PostMapping("/exec") + public Dto execution(@Valid @RequestBody IdDTO idDTO) { + Boolean one = true; + one = !one; + return Dto.returnResult(sysQuartzJobService.executionById(idDTO.getId())); + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/YdCallBackController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/YdCallBackController.java new file mode 100644 index 0000000..d3c4589 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/base/YdCallBackController.java @@ -0,0 +1,122 @@ +package me.zhengjie.modules.group.controller.base; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.config.YdApiProperties; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtRebot; +import me.zhengjie.entity.ReturnObje; +import me.zhengjie.entity.YdSign; +import me.zhengjie.enums.YesOrNoEnum; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.service.CtRebotService; +import me.zhengjie.utils.YdSignUtil; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.Map; + +/** + * @Description + * @Date 2022/7/23 + * @Author rch + */ +@Slf4j +@Validated +@RequestMapping("/api/yd") +@RestController +@Api(tags = "业务:影刀回调管理Demo") +public class YdCallBackController { + + @Resource + private CtRebotService ctRebotService; + /** + * 影刀回调Demo + */ + @ApiOperation("影刀回调Demo") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3700, message = "影刀回调参数空值异常!"), + @ApiResponse(code = 3701, message = "影刀回调鉴权异常!") + }) + @Log(value = "影刀回调") + @PostMapping("/callback") + @AnonymousAccess + public Dto callback(@Valid @RequestBody String data, HttpServletRequest httpServletRequest){ + log.info("=======影刀回调=======callback"); + String requestUrl = httpServletRequest.getRequestURI(); + Map map = httpServletRequest.getParameterMap(); + if (ObjectUtil.isEmpty(map.get("sign"))) { + return Dto.getInstance(ErrorCodeEnum.ERROR_PARAM_NULL); + } + + String getSign = map.get("sign")[0]; + JSONObject jsonObject = JSONUtil.parseObj(data); + String accessKeyId = YdApiProperties.ACCESS_KEY_ID; + String accessKeySecret = YdApiProperties.ACCESS_KEY_SECRET; + if (ObjectUtil.isEmpty(getSign) + || ObjectUtil.isEmpty(jsonObject) + || ObjectUtil.isEmpty(accessKeyId) + || ObjectUtil.isEmpty(accessKeySecret)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_PARAM_NULL); + } + + // 根据task枚举获取 应用信息 取出 accessKey 和 accessKeySecret 用于鉴权 + + + // 鉴权 + YdSign ydSign = new YdSign(); + ydSign.setTimestamp(Long.valueOf(map.get("timestamp")[0])); + ydSign.setAccessKeyId(accessKeyId); + ydSign.setAccessKeySecret(accessKeySecret); + ydSign.setBodyMd5(map.get("bodyMd5")[0]); + + log.info("-------map:{}" , JSONUtil.toJsonStr(map)); + log.info("====ydSign====={}", JSONUtil.toJsonStr(ydSign)); + String sign = YdSignUtil.getSign(ydSign); + log.info("====sign:{} ---getSign:{}", sign, getSign); + if (ObjectUtil.isEmpty(sign) || !getSign.equals(sign)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_CALLBACK_SIGN_NULL); + } + + System.out.println("===================data:" + data); + + + // TODO 拿到返回信息 根据回调知道是那个应用的业务场景 这里算是刷单系统的 + // 1.得到结果 根据结果修改 刷单信息状态 以及响应信息 + + + // TODO 获取设备id 然后修改设备状态是未占用 + ReturnObje returnObje = JSONUtil.toBean(data, ReturnObje.class); + String rebotClientName = returnObje.getRobotClientName(); + CtRebot ctRebot = ctRebotService.getByAccountNameLock(rebotClientName); + if (ObjectUtil.isEmpty(ctRebot) || !YesOrNoEnum.YES.eqValue(ctRebot.getStatus())) { + // 有问题 不执行 + System.out.println("===========设备有问题==========="); + return Dto.returnResult(true); + } else { + // 修改机器人状态 不管是什么状态,执行完成之后在我们平台就是修改为 待占用即可 + CtRebot updateCtRebot = new CtRebot(); + updateCtRebot.setId(ctRebot.getId()); + updateCtRebot.setStatus(YesOrNoEnum.NO.value()); + Boolean resultBoolean = ctRebotService.updateById(updateCtRebot); + return Dto.returnResult(resultBoolean); + } + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/BossTaskCallBackController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/BossTaskCallBackController.java new file mode 100644 index 0000000..ce0894e --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/BossTaskCallBackController.java @@ -0,0 +1,84 @@ +package me.zhengjie.modules.group.controller.callbcak; + +import cn.hutool.json.JSONUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.CtApply; +import me.zhengjie.entity.ReturnObje; +import me.zhengjie.entity.quartz.JobQueryByUuidReturn; +import me.zhengjie.enums.TaskInfoEnum; +import me.zhengjie.service.CtApplyService; +import me.zhengjie.service.YdQuartzService; +import me.zhengjie.utils.YdCallBackUtil; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +/** + * @Description + * @Date 2022/7/23 + * @Author rch + */ +@Slf4j +@Validated +@RequestMapping("/api/bossTask") +@RestController +@Api(tags = "回调:Boss-职位查询采集-影刀回调") +public class BossTaskCallBackController { + + @Resource + private CtApplyService ctApplyService; + @Resource + private YdQuartzService ydQuartzService; + /** + * Boss-职位查询采集-影刀回调 + */ + @ApiOperation("Boss-职位查询采集-影刀回调") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3700, message = "影刀回调参数空值异常!"), + @ApiResponse(code = 3701, message = "影刀回调鉴权异常!") + }) + @Log(value = "Boss-职位查询采集-影刀回调") + @PostMapping("/callback") + @AnonymousAccess + public Dto callback(@Valid @RequestBody String data, HttpServletRequest httpServletRequest){ + // 根据task枚举获取 应用信息 取出 accessKey 和 accessKeySecret 用于鉴权 + YdCallBackUtil ydCallBackUtil = new YdCallBackUtil(); + CtApply ctApply = ctApplyService.getApplyByTaskAndMethod(TaskInfoEnum.BOSS_TASK.getTaskName(), TaskInfoEnum.BOSS_TASK.getMethodName()); + Dto dto = ydCallBackUtil.callback(httpServletRequest, ctApply, data); + if (!dto.success(dto)) { + return dto; + } + + // 执行自己的业务逻辑 + log.info("============bossTask 回调鉴权完成 开始执行对应的定时业务逻辑================begin="); + // 获取自己想要的数据 + ReturnObje returnObje = JSONUtil.toBean(data, ReturnObje.class); + log.info("====returnObje====:{}", JSONUtil.toJsonStr(returnObje)); + // 获取应用名称 获取机器人名称 + // 执行自己的业务逻辑 + log.info("============刷单回调鉴权完成 开始执行对应的定时业务逻辑================begin="); + log.info("回调======data:" + data); + // 获取自己想要的数据 + JobQueryByUuidReturn jobQueryByUuidReturn = ydQuartzService.queryJobUuid(returnObje.getJobUuid(), ctApply.getAccessKeyId(), ctApply.getAccessKeySecret()); + log.info("====jobQueryByUuidReturn====:{}", JSONUtil.toJsonStr(jobQueryByUuidReturn)); + + log.info("============bossTask 回调鉴权完成 开始执行对应的定时业务逻辑================end==="); + return dto; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/ClickFarmingCallBackController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/ClickFarmingCallBackController.java new file mode 100644 index 0000000..3887c5d --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/ClickFarmingCallBackController.java @@ -0,0 +1,432 @@ +package me.zhengjie.modules.group.controller.callbcak; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.*; +import me.zhengjie.entity.quartz.Boss; +import me.zhengjie.entity.quartz.JobQueryByUuidReturn; +import me.zhengjie.entity.quartz.Param; +import me.zhengjie.enums.*; +import me.zhengjie.modules.quartz.service.SysQuartzJobService; +import me.zhengjie.service.*; +import me.zhengjie.service.vo.CtBuyerDetailVO; +import me.zhengjie.utils.CronUtils; +import me.zhengjie.utils.RedisUtils; +import me.zhengjie.utils.YdCallBackUtil; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.stream.Collectors; + +/** + * @Description + * 刷单定时任务回调逻辑 + * 回调需要鉴权,鉴权是根据 accesskey accessKeySrect + * 我们应用确认之后 accesskey 和 Srect是确定的 + * + * @Date 2022-8-23 + * @Author rch + */ +@Slf4j +@Validated +@RequestMapping("/api/clickFarming") +@RestController +@Api(tags = "回调:速卖通刷单-影刀回调") +public class ClickFarmingCallBackController { + + @Resource + private CtApplyService ctApplyService; + @Resource + private YdQuartzService ydQuartzService; + @Resource + private CtClickFarmingService ctClickFarmingService; + @Resource + private CtClickOrderService ctClickOrderService; + @Resource + private RedisUtils redisUtils; + @Resource + private CtBuyerService ctBuyerService; + @Resource + private SysQuartzJobService sysQuartzJobService; + @Resource + private Snowflake snowflake; + @Resource + private SettingSiteService settingSiteService; + + private final String STAET_MODULAR = "】任务失败,在【"; + private final String END_MODULAR = "】中第"; + private final String END_LINE_NUMBER = "行:出错"; + private final Integer START_TASK_TIME = 20; + private final String RE_EXECTE_KEY = "reExecuteKey"; + /** + * 速卖通刷单-影刀回调 + */ + @ApiOperation("速卖通刷单-影刀回调") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3700, message = "影刀回调参数空值异常!"), + @ApiResponse(code = 3701, message = "影刀回调鉴权异常!") + }) + @Log(value = "速卖通刷单-影刀回调") + @PostMapping("/callback") + @AnonymousAccess + @Transactional(rollbackFor = Exception.class) + public Dto callback(@Valid @RequestBody String data, HttpServletRequest httpServletRequest){ + + // 根据task枚举获取 应用信息 取出 accessKey 和 accessKeySecret 用于鉴权 + YdCallBackUtil ydCallBackUtil = new YdCallBackUtil(); + CtApply ctApply = ctApplyService.getApplyByTaskAndMethod(TaskInfoEnum.CLICK_FARMING.getTaskName(), TaskInfoEnum.CLICK_FARMING.getMethodName()); + Dto dto = ydCallBackUtil.callback(httpServletRequest, ctApply, data); + if (!dto.success(dto)) { + return dto; + } + + // 执行自己的业务逻辑 + log.info("============刷单回调鉴权完成 开始执行对应的定时业务逻辑================begin="); + log.info("回调======data:" + data); + // 获取自己想要的数据 + ReturnObje returnObje = JSONUtil.toBean(data, ReturnObje.class); + // job ID + String jobUuid = returnObje.getJobUuid(); + + // TODO 回调会重试 这里注意保证幂等 + // TODO 所以需要对接方在业务层面保障幂等(可以根据jobUuid或者taskUuid进行幂等保障,视startJob时是指定应用和机器人模式还是指定任务模式) + String keyJobUuid = PublicConstant.getJobUuidKeyPrefix(jobUuid); + if (!redisUtils.setIfAbsent(keyJobUuid, DateUtil.now())) { + log.info("-刷单回调接口-幂等性:keyJobUuid:" + keyJobUuid); + return Dto.returnResult(true); + } + + log.info("====returnObje====:{}", JSONUtil.toJsonStr(returnObje)); + JobQueryByUuidReturn jobQueryByUuidReturn = ydQuartzService.queryJobUuid(returnObje.getJobUuid(), ctApply.getAccessKeyId(), ctApply.getAccessKeySecret()); + log.info("====jobQueryByUuidReturn====:{}", JSONUtil.toJsonStr(jobQueryByUuidReturn)); + List inputsList = jobQueryByUuidReturn.getData().getRobotParams().getInputs(); + // 获取id + String id = null; + String buyerName = null; + String taskNum = null; + for (ResultObj resultObj:inputsList) { + if ("id".equals(resultObj.getName())) { + id = resultObj.getValue(); + } + + if ("account".equals(resultObj.getName())) { + buyerName = resultObj.getValue(); + } + + if ("taskNum".equals(resultObj.getName())) { + taskNum = resultObj.getValue(); + } + } + + Integer status = ClickFarmingStatusEnum.EXECUTION_FAILE.value(); + if ("finish".equals(jobQueryByUuidReturn.getData().getStatus())) { + status = ClickFarmingStatusEnum.EXECUTION_SUCCESS.value(); + } + + // 执行失败 + Boolean resultBoolean = false; + if (ObjectUtil.isNotEmpty(id)) { + CtClickFarming ctClickFarming = new CtClickFarming(); + ctClickFarming.setId(Long.valueOf(id)); + + // 获取买家信息并修改买家信息 + CtBuyer ctBuyer = ctBuyerService.getBuyerOccupyStatusLock(buyerName); + if (ObjectUtil.isNotEmpty(ctBuyer) && BuyerOccupyStatusEnum.OCCUPIED.value().equals(ctBuyer.getOccupyStatus())) { + ctBuyer.setOccupyStatus(BuyerOccupyStatusEnum.UN_OCCUPIED.value()); + resultBoolean = ctBuyerService.updateById(ctBuyer); + } + + // TODO 需要更新的字段 从这里获取影刀返回的 然后接着设置到 对应的 基础信息里 + List outputsList = jobQueryByUuidReturn.getData().getRobotParams().getOutputs(); + if (resultBoolean && ObjectUtil.isNotEmpty(outputsList)) { + Map resultObjMap = outputsList.stream().collect(Collectors.toMap(ResultObj::getName, ResultObj::getValue)); + CtClickOrder ctClickOrder = BeanUtil.mapToBean(resultObjMap, CtClickOrder.class, false); + if (ObjectUtil.isNotEmpty(ctClickOrder)) { + if (ObjectUtil.isNotEmpty(ctClickOrder.getPaymentResults()) && "Awaiting payment".equals(ctClickOrder.getPaymentResults())) { + status = ClickFarmingStatusEnum.AWAITING_PAYMENT.value(); + } + // 设置订单 公司 平台信息 + ctClickOrder.setCompanyId(ctBuyer.getCompanyId()); + ctClickOrder.setType(OrderTypeEnum.CLICK_FARMING.value()); + if (ctClickOrderService.save(ctClickOrder)) { + ctClickFarming.setCtClickOrderId(ctClickOrder.getId()); + } + } + } else { + // 解析json 返回错误类型 + status = analysisReturnJson(jobQueryByUuidReturn.getData().getRemark()); + } + + ctClickFarming.setStatus(status); + if (ClickFarmingStatusEnum.EXECUTION_FAILE.value().equals(status) || ClickFarmingStatusEnum.PAY_OK_ERROR.value().equals(status) || ClickFarmingStatusEnum.AWAITING_PAYMENT.value().equals(status)) { + ctClickFarming.setResponse(jobQueryByUuidReturn.getData().getRemark()); + }else { + ctClickFarming.setResponse(jobQueryByUuidReturn.getData().getStatusName()); + } + resultBoolean = ctClickFarmingService.updateById(ctClickFarming); + // TODO 判断状态 如果是执行失败 (未下单成功 未支付的则直接重新创建任务重新执行-(换个买家)) + /** + * 1.根据买家规则返回买家信息 + * 2.用新买家信息 创建新的定时任务 + */ + // 查询刷单信息 默认不执行 只有设置1才执行 + String reExecuteValue = settingSiteService.getValue(RE_EXECTE_KEY); + if (ObjectUtil.isNotEmpty(reExecuteValue) && "1".equals(reExecuteValue)) { + CtClickFarming ctClickFarmingOld = ctClickFarmingService.getById(id); + if (ClickFarmingStatusEnum.EXECUTION_FAILE.value().equals(status)) { + SysQuartzJob sysQuartzJob = sysQuartzJobService.getByTaskNum(taskNum); + if (ObjectUtil.isEmpty(sysQuartzJob)) { + return Dto.returnResult(false); + } + resultBoolean = reExecuteTask(sysQuartzJob, ctClickFarmingOld); + } + } + } + + log.info("============刷单回调鉴权完成 开始执行对应的定时业务逻辑================end==="); + return Dto.returnResult(resultBoolean); + } + + /** + * 执行失败-重新创建定时任务 + * @param sysQuartzJob + * @return + */ + private Boolean reExecuteTask(SysQuartzJob sysQuartzJob, CtClickFarming ctClickFarming) { + // TODO 根据规则 修改 param 参数信息 以及 + log.info("刷单任务-执行失败-重新创建定时任务--sysQuartzJob:{} --ctClickFarming:{}", JSONUtil.toJsonStr(sysQuartzJob), JSONUtil.toJsonStr(ctClickFarming)); + // 创建后启用状态 并且 失败不暂停(失败后要暂停的) + sysQuartzJob.setIsPause(TaskIsPauseEnum.NOT_PAUSE.value()); + sysQuartzJob.setPauseAfterFailure(TaskIsPauseEnum.IS_PAUSE.value()); + // 设置执行时间 + String cronStr = CronUtils.onlyOnce(DateUtil.formatDateTime(DateUtil.offsetSecond(DateUtil.date(), START_TASK_TIME))); + sysQuartzJob.setCronExpression(cronStr); + // 新的定时任务taskNum + Long taskNum = snowflake.nextId(); + sysQuartzJob.setJobName(jobNameNew(sysQuartzJob.getJobName(), sysQuartzJob.getTaskNum().toString())); + // 买家信息 + String paramsStr = sysQuartzJob.getParams(); + Boss bossObj = JSONUtil.toBean(paramsStr, Boss.class); + log.info("bossObj--before:" + JSONUtil.toJsonStr(bossObj)); + List paramList = bossObj.getParams(); + Param paramAccount = paramList.stream().filter(r->"account".equals(r.getName())).findFirst().get(); + Param paramCountry = paramList.stream().filter(r->"country".equals(r.getName())).findFirst().get(); + // 替换新的买家信息 + CtBuyerDetailVO ctBuyerDetailVO = getRuleCtBuyer(paramAccount.getValue(), paramCountry.getValue(), ctClickFarming); + if (ObjectUtil.isEmpty(ctBuyerDetailVO)) { + log.info("买家信息全部执行完成,没有可选择的买家信息!-任务不在重试"); + return false; + } + for (Param paramObj:paramList) { + if (("country").equals(paramObj.getName())) { + paramObj.setValue(ctBuyerDetailVO.getCountry()); + } + if (("account").equals(paramObj.getName())) { + paramObj.setValue(ctBuyerDetailVO.getAccount()); + } + if (("pwd").equals(paramObj.getName())) { + paramObj.setValue(ctBuyerDetailVO.getPwd()); + } + if (("vpnShare").equals(paramObj.getName())) { + paramObj.setValue(ctBuyerDetailVO.getVpn()); + } + // 信用卡 + if (("cardName").equals(paramObj.getName())) { + paramObj.setValue(ctBuyerDetailVO.getHolderSurname() + " " + ctBuyerDetailVO.getHolderName()); + } + if (("cardNumber").equals(paramObj.getName())) { + paramObj.setValue(ctBuyerDetailVO.getNumber()); + } + if (("cardPwd").equals(paramObj.getName())) { + paramObj.setValue(ctBuyerDetailVO.getCardPwd()); + } + if (("taskNum").equals(paramObj.getName())) { + paramObj.setValue(taskNum.toString()); + } + } + + log.info("bossObj--after:" + JSONUtil.toJsonStr(bossObj)); + sysQuartzJob.setParams(JSONUtil.toJsonStr(bossObj)); + sysQuartzJob.setTaskNum(taskNum); + + sysQuartzJobService.reAddQuartzJob(sysQuartzJob); + + return true; + } + + /** + * 返回新的jobName名字 + * 原则上传入的 jobName 和 taskNum 是同一个QuartzJob的。 + * 这个返回的 作为子集的 job_name = 父级原本的jobName + 父级的taskNum + * 为后续 排查使用 (最好是新设置一个字段,这里先这样) + * 说明: 父级的意思说的是 上级, 比如A任务 回调失败,换个买家 新创建任务B A就说是B的父级 + * @param jobName + * @param taskNum + * @return + */ + public String jobNameNew(String jobName, String taskNum) { + if (jobName.contains("-")) { + jobName = jobName.substring(0,jobName.lastIndexOf("-")); + } + + return jobName + "-" + taskNum; + } + + + /** + * 根据规则获取新的买家信息 + * @param buyerAccount + * @return + */ + public CtBuyerDetailVO getRuleCtBuyer(String buyerAccount, String country, CtClickFarming ctClickFarming) { + if (ObjectUtil.isEmpty(buyerAccount) + || ObjectUtil.isEmpty(country) + || ObjectUtil.isEmpty(ctClickFarming) + || ObjectUtil.isEmpty(ctClickFarming.getShopName()) + || ObjectUtil.isEmpty(ctClickFarming.getId())) { + return null; + } + // 获取所有成功的刷单信息买家 然后统计每个成功的个数并返回 同时剔除传过来的参数信息 + // TODO 这里不能无限制的取, 通过redis 根据 刷单id 设置取过的买家信息,取过的不再取了 + List ctBuyerClickSuccessList = ctClickFarmingService.ruleGetCtBuyer(buyerAccount, country, ctClickFarming.getShopName()); + String clickFarmingExecBuyerIdPrefix = PublicConstant.getClickFarmingExecBuyerIdPrefix(ctClickFarming.getId()); + Long setSize = redisUtils.sGetSetSize(clickFarmingExecBuyerIdPrefix); + Long buyerId = null; + if (setSize == 0) { + buyerId = ctBuyerClickSuccessList.get(new Random().nextInt(ctBuyerClickSuccessList.size())).getBuyerId(); + } else { + for (CtBuyerClickSuccess ctBuyerClickSuccess : ctBuyerClickSuccessList) { + buyerId = ctBuyerClickSuccess.getBuyerId(); + if (redisUtils.sHasKey(clickFarmingExecBuyerIdPrefix, buyerId.toString())) { + continue; + } + break; + } + System.out.println("没有取到合适的========================================"); + } + + if (ObjectUtil.isNotEmpty(buyerId)) { + redisUtils.sSet(clickFarmingExecBuyerIdPrefix, buyerId.toString()); + return ctBuyerService.getDetailById(buyerId); + } + return null; + } + + + + /** + * 解析json 区分错误类型 4.有订单id之前的异常 5.有订单未支付 6.支付成功异常 + * @param remark + * @return Integer + */ + private Integer analysisReturnJson(String remark) { + // 根据规则解析 + // "remark": "【0757f764-07b4-4d4d-a48d-e1e13b598a1f】任务失败,在【5-1清空银行卡】中第17行:出错:未找到元素, 元素名: 按钮_OK", + // "remark": "【9a92a414-e957-47f8-ada1-7296723769a9】任务失败,在【9-1优惠劵】中第7行:出错:未找到元素", + // "remark": "【60a92f00-f7cb-4321-aa0b-6f18814fb462】任务失败,在【3.切换国家】中第8行:出错:未找到元素", + // "remark": "【81f6c1ac-6493-40cf-83fd-867b1a39e3ca】任务失败,在【9-3添加银行卡】中第5行:出错:未找到元素, 元素名: SAVE CARD", + // "remark": "【e201a1b3-f0a1-42b9-8315-d6736eead5a4】任务失败,在【1-2清空浏览器数据】中第1行:出错:操作无法执行!请重启当前浏览器 或 重装当前浏览器插件后再次尝试。", +// 【923eea47-c056-47ef-bccf-930d8ef700da】任务失败,在【9-1.留言】中第2行:出错:未找到元素, 元素名: 留言板 +// private final String STAET_MODULAR = "】任务失败,在【"; +// private final String END_MODULAR = "】中第"; +// private final String END_LINE_NUMBER = "行:出错"; +// private final Integer START_TASK_TIME = 10; + /** + * 1.切换VPN + * 2.关闭弹窗 + * 3.清空浏览器 + * 4.切换国家 + * 5.登录 + * 6.清空购物车 + * 6-1.清空银行卡 + * 7.搜索商品 + * 7-1.随意浏览界面 + * 7-2.滚动鼠标浏览界面 + * 7-3.随机点击商品 + * 7-4.浏览随机商品 + * 7-5匹配商品信息 + * 8.商品下单 + * 8-1.滚动鼠标浏览商品 + * 8-2.查找规格 + * 8-3.查找颜色 + * 8-4.商品个数 + * 9.购物车-------------------------------有订单未支付:流程第19行点击Pay_now + * 9-1.留言 + * 9-2.添加银行卡 + * 9-3.选择银行卡有效时间 + * 9-4.选择优惠券 + * 10.回到首页----------------------回到首页:流程第11行点击首页 + * 11.获取订单信息 + * 12.退出账号 + */ + log.info(remark); + if (ObjectUtil.isEmpty(remark) + || !remark.contains("任务失败") + || !remark.contains("中第") + || !remark.contains("行:出错") + || remark.length() <= 12) { + return ClickFarmingStatusEnum.EXECUTION_FAILE.value(); + } + + String modular = remark.substring(remark.indexOf(STAET_MODULAR) + 8, remark.indexOf(END_MODULAR)); + String lineNumber = remark.substring(remark.indexOf(END_MODULAR) + 3, remark.indexOf(END_LINE_NUMBER)); + + // 子模块可以忽略 + Integer modularInteger = 0; + Integer lineNumberInteger = 0; + if (ObjectUtil.isNotEmpty(modular)) { + if (modular.contains(".") && !modular.contains("-") ) { + modularInteger = Integer.valueOf(modular.substring(0, modular.indexOf("."))); + } else if (modular.contains("-")) { + modularInteger = Integer.valueOf(modular.split("-")[0]); + } + } + if (ObjectUtil.isNotEmpty(lineNumber)) { + lineNumberInteger = Integer.valueOf(lineNumber); + } + + if (modularInteger < 9) { + return ClickFarmingStatusEnum.EXECUTION_FAILE.value(); + } else if(modularInteger == 9) { + if (lineNumberInteger <= 19) { + return ClickFarmingStatusEnum.EXECUTION_FAILE.value(); + } else { + return ClickFarmingStatusEnum.AWAITING_PAYMENT.value(); + } + } else if (modularInteger < 10){ + return ClickFarmingStatusEnum.AWAITING_PAYMENT.value(); + } else if(modularInteger == 10) { + if (lineNumberInteger <= 11) { + return ClickFarmingStatusEnum.AWAITING_PAYMENT.value(); + } else { + return ClickFarmingStatusEnum.PAY_OK_ERROR.value(); + } + } else { + return ClickFarmingStatusEnum.PAY_OK_ERROR.value(); + } + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/ClickFarmingSuppleMentCallBackController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/ClickFarmingSuppleMentCallBackController.java new file mode 100644 index 0000000..1250309 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/ClickFarmingSuppleMentCallBackController.java @@ -0,0 +1,234 @@ +package me.zhengjie.modules.group.controller.callbcak; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.*; +import me.zhengjie.entity.quartz.JobQueryByUuidReturn; +import me.zhengjie.enums.BuyerOccupyStatusEnum; +import me.zhengjie.enums.ClickFarmingStatusEnum; +import me.zhengjie.enums.TaskInfoEnum; +import me.zhengjie.service.*; +import me.zhengjie.utils.RedisUtils; +import me.zhengjie.utils.YdCallBackUtil; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @Description + * 刷单补录定时任务回调逻辑 + * 回调需要鉴权,鉴权是根据 accesskey accessKeySrect + * 我们应用确认之后 accesskey 和 Srect是确定的 + * + * @Date 2022-8-23 + * @Author rch + */ +@Slf4j +@Validated +@RequestMapping("/api/clickFarmSupplyMent") +@RestController +@Api(tags = "回调:速卖通刷单补录-影刀回调") +public class ClickFarmingSuppleMentCallBackController { + + @Resource + private CtApplyService ctApplyService; + @Resource + private YdQuartzService ydQuartzService; + @Resource + private CtClickFarmingService ctClickFarmingService; + @Resource + private CtClickOrderService ctClickOrderService; + @Resource + private RedisUtils redisUtils; + @Resource + private CtBuyerService ctBuyerService; + + private final String STAET_MODULAR = "】任务失败,在【"; + private final String END_MODULAR = "】中第"; + private final String END_LINE_NUMBER = "行:出错"; + private final Integer START_TASK_TIME = 20; + + /** + * 速卖通刷单补录-回调 + */ + @ApiOperation("速卖通刷单补录-回调") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3700, message = "影刀回调参数空值异常!"), + @ApiResponse(code = 3701, message = "影刀回调鉴权异常!") + }) + @Log(value = "速卖通刷单补录-回调") + @PostMapping("/callback") + @AnonymousAccess + @Transactional(rollbackFor = Exception.class) + public Dto callback(@Valid @RequestBody String data, HttpServletRequest httpServletRequest){ + + // 根据task枚举获取 应用信息 取出 accessKey 和 accessKeySecret 用于鉴权 + YdCallBackUtil ydCallBackUtil = new YdCallBackUtil(); + CtApply ctApply = ctApplyService.getApplyByTaskAndMethod(TaskInfoEnum.CLICK_FARMING_SUPPLE_MENY.getTaskName(), TaskInfoEnum.CLICK_FARMING_SUPPLE_MENY.getMethodName()); + Dto dto = ydCallBackUtil.callback(httpServletRequest, ctApply, data); + if (!dto.success(dto)) { + return dto; + } + + // 执行自己的业务逻辑 + log.info("============刷单回调鉴权完成 开始执行对应的定时业务逻辑================begin="); + log.info("回调======data:" + data); + // 获取自己想要的数据 + ReturnObje returnObje = JSONUtil.toBean(data, ReturnObje.class); + // job ID + String jobUuid = returnObje.getJobUuid(); + + // TODO 回调会重试 这里注意保证幂等 + // TODO 所以需要对接方在业务层面保障幂等(可以根据jobUuid或者taskUuid进行幂等保障,视startJob时是指定应用和机器人模式还是指定任务模式) + String keyJobUuid = PublicConstant.getJobUuidKeyPrefix(jobUuid); + if (!redisUtils.setIfAbsent(keyJobUuid, DateUtil.now())) { + log.info("-刷单回调接口-幂等性:keyJobUuid:" + keyJobUuid); + return Dto.returnResult(true); + } + + log.info("====returnObje====:{}", JSONUtil.toJsonStr(returnObje)); + JobQueryByUuidReturn jobQueryByUuidReturn = ydQuartzService.queryJobUuid(returnObje.getJobUuid(), ctApply.getAccessKeyId(), ctApply.getAccessKeySecret()); + log.info("====jobQueryByUuidReturn====:{}", JSONUtil.toJsonStr(jobQueryByUuidReturn)); + List inputsList = jobQueryByUuidReturn.getData().getRobotParams().getInputs(); + // 获取id + String id = null; + String buyerName = null; + for (ResultObj resultObj:inputsList) { + if ("id".equals(resultObj.getName())) { + id = resultObj.getValue(); + } + + if ("account".equals(resultObj.getName())) { + buyerName = resultObj.getValue(); + } + } + +// Integer status = ClickFarmingStatusEnum.EXECUTION_FAILE.value(); + Integer status = ClickFarmingStatusEnum.AWAITING_PAYMENT.value(); + if ("finish".equals(jobQueryByUuidReturn.getData().getStatus())) { + status = ClickFarmingStatusEnum.EXECUTION_SUCCESS.value(); + } + + // 执行失败 + Boolean resultBoolean = false; + if (ObjectUtil.isNotEmpty(id)) { + CtClickFarming ctClickFarming = new CtClickFarming(); + ctClickFarming.setId(Long.valueOf(id)); + + // 获取买家信息并修改买家信息 + CtBuyer ctBuyer = ctBuyerService.getBuyerOccupyStatusLock(buyerName); + if (ObjectUtil.isNotEmpty(ctBuyer) && BuyerOccupyStatusEnum.OCCUPIED.value().equals(ctBuyer.getOccupyStatus())) { + ctBuyer.setOccupyStatus(BuyerOccupyStatusEnum.UN_OCCUPIED.value()); + resultBoolean = ctBuyerService.updateById(ctBuyer); + } + + // TODO 需要更新的字段 从这里获取影刀返回的 然后接着设置到 对应的 基础信息里 + List outputsList = jobQueryByUuidReturn.getData().getRobotParams().getOutputs(); + if (resultBoolean && ObjectUtil.isNotEmpty(outputsList)) { + Map resultObjMap = outputsList.stream().collect(Collectors.toMap(ResultObj::getName, ResultObj::getValue)); + CtClickOrder ctClickOrder = BeanUtil.mapToBean(resultObjMap, CtClickOrder.class, false); + if (ObjectUtil.isNotEmpty(ctClickOrder)) { + if (ObjectUtil.isNotEmpty(ctClickOrder.getPaymentResults()) && "Awaiting payment".equals(ctClickOrder.getPaymentResults())) { + status = ClickFarmingStatusEnum.AWAITING_PAYMENT.value(); + } + // 设置订单 公司 平台信息 + ctClickOrder.setCompanyId(ctBuyer.getCompanyId()); + if (ctClickOrderService.save(ctClickOrder)) { + ctClickFarming.setCtClickOrderId(ctClickOrder.getId()); + } + } + }else { + // 解析json 返回错误类型 + status = analysisReturnJson(jobQueryByUuidReturn.getData().getRemark()); + } + + ctClickFarming.setStatus(status); + if (ClickFarmingStatusEnum.EXECUTION_FAILE.value().equals(status) || ClickFarmingStatusEnum.PAY_OK_ERROR.value().equals(status)) { + ctClickFarming.setResponse(jobQueryByUuidReturn.getData().getRemark()); + }else { + ctClickFarming.setResponse(jobQueryByUuidReturn.getData().getStatusName()); + } + resultBoolean = ctClickFarmingService.updateById(ctClickFarming); + } + + log.info("============刷单补录回调鉴权完成 开始执行对应的定时业务逻辑================end==="); + return Dto.returnResult(resultBoolean); + } + + + /** + * 解析json 区分错误类型 + * @param remark + * @return Integer + */ + private Integer analysisReturnJson(String remark) { + // 根据规则解析 + /** + 1.切换VPN + 2.关闭弹窗 + 3.清空浏览器 + 4.切换国家 + 5.登录 + 6.订单首页 + 6-1.添加银行卡 + 6-2.选择银行卡有效时间 + 7.获取订单信息-------------------支付成功:流程7行(包含) + 8.退出账号 + */ + if (ObjectUtil.isEmpty(remark) || !remark.contains("任务失败")) { + return ClickFarmingStatusEnum.EXECUTION_FAILE.value(); + } + + String modular = remark.substring(remark.indexOf(STAET_MODULAR) + 8, remark.indexOf(END_MODULAR)); + String lineNumber = remark.substring(remark.indexOf(END_MODULAR) + 3, remark.indexOf(END_LINE_NUMBER)); + + // 子模块可以忽略 + Integer modularInteger = 0; + Integer lineNumberInteger = 0; + if (ObjectUtil.isNotEmpty(modular)) { + if (modular.contains(".") && !modular.contains("-") ) { + modularInteger = Integer.valueOf(modular.substring(0, modular.indexOf("."))); + } else if (modular.contains("-")) { + modularInteger = Integer.valueOf(modular.split("-")[0]); + } + } + if (ObjectUtil.isNotEmpty(lineNumber)) { + lineNumberInteger = Integer.valueOf(lineNumber); + } + + if (modularInteger < 7) { + return ClickFarmingStatusEnum.AWAITING_PAYMENT.value(); + } else if(modularInteger == 7) { + if (lineNumberInteger < 7) { + return ClickFarmingStatusEnum.AWAITING_PAYMENT.value(); + } else { + return ClickFarmingStatusEnum.PAY_OK_ERROR.value(); + } + } else { + return ClickFarmingStatusEnum.PAY_OK_ERROR.value(); + } + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/ClickOrderCallBackController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/ClickOrderCallBackController.java new file mode 100644 index 0000000..d903379 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/ClickOrderCallBackController.java @@ -0,0 +1,151 @@ +package me.zhengjie.modules.group.controller.callbcak; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.*; +import me.zhengjie.entity.quartz.JobQueryByUuidReturn; +import me.zhengjie.enums.BuyerOccupyStatusEnum; +import me.zhengjie.enums.ClickOrderStatusEnum; +import me.zhengjie.enums.TaskInfoEnum; +import me.zhengjie.service.CtApplyService; +import me.zhengjie.service.CtBuyerService; +import me.zhengjie.service.CtClickOrderService; +import me.zhengjie.service.YdQuartzService; +import me.zhengjie.utils.RedisUtils; +import me.zhengjie.utils.YdCallBackUtil; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.List; + +/** + * @Description + * 好评定时任务回调逻辑 + * 回调需要鉴权,鉴权是根据 accesskey accessKeySrect + * 我们应用确认之后 accesskey 和 Srect是确定的 + * + * @Date 2022-8-23 + * @Author rch + */ +@Slf4j +@Validated +@RequestMapping("/api/clickOrder") +@RestController +@Api(tags = "回调:速卖通刷单好评-影刀回调") +public class ClickOrderCallBackController { + + @Resource + private CtApplyService ctApplyService; + @Resource + private YdQuartzService ydQuartzService; + @Resource + private CtClickOrderService ctClickOrderService; + @Resource + private RedisUtils redisUtils; + @Resource + private CtBuyerService ctBuyerService; + + /** + * 速卖通刷单好评-好评回调 + */ + @ApiOperation("速卖通刷单好评-好评回调") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3700, message = "影刀回调参数空值异常!"), + @ApiResponse(code = 3701, message = "影刀回调鉴权异常!") + }) + @Log(value = "速卖通刷单好评-好评回调") + @PostMapping("/callback") + @AnonymousAccess + @Transactional(rollbackFor = Exception.class) + public Dto callback(@Valid @RequestBody String data, HttpServletRequest httpServletRequest){ + + // 根据task枚举获取 应用信息 取出 accessKey 和 accessKeySecret 用于鉴权 + YdCallBackUtil ydCallBackUtil = new YdCallBackUtil(); + CtApply ctApply = ctApplyService.getApplyByTaskAndMethod(TaskInfoEnum.WELL_RECEIVED.getTaskName(), TaskInfoEnum.WELL_RECEIVED.getMethodName()); + Dto dto = ydCallBackUtil.callback(httpServletRequest, ctApply, data); + if (!dto.success(dto)) { + return dto; + } + + // 执行自己的业务逻辑 + log.info("============刷单回调鉴权完成 开始执行对应的定时业务逻辑================begin="); + log.info("回调======data:" + data); + // 获取自己想要的数据 + ReturnObje returnObje = JSONUtil.toBean(data, ReturnObje.class); + // job ID + String jobUuid = returnObje.getJobUuid(); + + // TODO 回调会重试 这里注意保证幂等 + // TODO 所以需要对接方在业务层面保障幂等(可以根据jobUuid或者taskUuid进行幂等保障,视startJob时是指定应用和机器人模式还是指定任务模式) + String keyJobUuid = PublicConstant.getJobUuidKeyPrefix(jobUuid); + if (!redisUtils.setIfAbsent(keyJobUuid, DateUtil.now())) { + log.info("-刷单回调接口-幂等性:keyJobUuid:" + keyJobUuid); + return Dto.returnResult(true); + } + + log.info("====returnObje====:{}", JSONUtil.toJsonStr(returnObje)); + JobQueryByUuidReturn jobQueryByUuidReturn = ydQuartzService.queryJobUuid(returnObje.getJobUuid(), ctApply.getAccessKeyId(), ctApply.getAccessKeySecret()); + log.info("====jobQueryByUuidReturn====:{}", JSONUtil.toJsonStr(jobQueryByUuidReturn)); + List inputsList = jobQueryByUuidReturn.getData().getRobotParams().getInputs(); + // 获取id + String id = null; + String buyerName = null; + for (ResultObj resultObj:inputsList) { + if ("id".equals(resultObj.getName())) { + id = resultObj.getValue(); + } + + if ("account".equals(resultObj.getName())) { + buyerName = resultObj.getValue(); + } + } + + Integer status = ClickOrderStatusEnum.EXECUTION_FAILE.value(); + if ("finish".equals(jobQueryByUuidReturn.getData().getStatus())) { + status = ClickOrderStatusEnum.EXECUTION_SUCCESS.value(); + } + + // 执行失败 + Boolean resultBoolean = false; + if (ObjectUtil.isNotEmpty(id)) { + CtClickOrder ctClickOrder = new CtClickOrder(); + ctClickOrder.setId(Long.valueOf(id)); + ctClickOrder.setStatus(status); + ctClickOrder.setPaymentResults(jobQueryByUuidReturn.getData().getRemark()); + + // 获取买家信息并修改买家信息 + CtBuyer ctBuyer = ctBuyerService.getBuyerOccupyStatusLock(buyerName); + if (ObjectUtil.isNotEmpty(ctBuyer) && BuyerOccupyStatusEnum.OCCUPIED.value().equals(ctBuyer.getOccupyStatus())) { + ctBuyer.setOccupyStatus(BuyerOccupyStatusEnum.UN_OCCUPIED.value()); + resultBoolean = ctBuyerService.updateById(ctBuyer); + } + + // TODO 需要更新的字段 从这里获取影刀返回的 然后接着设置到 对应的 基础信息里 + if (resultBoolean) { + resultBoolean = ctClickOrderService.updateById(ctClickOrder); + } + } + + log.info("============刷单回调鉴权完成 开始执行对应的定时业务逻辑================end==="); + return Dto.returnResult(resultBoolean); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/CtbrowseCallBackController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/CtbrowseCallBackController.java new file mode 100644 index 0000000..f575b42 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/CtbrowseCallBackController.java @@ -0,0 +1,148 @@ +package me.zhengjie.modules.group.controller.callbcak; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.*; +import me.zhengjie.entity.quartz.JobQueryByUuidReturn; +import me.zhengjie.enums.BuyerOccupyStatusEnum; +import me.zhengjie.enums.ClickOrderStatusEnum; +import me.zhengjie.enums.TaskInfoEnum; +import me.zhengjie.service.*; +import me.zhengjie.utils.RedisUtils; +import me.zhengjie.utils.YdCallBackUtil; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.List; + +/** + * @Description + * 浏览收藏定时任务回调逻辑 + * 回调需要鉴权,鉴权是根据 accesskey accessKeySrect + * 我们应用确认之后 accesskey 和 Srect是确定的 + * + * @Date 2022-8-23 + * @Author rch + */ +@Slf4j +@Validated +@RequestMapping("/api/ctBrowse") +@RestController +@Api(tags = "回调:速卖通浏览收藏-影刀回调") +public class CtbrowseCallBackController { + + @Resource + private CtApplyService ctApplyService; + @Resource + private YdQuartzService ydQuartzService; + @Resource + private CtBrowseService ctBrowseService; + @Resource + private RedisUtils redisUtils; + @Resource + private CtBuyerService ctBuyerService; + + /** + * 速卖通刷单好评-好评回调 + */ + @ApiOperation("速卖通浏览收藏-回调") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3700, message = "影刀回调参数空值异常!"), + @ApiResponse(code = 3701, message = "影刀回调鉴权异常!") + }) + @Log(value = "速卖通浏览收藏-回调") + @PostMapping("/callback") + @AnonymousAccess + @Transactional(rollbackFor = Exception.class) + public Dto callback(@Valid @RequestBody String data, HttpServletRequest httpServletRequest){ + + // 根据task枚举获取 应用信息 取出 accessKey 和 accessKeySecret 用于鉴权 + YdCallBackUtil ydCallBackUtil = new YdCallBackUtil(); + CtApply ctApply = ctApplyService.getApplyByTaskAndMethod(TaskInfoEnum.BROWSE.getTaskName(), TaskInfoEnum.BROWSE.getMethodName()); + Dto dto = ydCallBackUtil.callback(httpServletRequest, ctApply, data); + if (!dto.success(dto)) { + return dto; + } + + // 执行自己的业务逻辑 + log.info("============刷单回调鉴权完成 开始执行对应的定时业务逻辑================begin="); + log.info("回调======data:" + data); + // 获取自己想要的数据 + ReturnObje returnObje = JSONUtil.toBean(data, ReturnObje.class); + // job ID + String jobUuid = returnObje.getJobUuid(); + + // TODO 回调会重试 这里注意保证幂等 + // TODO 所以需要对接方在业务层面保障幂等(可以根据jobUuid或者taskUuid进行幂等保障,视startJob时是指定应用和机器人模式还是指定任务模式) + String keyJobUuid = PublicConstant.getJobUuidKeyPrefix(jobUuid); + if (!redisUtils.setIfAbsent(keyJobUuid, DateUtil.now())) { + log.info("-刷单回调接口-幂等性:keyJobUuid:" + keyJobUuid); + return Dto.returnResult(true); + } + + log.info("====returnObje====:{}", JSONUtil.toJsonStr(returnObje)); + JobQueryByUuidReturn jobQueryByUuidReturn = ydQuartzService.queryJobUuid(returnObje.getJobUuid(), ctApply.getAccessKeyId(), ctApply.getAccessKeySecret()); + log.info("====jobQueryByUuidReturn====:{}", JSONUtil.toJsonStr(jobQueryByUuidReturn)); + List inputsList = jobQueryByUuidReturn.getData().getRobotParams().getInputs(); + // 获取id + String id = null; + String buyerName = null; + for (ResultObj resultObj:inputsList) { + if ("id".equals(resultObj.getName())) { + id = resultObj.getValue(); + } + + if ("account".equals(resultObj.getName())) { + buyerName = resultObj.getValue(); + } + } + + Integer status = ClickOrderStatusEnum.EXECUTION_FAILE.value(); + if ("finish".equals(jobQueryByUuidReturn.getData().getStatus())) { + status = ClickOrderStatusEnum.EXECUTION_SUCCESS.value(); + } + + // 执行失败 + Boolean resultBoolean = false; + if (ObjectUtil.isNotEmpty(id)) { + CtBrowse ctBrowse = new CtBrowse(); + ctBrowse.setId(Long.valueOf(id)); + ctBrowse.setStatus(status); + ctBrowse.setPaymentResults(jobQueryByUuidReturn.getData().getRemark()); + + // 获取买家信息并修改买家信息 + CtBuyer ctBuyer = ctBuyerService.getBuyerOccupyStatusLock(buyerName); + if (ObjectUtil.isNotEmpty(ctBuyer) && BuyerOccupyStatusEnum.OCCUPIED.value().equals(ctBuyer.getOccupyStatus())) { + ctBuyer.setOccupyStatus(BuyerOccupyStatusEnum.UN_OCCUPIED.value()); + resultBoolean = ctBuyerService.updateById(ctBuyer); + } + + // TODO 需要更新的字段 从这里获取影刀返回的 然后接着设置到 对应的 基础信息里 + if (resultBoolean) { + resultBoolean = ctBrowseService.updateById(ctBrowse); + } + } + + log.info("============刷单回调鉴权完成 开始执行对应的定时业务逻辑================end==="); + return Dto.returnResult(resultBoolean); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/DhAddCarCallBackController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/DhAddCarCallBackController.java new file mode 100644 index 0000000..e133d6a --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/DhAddCarCallBackController.java @@ -0,0 +1,152 @@ +package me.zhengjie.modules.group.controller.callbcak; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.*; +import me.zhengjie.entity.quartz.JobQueryByUuidReturn; +import me.zhengjie.enums.BuyerOccupyStatusEnum; +import me.zhengjie.enums.ClickFarmingStatusEnum; +import me.zhengjie.enums.DhAddCarStatusEnum; +import me.zhengjie.enums.TaskInfoEnum; +import me.zhengjie.service.*; +import me.zhengjie.utils.RedisUtils; +import me.zhengjie.utils.YdCallBackUtil; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.List; + +/** + * @Description + * 敦煌加购定时任务回调逻辑 + * 回调需要鉴权,鉴权是根据 accesskey accessKeySrect + * 我们应用确认之后 accesskey 和 Srect是确定的 + * + * @Date 2022-8-23 + * @Author rch + */ +@Slf4j +@Validated +@RequestMapping("/api/dhAddCar") +@RestController +@Api(tags = "回调:敦煌加购-影刀回调") +public class DhAddCarCallBackController { + + @Resource + private CtApplyService ctApplyService; + @Resource + private YdQuartzService ydQuartzService; + @Resource + private DhAddCarService dhAddCarService; + @Resource + private DhAddCarOrderService dhAddCarOrderService; + @Resource + private RedisUtils redisUtils; + @Resource + private CtBuyerService ctBuyerService; + /** + * 敦煌加购-影刀回调 + */ + @ApiOperation("敦煌加购-影刀回调") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3700, message = "影刀回调参数空值异常!"), + @ApiResponse(code = 3701, message = "影刀回调鉴权异常!") + }) + @Log(value = "敦煌加购-影刀回调") + @PostMapping("/callback") + @AnonymousAccess + @Transactional(rollbackFor = Exception.class) + public Dto callback(@Valid @RequestBody String data, HttpServletRequest httpServletRequest){ + + // 根据task枚举获取 应用信息 取出 accessKey 和 accessKeySecret 用于鉴权 + YdCallBackUtil ydCallBackUtil = new YdCallBackUtil(); + CtApply ctApply = ctApplyService.getApplyByTaskAndMethod(TaskInfoEnum.DH_ADD_CAR_FARMING.getTaskName(), TaskInfoEnum.DH_ADD_CAR_FARMING.getMethodName()); + Dto dto = ydCallBackUtil.callback(httpServletRequest, ctApply, data); + if (!dto.success(dto)) { + return dto; + } + + // 执行自己的业务逻辑 + log.info("============敦煌加购回调鉴权完成 开始执行对应的定时业务逻辑================begin="); + log.info("回调======data:" + data); + // 获取自己想要的数据 + ReturnObje returnObje = JSONUtil.toBean(data, ReturnObje.class); + // job ID + String jobUuid = returnObje.getJobUuid(); + + // TODO 回调会重试 这里注意保证幂等 + // TODO 所以需要对接方在业务层面保障幂等(可以根据jobUuid或者taskUuid进行幂等保障,视startJob时是指定应用和机器人模式还是指定任务模式) + String keyJobUuid = PublicConstant.getJobUuidKeyPrefix(jobUuid); + if (!redisUtils.setIfAbsent(keyJobUuid, DateUtil.now())) { + log.info("-敦煌加购回调接口-幂等性:keyJobUuid:" + keyJobUuid); + return Dto.returnResult(true); + } + + log.info("====returnObje====:{}", JSONUtil.toJsonStr(returnObje)); + JobQueryByUuidReturn jobQueryByUuidReturn = ydQuartzService.queryJobUuid(returnObje.getJobUuid(), ctApply.getAccessKeyId(), ctApply.getAccessKeySecret()); + log.info("====jobQueryByUuidReturn====:{}", JSONUtil.toJsonStr(jobQueryByUuidReturn)); + List inputsList = jobQueryByUuidReturn.getData().getRobotParams().getInputs(); + // 获取id + String id = null; + String buyerName = null; + for (ResultObj resultObj:inputsList) { + if ("id".equals(resultObj.getName())) { + id = resultObj.getValue(); + } + if ("account".equals(resultObj.getName())) { + buyerName = resultObj.getValue(); + } + } + + Integer status = DhAddCarStatusEnum.ADD_CARD_FAILE.value(); + if ("finish".equals(jobQueryByUuidReturn.getData().getStatus())) { + status = DhAddCarStatusEnum.Add_CARD_SUCCESS.value(); + } + + // 执行失败 + Boolean resultBoolean = false; + if (ObjectUtil.isNotEmpty(id)) { + DhAddCar dhAddCar = new DhAddCar(); + dhAddCar.setId(Long.valueOf(id)); + + // 获取买家信息并修改买家信息 + CtBuyer ctBuyer = ctBuyerService.getBuyerOccupyStatusLock(buyerName); + if (ObjectUtil.isNotEmpty(ctBuyer) && BuyerOccupyStatusEnum.OCCUPIED.value().equals(ctBuyer.getOccupyStatus())) { + ctBuyer.setOccupyStatus(BuyerOccupyStatusEnum.UN_OCCUPIED.value()); + resultBoolean = ctBuyerService.updateById(ctBuyer); + } + + if (resultBoolean) { + dhAddCar.setStatus(status); + if (ClickFarmingStatusEnum.EXECUTION_FAILE.value().equals(status)) { + dhAddCar.setResponse(jobQueryByUuidReturn.getData().getRemark()); + }else { + dhAddCar.setResponse(jobQueryByUuidReturn.getData().getStatusName()); + } + resultBoolean = dhAddCarService.updateById(dhAddCar); + } + } + + log.info("============敦煌加购回调鉴权完成 开始执行对应的定时业务逻辑================end==="); + return Dto.returnResult(resultBoolean); + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/DhCarOrderCallBackController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/DhCarOrderCallBackController.java new file mode 100644 index 0000000..3cc8364 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/DhCarOrderCallBackController.java @@ -0,0 +1,170 @@ +package me.zhengjie.modules.group.controller.callbcak; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.*; +import me.zhengjie.entity.quartz.JobQueryByUuidReturn; +import me.zhengjie.enums.BuyerOccupyStatusEnum; +import me.zhengjie.enums.ClickOrderStatusEnum; +import me.zhengjie.enums.DhAddCarStatusEnum; +import me.zhengjie.enums.TaskInfoEnum; +import me.zhengjie.service.CtApplyService; +import me.zhengjie.service.CtBuyerService; +import me.zhengjie.service.DhAddCarOrderService; +import me.zhengjie.service.YdQuartzService; +import me.zhengjie.utils.RedisUtils; +import me.zhengjie.utils.YdCallBackUtil; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @Description + * 敦煌加购好评定时任务回调逻辑 + * 回调需要鉴权,鉴权是根据 accesskey accessKeySrect + * 我们应用确认之后 accesskey 和 Srect是确定的 + * + * @Date 2022-8-23 + * @Author rch + */ +@Slf4j +@Validated +@RequestMapping("/api/dhCarOrder") +@RestController +@Api(tags = "回调:敦煌加购好评-影刀回调") +public class DhCarOrderCallBackController { + + @Resource + private CtApplyService ctApplyService; + @Resource + private YdQuartzService ydQuartzService; + @Resource + private DhAddCarOrderService dhAddCarOrderService; + @Resource + private RedisUtils redisUtils; + @Resource + private CtBuyerService ctBuyerService; + + /** + * 速卖通刷单好评-好评回调 + */ + @ApiOperation("速卖通刷单好评-好评回调") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3700, message = "影刀回调参数空值异常!"), + @ApiResponse(code = 3701, message = "影刀回调鉴权异常!") + }) + @Log(value = "敦煌加购好评-好评回调") + @PostMapping("/callback") + @AnonymousAccess + @Transactional(rollbackFor = Exception.class) + public Dto callback(@Valid @RequestBody String data, HttpServletRequest httpServletRequest){ + + // 根据task枚举获取 应用信息 取出 accessKey 和 accessKeySecret 用于鉴权 + YdCallBackUtil ydCallBackUtil = new YdCallBackUtil(); + CtApply ctApply = ctApplyService.getApplyByTaskAndMethod(TaskInfoEnum.DH_WELL_RECEIVED.getTaskName(), TaskInfoEnum.DH_WELL_RECEIVED.getMethodName()); + Dto dto = ydCallBackUtil.callback(httpServletRequest, ctApply, data); + if (!dto.success(dto)) { + return dto; + } + + // 执行自己的业务逻辑 + log.info("============刷单回调鉴权完成 开始执行对应的定时业务逻辑================begin="); + log.info("回调======data:" + data); + // 获取自己想要的数据 + ReturnObje returnObje = JSONUtil.toBean(data, ReturnObje.class); + // job ID + String jobUuid = returnObje.getJobUuid(); + + // TODO 回调会重试 这里注意保证幂等 + // TODO 所以需要对接方在业务层面保障幂等(可以根据jobUuid或者taskUuid进行幂等保障,视startJob时是指定应用和机器人模式还是指定任务模式) + String keyJobUuid = PublicConstant.getJobUuidKeyPrefix(jobUuid); + if (!redisUtils.setIfAbsent(keyJobUuid, DateUtil.now())) { + log.info("-刷单回调接口-幂等性:keyJobUuid:" + keyJobUuid); + return Dto.returnResult(true); + } + + log.info("====returnObje====:{}", JSONUtil.toJsonStr(returnObje)); + JobQueryByUuidReturn jobQueryByUuidReturn = ydQuartzService.queryJobUuid(returnObje.getJobUuid(), ctApply.getAccessKeyId(), ctApply.getAccessKeySecret()); + log.info("====jobQueryByUuidReturn====:{}", JSONUtil.toJsonStr(jobQueryByUuidReturn)); + List inputsList = jobQueryByUuidReturn.getData().getRobotParams().getInputs(); + // 获取id + String id = null; + String buyerName = null; + for (ResultObj resultObj:inputsList) { + if ("id".equals(resultObj.getName())) { + id = resultObj.getValue(); + } + + if ("account".equals(resultObj.getName())) { + buyerName = resultObj.getValue(); + } + } + + Integer status = ClickOrderStatusEnum.EXECUTION_FAILE.value(); + if ("finish".equals(jobQueryByUuidReturn.getData().getStatus())) { + status = ClickOrderStatusEnum.EXECUTION_SUCCESS.value(); + } + + // 执行失败 + Boolean resultBoolean = false; + if (ObjectUtil.isNotEmpty(id)) { + DhAddCarOrder dhAddCarOrder = new DhAddCarOrder(); + dhAddCarOrder.setId(Long.valueOf(id)); + dhAddCarOrder.setStatus(status); + + // 获取买家信息并修改买家信息 + CtBuyer ctBuyer = ctBuyerService.getBuyerOccupyStatusLock(buyerName); + if (ObjectUtil.isNotEmpty(ctBuyer) && BuyerOccupyStatusEnum.OCCUPIED.value().equals(ctBuyer.getOccupyStatus())) { + ctBuyer.setOccupyStatus(BuyerOccupyStatusEnum.UN_OCCUPIED.value()); + resultBoolean = ctBuyerService.updateById(ctBuyer); + } + + // TODO 需要更新的字段 从这里获取影刀返回的 然后接着设置到 对应的 基础信息里 + List outputsList = jobQueryByUuidReturn.getData().getRobotParams().getOutputs(); + if (ObjectUtil.isNotEmpty(outputsList)) { + Map resultObjMap = outputsList.stream().collect(Collectors.toMap(ResultObj::getName, ResultObj::getValue)); + if (ObjectUtil.isNotEmpty(resultObjMap.containsKey("receipt"))) { + dhAddCarOrder.setPaymentResults(resultObjMap.get("receipt")); + if ("success".equals(resultObjMap.get("receipt"))) { + status = ClickOrderStatusEnum.EXECUTION_SUCCESS.value(); + } + } else { + status = ClickOrderStatusEnum.EXECUTION_FAILE.value(); + } + } else { + status = DhAddCarStatusEnum.CATCH_ORDER_FAILE.value(); + } + + // TODO 需要更新的字段 从这里获取影刀返回的 然后接着设置到 对应的 基础信息里 + if (resultBoolean) { + dhAddCarOrder.setStatus(status); + resultBoolean = dhAddCarOrderService.updateById(dhAddCarOrder); + } + } + + log.info("============刷单回调鉴权完成 开始执行对应的定时业务逻辑================end==="); + return Dto.returnResult(resultBoolean); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/DhCatchOrderCallBackController.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/DhCatchOrderCallBackController.java new file mode 100644 index 0000000..bc9fc22 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/controller/callbcak/DhCatchOrderCallBackController.java @@ -0,0 +1,166 @@ +package me.zhengjie.modules.group.controller.callbcak; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.*; +import me.zhengjie.entity.quartz.JobQueryByUuidReturn; +import me.zhengjie.enums.BuyerOccupyStatusEnum; +import me.zhengjie.enums.DhAddCarStatusEnum; +import me.zhengjie.enums.OrderTypeEnum; +import me.zhengjie.enums.TaskInfoEnum; +import me.zhengjie.service.*; +import me.zhengjie.utils.RedisUtils; +import me.zhengjie.utils.YdCallBackUtil; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @Description + * 敦煌-加购-抓单定时任务回调逻辑 + * 回调需要鉴权,鉴权是根据 accesskey accessKeySrect + * 我们应用确认之后 accesskey 和 Srect是确定的 + * + * @Date 2022-8-23 + * @Author rch + */ +@Slf4j +@Validated +@RequestMapping("/api/catchOrder") +@RestController +@Api(tags = "回调:敦煌抓单-影刀回调") +public class DhCatchOrderCallBackController { + + @Resource + private CtApplyService ctApplyService; + @Resource + private YdQuartzService ydQuartzService; + @Resource + private DhAddCarService dhAddCarService; + @Resource + private DhAddCarOrderService dhAddCarOrderService; + @Resource + private RedisUtils redisUtils; + @Resource + private CtBuyerService ctBuyerService; + + /** + * 敦煌-加购抓单-影刀回调 + */ + @ApiOperation("敦煌-加购抓单-影刀回调") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "响应成功"), + @ApiResponse(code = 2000, message = "服务器开小差了....,请稍后再试!"), + @ApiResponse(code = 3700, message = "影刀回调参数空值异常!"), + @ApiResponse(code = 3701, message = "影刀回调鉴权异常!") + }) + @Log(value = "敦煌-加购抓单-影刀回调") + @PostMapping("/callback") + @AnonymousAccess + @Transactional(rollbackFor = Exception.class) + public Dto callback(@Valid @RequestBody String data, HttpServletRequest httpServletRequest){ + + // 根据task枚举获取 应用信息 取出 accessKey 和 accessKeySecret 用于鉴权 + YdCallBackUtil ydCallBackUtil = new YdCallBackUtil(); + CtApply ctApply = ctApplyService.getApplyByTaskAndMethod(TaskInfoEnum.DH_ADD_CAR_CATCH_ORDER.getTaskName(), TaskInfoEnum.DH_ADD_CAR_CATCH_ORDER.getMethodName()); + Dto dto = ydCallBackUtil.callback(httpServletRequest, ctApply, data); + if (!dto.success(dto)) { + return dto; + } + + // 执行自己的业务逻辑 + log.info("============刷单回调鉴权完成 开始执行对应的定时业务逻辑================begin="); + log.info("回调======data:" + data); + // 获取自己想要的数据 + ReturnObje returnObje = JSONUtil.toBean(data, ReturnObje.class); + // job ID + String jobUuid = returnObje.getJobUuid(); + + // TODO 回调会重试 这里注意保证幂等 + // TODO 所以需要对接方在业务层面保障幂等(可以根据jobUuid或者taskUuid进行幂等保障,视startJob时是指定应用和机器人模式还是指定任务模式) + String keyJobUuid = PublicConstant.getJobUuidKeyPrefix(jobUuid); + if (!redisUtils.setIfAbsent(keyJobUuid, DateUtil.now())) { + log.info("-刷单回调接口-幂等性:keyJobUuid:" + keyJobUuid); + return Dto.returnResult(true); + } + + log.info("====returnObje====:{}", JSONUtil.toJsonStr(returnObje)); + JobQueryByUuidReturn jobQueryByUuidReturn = ydQuartzService.queryJobUuid(returnObje.getJobUuid(), ctApply.getAccessKeyId(), ctApply.getAccessKeySecret()); + log.info("====jobQueryByUuidReturn====:{}", JSONUtil.toJsonStr(jobQueryByUuidReturn)); + List inputsList = jobQueryByUuidReturn.getData().getRobotParams().getInputs(); + // 获取id + String id = null; + String buyerName = null; + for (ResultObj resultObj:inputsList) { + if ("id".equals(resultObj.getName())) { + id = resultObj.getValue(); + } + + if ("account".equals(resultObj.getName())) { + buyerName = resultObj.getValue(); + } + } + + Integer status = DhAddCarStatusEnum.CATCH_ORDER_FAILE.value(); + if ("finish".equals(jobQueryByUuidReturn.getData().getStatus())) { + status = DhAddCarStatusEnum.CATCH_ORDER_SUCCESS.value(); + } + + Boolean resultBoolean = false; + if (ObjectUtil.isNotEmpty(id)) { + DhAddCar dhAddCar = new DhAddCar(); + dhAddCar.setId(Long.valueOf(id)); + + // 获取买家信息并修改买家信息 + CtBuyer ctBuyer = ctBuyerService.getBuyerOccupyStatusLock(buyerName); + if (ObjectUtil.isNotEmpty(ctBuyer) && BuyerOccupyStatusEnum.OCCUPIED.value().equals(ctBuyer.getOccupyStatus())) { + ctBuyer.setOccupyStatus(BuyerOccupyStatusEnum.UN_OCCUPIED.value()); + resultBoolean = ctBuyerService.updateById(ctBuyer); + } + + // TODO 需要更新的字段 从这里获取影刀返回的 然后接着设置到 对应的 基础信息里 + List outputsList = jobQueryByUuidReturn.getData().getRobotParams().getOutputs(); + if (ObjectUtil.isNotEmpty(outputsList)) { + Map resultObjMap = outputsList.stream().collect(Collectors.toMap(ResultObj::getName, ResultObj::getValue)); + DhAddCarOrder dhAddCarOrder = BeanUtil.mapToBean(resultObjMap, DhAddCarOrder.class, false); + if (ObjectUtil.isNotEmpty(dhAddCarOrder)) { + // 设置订单 公司 平台信息 + dhAddCarOrder.setType(OrderTypeEnum.CLICK_FARMING.value()); + if (dhAddCarOrderService.save(dhAddCarOrder)) { + dhAddCarOrder.setAddCarId(Long.valueOf(id)); + } + } + } else { + status = DhAddCarStatusEnum.CATCH_ORDER_FAILE.value(); + } + + dhAddCar.setResponse(jobQueryByUuidReturn.getData().getStatusName()); + dhAddCar.setStatus(status); + resultBoolean = dhAddCarService.updateById(dhAddCar); + } + + log.info("============敦煌-加购抓单-回调鉴权完成 开始执行对应的定时业务逻辑================end==="); + return Dto.returnResult(resultBoolean); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtApplyAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtApplyAddDTO.java new file mode 100644 index 0000000..5f665af --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtApplyAddDTO.java @@ -0,0 +1,57 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * 应用信息(ct_apply)新增 DTO + * + * Author zhw + * Data 2022-07-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel(description="添加应用信息") +public class CtApplyAddDTO { + + /** 应用名称 */ + @NotNull + @ApiModelProperty(value = "应用名称", required = true) + private String name; + + /** 任务名称 */ + @NotNull + @ApiModelProperty(value = "任务名称", required = true) + private String taskName; + + /** 方法名称 */ + @ApiModelProperty(value = "方法名称") + private String methodName; + + /** accessKeyId */ + @NotNull + @ApiModelProperty(value = "accessKeyId", required = true) + private String accessKeyId; + + /** accessKeySecret */ + @NotNull + @ApiModelProperty(value = "accessKeySecret", required = true) + private String accessKeySecret; + + /** 应用id */ + @NotNull + @ApiModelProperty(value = "应用id", required = true) + private String robotUuid; + + /** 备注 */ + @NotNull + @ApiModelProperty(value = "备注", required = true) + private String remark; + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtApplyListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtApplyListDTO.java new file mode 100644 index 0000000..4347328 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtApplyListDTO.java @@ -0,0 +1,43 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtApply; + + +/** + * @Description 分页查询 应用信息 + * @Date 2022/7/23 + * @Author zhw + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("查询用户") +public class CtApplyListDTO extends PageDTO { + + /** 应用名称 */ + @ApiModelProperty(value = "应用名称") + private String name; + /** 应用id */ + @ApiModelProperty(value = "应用id") + private String robotUuid; + + public Wrapper getWrapper(){ + QueryWrapper qw = new QueryWrapper<>(); + qw + .like(ObjectUtil.isNotEmpty(name),"name",name) + .like(ObjectUtil.isNotEmpty(robotUuid),"robot_uuid", robotUuid) + .orderBy(ObjectUtil.isNotEmpty(getSort()),isAsc(),getSort()) + .orderByDesc("id") + ; + return qw; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtApplyUpdateDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtApplyUpdateDTO.java new file mode 100644 index 0000000..f5476ce --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtApplyUpdateDTO.java @@ -0,0 +1,54 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * 应用信息(ct_apply)修改 DTO + * + * Author zhw + * Data 2022-07-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("修改应用") +public class CtApplyUpdateDTO { + + @NotNull + @ApiModelProperty(value = "id", required = true) + private Long id; + + /** 应用名称 */ + @ApiModelProperty(value = "应用名称") + private String name; + + /** 任务名称 */ + @ApiModelProperty(value = "任务名称") + private String taskName; + + /** 方法名称 */ + @ApiModelProperty(value = "方法名称") + private String methodName; + + /** accessKeyId */ + @ApiModelProperty(value = "accessKeyId") + private String accessKeyId; + + /** accessKeySecret */ + @ApiModelProperty(value = "accessKeySecret") + private String accessKeySecret; + + /** 应用id */ + @ApiModelProperty(value = "应用id") + private String robotUuid; + + /** 备注 */ + @ApiModelProperty(value = "备注") + private String remark; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBrowseAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBrowseAddDTO.java new file mode 100644 index 0000000..f99b236 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBrowseAddDTO.java @@ -0,0 +1,33 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * 浏览收藏信息 DTO + * + * @author rch + * @create 2022-11-04 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("新增浏览收藏") +public class CtBrowseAddDTO { + + /** 买家ID */ + @NotNull + @ApiModelProperty(value = "买家ID", required = true) + private Long buyerId; + + /** 收藏链接 */ + @NotNull + @ApiModelProperty(value = "收藏链接", required = true) + private String linkUrl; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBrowseListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBrowseListDTO.java new file mode 100644 index 0000000..7b8a80e --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBrowseListDTO.java @@ -0,0 +1,57 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtBuyer; +import me.zhengjie.enums.ClickBrowseStatusEnum; +import me.zhengjie.enums.ClickFarmingStatusEnum; +import me.zhengjie.enums.ClickOrderStatusEnum; + +import java.util.Arrays; +import java.util.Date; + + +/** + * @Description 分页查询 浏览刷单 + * @Date 2022-11-04 + * @Author rch + */ +@Data +@ApiModel("分页查询浏览刷单") +public class CtBrowseListDTO extends PageDTO { + + /** 账号 */ + @ApiModelProperty(value = "账号") + private String account; + + /** 收藏链接 */ + @ApiModelProperty(value = "收藏链接") + private String linkUrl; + + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + @ApiModelProperty(value = "状态 1.待执行 2.执行中 3.执行成功 4.执行失败", allowableValues = "1,2,3,4") + private Integer status; + + @ApiModelProperty(value = "是否是仅查询可以执行的浏览收藏") + private Integer inStatusList; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .eq(ObjectUtil.isNotEmpty(account), "ctBuyer.account", account) + .eq(ObjectUtil.isNotEmpty(linkUrl), "ctBrowse.link_url", linkUrl) + .eq(ObjectUtil.isNotEmpty(status), "ctBrowse.status", status) + .in(ObjectUtil.isNotEmpty(inStatusList), "ctBrowse.status", Arrays.asList(ClickBrowseStatusEnum.TOBE_EXECUTION.value(), ClickBrowseStatusEnum.EXECUTION_FAILE.value())) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + .orderByDesc("ctBrowse.updated_at") + ; + + return qw; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBrowseUpdateDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBrowseUpdateDTO.java new file mode 100644 index 0000000..3859d1a --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBrowseUpdateDTO.java @@ -0,0 +1,46 @@ +package me.zhengjie.modules.group.dto; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + + +/** + * 修改浏览收藏 + * + * @author rch + * @create 2022-11-04 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("修改浏览收藏") +public class CtBrowseUpdateDTO { + + @NotNull + @ApiModelProperty(value = "id") + private Long id; + + /** 买家ID */ + @ApiModelProperty(value = "买家ID") + private Long buyerId; + + /** 收藏链接 */ + @ApiModelProperty(value = "收藏链接") + private String linkUrl; + + /** 状态描述 */ + @ApiModelProperty(value = "状态描述") + private String paymentResults; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBuyerAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBuyerAddDTO.java new file mode 100644 index 0000000..97ed46d --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBuyerAddDTO.java @@ -0,0 +1,135 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * 买家信息 DTO + * + * @author rch + * @create 2022-06-22 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("新增买家") +public class CtBuyerAddDTO { + + /** 昵称*/ + @NotNull + @ApiModelProperty(value = "昵称", required = true) + private String nickName; + + /** 账号*/ + @NotNull + @ApiModelProperty(value = "账号", required = true) + private String account; + + /** 密码*/ + @NotNull + @ApiModelProperty(value = "密码", required = true) + private String pwd; + + /** 公司id */ + @NotNull + @ApiModelProperty(value = "公司id", required = true) + private Long companyId; + + /** 平台id */ + @NotNull + @ApiModelProperty(value = "平台id", required = true) + private Integer platformId; + + ////////////////////////////////////// 新增字段 + /** 国家 */ + @NotNull + @ApiModelProperty(value = "国家", required = true) + private String contntryShort; + + /** VPN_ID(导入excel里包含) */ + @NotNull + @ApiModelProperty(value = "VPN_ID", required = true) + private Long vpnId; + + /** 信用卡ID */ + @ApiModelProperty(value = "信用卡ID", required = true) + private Long cardId; + + /** 用户等级(导入默认内部账号) 1.普通 2.精品 3.压力 4.内部账号 */ + @NotNull + @Min(1) + @Max(4) + @ApiModelProperty(value = "用户等级(导入默认内部账号) 1.普通 2.精品 3.压力 4.内部账号", required = true, allowableValues = "1,2,3,4") + private Integer level; + + /** 占用状态 1.已占用 2.未占用 */ + @NotNull + @Min(1) + @Max(2) + @ApiModelProperty(value = "占用状态 1.已占用 2.未占用", required = true, allowableValues = "1,2") + private Integer occupyStatus; + + /** 状态(导入默认正常) 1.待注册 2待验证 3.待完善 4.正常 5.异常 6.可用但已用 7.删除 */ + @NotNull + @Min(1) + @Max(7) + @ApiModelProperty(value = "状态(导入默认正常) 1.待注册 2待验证 3.待完善 4.正常 5.异常 6.可用但已用 7.删除", required = true, allowableValues = "1,2,3,4,5,6,7") + private Integer status; + + // ==================地址信息相关========================================begin + /** 地址1 */ + @NotNull + @ApiModelProperty(value = "地址1", required = true) + private String addressline1; + + /** 国家 */ + @NotNull + @ApiModelProperty(value = "国家", required = true) + private String country; + + /** 州 */ + @NotNull + @ApiModelProperty(value = "州", required = true) + private String state; + + /** 电话 */ + @NotNull + @ApiModelProperty(value = "电话", required = true) + private String tel; + + /** lastname */ + @NotNull + @ApiModelProperty(value = "lastname", required = true) + private String lastname; + + /** 税号 */ + @ApiModelProperty(value = "税号") + private String vatNumber; + + /** 城市 */ + @NotNull + @ApiModelProperty(value = "城市", required = true) + private String city; + + /** 地址2 */ + @ApiModelProperty(value = "地址2") + private String addressline2; + + /** firstname */ + @NotNull + @ApiModelProperty(value = "firstname", required = true) + private String firstname; + + /** 邮政编码 */ + @NotNull + @ApiModelProperty(value = "邮政编码", required = true) + private String postalcode; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBuyerListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBuyerListDTO.java new file mode 100644 index 0000000..9c6dc08 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBuyerListDTO.java @@ -0,0 +1,57 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtBuyer; + + +/** + * @Description 分页查询 买家信息 + * @Date 2022-06-22 + * @Author rch + */ +@Data +@ApiModel("查询买家") +public class CtBuyerListDTO extends PageDTO { + + /** 昵称*/ + @ApiModelProperty(value = "昵称") + private String nickName; + + /** 账号*/ + @ApiModelProperty(value = "账号") + private String account; + + /** 姓名 */ + @ApiModelProperty(value = "姓名") + private String pwd; + + /** 平台id */ + @ApiModelProperty(value = "平台id") + private Integer platformId; + + /** 公司id */ + @ApiModelProperty(value = "公司id") + private Long companyId; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .eq(ObjectUtil.isNotEmpty(platformId), "t1.platform_id", platformId) + .eq(ObjectUtil.isNotEmpty(companyId), "t1.company_id", companyId) + .like(ObjectUtil.isNotEmpty(nickName), "t1.nick_name", nickName) + .like(ObjectUtil.isNotEmpty(account), "t1.account", account) + .like(ObjectUtil.isNotEmpty(pwd), "t1.pwd", pwd) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + .orderByDesc("updated_at") + ; + + return qw; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBuyerUpdateDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBuyerUpdateDTO.java new file mode 100644 index 0000000..9bd28c2 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtBuyerUpdateDTO.java @@ -0,0 +1,122 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + + +/** + * 修改 买家 + * + * @author rch + * @create 2022-06-22 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("编辑买家") +public class CtBuyerUpdateDTO { + + @NotNull + @ApiModelProperty(value = "Id", required = true) + private Integer id; + + /** 公司id */ + @ApiModelProperty(value = "公司id") + private Long companyId; + + /** 平台id */ + @ApiModelProperty(value = "平台id") + private Integer platformId; + + /** 昵称 */ + @ApiModelProperty(value = "昵称") + private String nickName; + + /** 账号 */ + @ApiModelProperty(value = "账号") + private String account; + + /** 密码 */ + @ApiModelProperty(value = "密码") + private String pwd; + + ////////////////////////////////////// 新增字段 + /** 国家 */ + @ApiModelProperty(value = "国家") + private String contntryShort; + + /** VPN_ID(导入excel里包含) */ + @ApiModelProperty(value = "VPN_ID") + private Long vpnId; + + /** 信用卡ID */ + @ApiModelProperty(value = "信用卡ID") + private Long cardId; + + /** 用户等级(导入默认内部账号) 1.普通 2.精品 3.压力 4.内部账号 */ + @Min(1) + @Max(4) + @ApiModelProperty(value = "用户等级(导入默认内部账号) 1.普通 2.精品 3.压力 4.内部账号", allowableValues = "1,2,3,4") + private Integer level; + + /** 占用状态 1.已占用 2.未占用 */ + @Min(1) + @Max(2) + @ApiModelProperty(value = "占用状态 1.已占用 2.未占用", allowableValues = "1,2") + private Integer occupyStatus; + + /** 状态(导入默认正常) 1.待注册 2待验证 3.待完善 4.正常 5.异常 6.可用但已用 7.删除 */ + @Min(1) + @Max(7) + @ApiModelProperty(value = "状态(导入默认正常) 1.待注册 2待验证 3.待完善 4.正常 5.异常 6.可用但已用 7.删除", allowableValues = "1,2,3,4,5,6,7") + private Integer status; + + // ==================地址信息相关========================================begin + /** 地址1 */ + @ApiModelProperty(value = "地址1") + private String addressline1; + + /** 国家 */ + @ApiModelProperty(value = "国家") + private String country; + + /** 州 */ + @ApiModelProperty(value = "州") + private String state; + + /** 电话 */ + @ApiModelProperty(value = "电话") + private String tel; + + /** lastname */ + @ApiModelProperty(value = "lastname") + private String lastname; + + /** 税号 */ + @ApiModelProperty(value = "税号") + private String vatNumber; + + /** 城市 */ + @ApiModelProperty(value = "城市") + private String city; + + /** 地址2 */ + @ApiModelProperty(value = "地址2") + private String addressline2; + + /** firstname */ + @ApiModelProperty(value = "firstname") + private String firstname; + + /** 邮政编码 */ + @ApiModelProperty(value = "邮政编码") + private String postalcode; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCardAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCardAddDTO.java new file mode 100644 index 0000000..8cba632 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCardAddDTO.java @@ -0,0 +1,105 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + * 信用卡信息 DTO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("新增信用卡") +public class CtCardAddDTO { + + /** 父ID */ + // private Long parentId; + + /** 卡号 */ + @NotBlank + @ApiModelProperty(value = "卡号", required = true) + private String number; + +// /** PIN码 */ +// @NotBlank +// @ApiModelProperty(value = "PIN码", required = true) +// private String pinNumber; + + /** 持卡人姓氏 */ + @NotBlank + @ApiModelProperty(value = "持卡人姓氏", required = true) + private String holderSurname; + + /** 持卡人名称 */ + @NotBlank + @ApiModelProperty(value = "持卡人名称", required = true) + private String holderName; + + /** 有效期 */ + @NotBlank + private String termOfValidity; + + /** 开卡日期 */ + // private Date openDate; + + /** 所属国家 */ + @ApiModelProperty(value = "所属国家", required = true) + private String contntryShort; + + /** 信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡 */ + @NotNull + @Min(1) + @Max(3) + @ApiModelProperty(value = "信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡", required = true, allowableValues = "1,2,3") + private Integer type; + + /** 所属厂商:1.AmzKeys 2.Airwallex */ + @NotNull + @Min(1) + @Max(2) + @ApiModelProperty(value = "所属厂商:1.AmzKeys 2.Airwallex", required = true, allowableValues = "1,2") + private Integer cardDealer; + + /** 身份证号 */ + // private String idNumber; + + /** 省份 */ + // private String province; + + /** 城市 */ + // private String country; + + /** 地址 */ + // private String address; + + /** 手机号 */ + // private String phone; + + /** 邮箱 */ + // private String email; + + /** 登陆账号 */ + // private String account; + + /** 密码 */ + @ApiModelProperty(value = "密码", required = true) + @NotNull + private String pwd; + + /** 备注 */ + @ApiModelProperty(value = "备注") + private String remarks; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCardListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCardListDTO.java new file mode 100644 index 0000000..bcb8320 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCardListDTO.java @@ -0,0 +1,62 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtBuyer; + + +/** + * @Description 分页查询 信用卡 + * @Date 2022-07-9 + * @Author rch + */ +@Data +@ApiModel("分页查询信用卡") +public class CtCardListDTO extends PageDTO { + + /** 卡号 */ + @ApiModelProperty(value = "卡号") + private String number; + + /** PIN码 */ + @ApiModelProperty(value = "PIN码") + private String pinNumber; + + /** 持卡人名称 */ + @ApiModelProperty(value = "持卡人名称") + private String holderName; + + /** 信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡 */ + @ApiModelProperty(value = "信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡", allowableValues = "1,2,3") + private Integer type; + + /** 所属厂商:1.AmzKeys 2.Airwallex */ + @ApiModelProperty(value = "所属厂商:1.AmzKeys 2.Airwallex", allowableValues = "1,2") + private Integer cardDealer; + + /** 状态:1.正常、2.异常、3.已删除 */ + @ApiModelProperty(value = "状态:1.正常、2.异常、3.已删除", allowableValues = "1,2,3") + private Integer status; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .eq(ObjectUtil.isNotEmpty(type), "type", type) + .eq(ObjectUtil.isNotEmpty(cardDealer), "card_dealer", cardDealer) + .eq(ObjectUtil.isNotEmpty(status), "status", status) + .like(ObjectUtil.isNotEmpty(number), "number", number) + .like(ObjectUtil.isNotEmpty(pinNumber), "pin_number", pinNumber) + .like(ObjectUtil.isNotEmpty(holderName), "holder_name", holderName) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + .orderByDesc("updated_at") + ; + + return qw; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCardUpdateDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCardUpdateDTO.java new file mode 100644 index 0000000..c63831c --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCardUpdateDTO.java @@ -0,0 +1,75 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + + +/** + * 修改信用卡 + * + * @author rch + * @create 2022-06-22 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("修改信用卡") +public class CtCardUpdateDTO { + + @NotNull + @ApiModelProperty(value = "Id", required = true) + private Integer id; + + /** 卡号 */ + @ApiModelProperty(value = "卡号") + private String number; + +// /** PIN码 */ +// @ApiModelProperty(value = "PIN码") +// private String pinNumber; + + /** 持卡人姓氏 */ + @ApiModelProperty(value = "持卡人姓氏") + private String holderSurname; + + /** 持卡人名称 */ + @ApiModelProperty(value = "持卡人名称") + private String holderName; + + /** 有效期 */ + @ApiModelProperty(value = "有效期") + private String termOfValidity; + + /** 所属国家 */ + @ApiModelProperty(value = "所属国家") + private String contntryShort; + + /** 信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡 */ + @Min(1) + @Max(3) + @ApiModelProperty(value = "信用卡类型 1.Payoneer 2.万事达虚拟卡 3.Visa信用卡", required = true, allowableValues = "1,2,3") + private Integer type; + + /** 所属厂商:1.AmzKeys 2.Airwallex */ + @Min(1) + @Max(2) + @ApiModelProperty(value = "所属厂商:1.AmzKeys 2.Airwallex", required = true, allowableValues = "1,2") + private Integer cardDealer; + + /** 密码 */ + @NotNull + @ApiModelProperty(value = "密码", required = true) + private String pwd; + + /** 备注 */ + @ApiModelProperty(value = "备注") + private String remarks; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickFarmingAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickFarmingAddDTO.java new file mode 100644 index 0000000..3ec971a --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickFarmingAddDTO.java @@ -0,0 +1,83 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import io.swagger.models.auth.In; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 刷单信息 DTO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("新增刷单信息") +public class CtClickFarmingAddDTO { + + @NotNull + /** 买家id */ + @ApiModelProperty(value = "买家id", required = true) + private Long buyerId; + + /** 店铺名称 */ + @ApiModelProperty(value = "店铺名称", required = true) + private String shopName; + + /** 刷单类型 */ + @NotNull + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接", required = true, allowableValues = "1,2") + private Integer paramsType; + + /** 关键词 */ + @ApiModelProperty(value = "关键词", required = true) + private String keyWord; + + /** 标题 */ + @ApiModelProperty(value = "标题", required = true) + private String title; + + /** 链接 */ + @ApiModelProperty(value = "链接", required = true) + private String link; + + /** 数量 */ + @ApiModelProperty(value = "数量", required = true) + private Integer number; + + /** 规格 */ + @ApiModelProperty(value = "规格") + private String specification; + + /** 颜色 */ + @ApiModelProperty(value = "颜色") + private String color; + + /** item */ + @ApiModelProperty(value = "item", required = true) + private String item; + + @ApiModelProperty(value = "exchange") + private String exchange; + + /** 最小价格区间 */ + @ApiModelProperty(value = "最小价格区间") + private String sectionMin; + + /** 最大价格区间 */ + @ApiModelProperty(value = "最大价格区间") + private String sectionMax; + + /** 留言 */ + @NotBlank + @ApiModelProperty(value = "留言", required = true) + private String amessage; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickFarmingDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickFarmingDTO.java new file mode 100644 index 0000000..5827d9b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickFarmingDTO.java @@ -0,0 +1,87 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtBuyer; +import me.zhengjie.enums.ClickFarmingStatusEnum; + +import java.util.Arrays; +import java.util.List; + + +/** + * @Description 分页查询 刷单信息 + * @Date 2022-07-9 + * @Author rch + */ +@Data +@ApiModel("分页查询刷单信息") +public class CtClickFarmingDTO extends PageDTO { + + /** 关键词 */ + @ApiModelProperty(value = "关键词") + private String keyWord; + + /** Item */ + @ApiModelProperty(value = "Item") + private String item; + + /** 店铺名称 */ + @ApiModelProperty(value = "店铺名称") + private String shopName; + +// /** 刷单类型 */ +// private Integer type; + /** 刷单类型 */ + private Integer paramsType; + /** 国家 */ + private String country; + /** 账号 */ + private String account; + +// /** 平台类型 2.速卖通 1.敦煌*/ +// private Integer platformId; + + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 5.代付款 */ + @ApiModelProperty(value = "状态 1.待执行 2.执行中 3.执行成功 4.执行失败 5.代付款", allowableValues = "1,2,3,4,5") + private Integer status; + + @ApiModelProperty(value = "") + private List inStatusList; + + /** 支付订单ID */ + @ApiModelProperty(value = "支付订单ID") + private String payOrderId; + +// @ApiModelProperty(value = "是否是抓单 1.是 0.否") // ct_click_order_id +// private Integer inCatchorder; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw +// .eq(ObjectUtil.isNotEmpty(type), "farming.type", type) + .eq(ObjectUtil.isNotEmpty(paramsType), "farming.params_type", paramsType) + .eq(ObjectUtil.isNotEmpty(country), "buyer.contntry_short", country) + .eq(ObjectUtil.isNotEmpty(account), "buyer.account", account) +// .eq(ObjectUtil.isNotEmpty(platformId), "buyer.platform_id", platformId) + .eq(ObjectUtil.isNotEmpty(status), "farming.status", status) +// .isNull(ObjectUtil.isNotEmpty(inCatchorder), "farming.ct_click_order_id") + .in(ObjectUtil.isNotEmpty(inStatusList), "farming.status", Arrays.asList(ClickFarmingStatusEnum.TOBE_EXECUTION.value(), ClickFarmingStatusEnum.EXECUTION_FAILE.value())) +// .in(ObjectUtil.isNotEmpty(inCatchorder), "farming.status", Arrays.asList(ClickFarmingStatusEnum.EXECUTION_SUCCESS.value(), ClickFarmingStatusEnum.EXECUTION_FAILE.value())) + .like(ObjectUtil.isNotEmpty(keyWord), "farming.key_word", keyWord) + .like(ObjectUtil.isNotEmpty(item), "farming.item", item) + .like(ObjectUtil.isNotEmpty(shopName), "farming.shop_name", shopName) + .like(ObjectUtil.isNotEmpty(payOrderId), "clickOrder.order_id", payOrderId) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + .orderByDesc("updated_at") + ; + + return qw; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickFarmingEditDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickFarmingEditDTO.java new file mode 100644 index 0000000..a10d747 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickFarmingEditDTO.java @@ -0,0 +1,84 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 刷单信息 DTO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("刷单信息") +public class CtClickFarmingEditDTO { + + @NotNull + @ApiModelProperty(value = "Id", required = true) + private Long id; + + @ApiModelProperty(value = "buyerId") + @NotNull + private Long buyerId; + + /** 刷单类型 */ + @NotNull + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接", required = true, allowableValues = "1,2") + private Integer paramsType; + + /** 店铺名称 */ + @ApiModelProperty(value = "店铺名称") + private String shopName; + + /** 关键词 */ + @ApiModelProperty(value = "关键词") + private String keyWord; + + /** 标题 */ + @ApiModelProperty(value = "标题") + private String title; + + /** 链接 */ + @ApiModelProperty(value = "链接") + private String link; + + /** 数量 */ + @ApiModelProperty(value = "数量") + private Integer number; + + /** 规格 */ + @ApiModelProperty(value = "规格") + private String specification; + + /** 颜色 */ + @ApiModelProperty(value = "颜色") + private String color; + + /** item */ + @ApiModelProperty(value = "item") + private String item; + + @ApiModelProperty(value = "exchange") + private String exchange; + + /** 最小价格区间 */ + @ApiModelProperty(value = "最小价格区间") + private String sectionMin; + + /** 最大价格区间 */ + @ApiModelProperty(value = "最大价格区间") + private String sectionMax; + + /** 留言 */ + @ApiModelProperty(value = "留言") + private String amessage; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickOrderAddDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickOrderAddDto.java new file mode 100644 index 0000000..1e35345 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickOrderAddDto.java @@ -0,0 +1,71 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * 刷单-订单评论信息 + * + * @author rch + * @since 2022-10-20 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("新增刷单订单评论") +public class CtClickOrderAddDto { + + /** 公司ID */ + @NotNull + @ApiModelProperty(value = "公司ID", required = true) + private Long companyId; + + /** 总金额 */ + @NotNull + @ApiModelProperty(value = "总金额", required = true) + private String amount; + + /** 状态描述 */ + @NotNull + @ApiModelProperty(value = "状态描述", required = true) + private String paymentResults; + + /** 店铺名称 */ + @NotNull + @ApiModelProperty(value = "店铺名称", required = true) + private String shop; + + /** 购买数量 */ + @NotNull + @ApiModelProperty(value = "购买数量", required = true) + private String pricesNumber; + + /** 订单id */ + @NotNull + @ApiModelProperty(value = "订单id", required = true) + private String orderId; + + /** 商品名称 */ + @NotNull + @ApiModelProperty(value = "商品名称", required = true) + private String shopName; + + /** 时间 */ + @NotNull + @ApiModelProperty(value = "时间", required = true) + private String orderDate; + + /** 评论 */ + @ApiModelProperty(value = "评论") + private String comment; + + /** 图片地址 */ + @ApiModelProperty(value = "图片地址") + private String paths; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickOrderCommentDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickOrderCommentDto.java new file mode 100644 index 0000000..19fb974 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickOrderCommentDto.java @@ -0,0 +1,34 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * 刷单-订单评论信息 + * + * @author rch + * @since 2022-10-20 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("新增评论") +public class CtClickOrderCommentDto { + /** 刷单订单id */ + @NotNull + @ApiModelProperty(value = "Id", required = true) + private Long id; + + /** 评论信息 */ + @ApiModelProperty(value = "评论信息") + private String comment; + + /** 图片地址 */ + @ApiModelProperty(value = "图片地址") + private String paths; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickOrderListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickOrderListDTO.java new file mode 100644 index 0000000..6751a07 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickOrderListDTO.java @@ -0,0 +1,69 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtClickOrder; + + +/** + * @Description 分页查询 刷单订单信息 + * @Date 2022-06-22 + * @Author rch + */ +@Data +@ApiModel("分页查询刷单订单") +public class CtClickOrderListDTO extends PageDTO { + + /** 店铺 */ + @ApiModelProperty(value = "店铺") + private String shop; + + /** 订单id */ + @ApiModelProperty(value = "订单id") + private String orderId; + + /** 公司id */ + @ApiModelProperty(value = "公司id") + private Long companyId; + + /** 类型 */ + @ApiModelProperty(value = "类型") + private Integer type; + + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + @ApiModelProperty(value = "状态 1.待执行 2.执行中 3.执行成功 4.执行失败", allowableValues = "1,2,3,4") + private Integer status; + + /** 开始时间 */ + @ApiModelProperty(value = "开始时间") + private String sTime; + + /** 结束时间 */ + @ApiModelProperty(value = "结束时间") + private String eTime; + + @ApiModelProperty(value = "是否评论") + private Boolean commentBoolean; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .eq(ObjectUtil.isNotEmpty(companyId), "company.id", companyId) + .eq(ObjectUtil.isNotEmpty(status), "clickOrder.status", status) + .eq(ObjectUtil.isNotEmpty(type), "clickOrder.type", type) + .isNotNull((ObjectUtil.isNotEmpty(commentBoolean) && commentBoolean), "comment") + .like(ObjectUtil.isNotEmpty(shop), "clickOrder.shop", shop) + .like(ObjectUtil.isNotEmpty(orderId), "clickOrder.order_id", orderId) + .between(ObjectUtil.isNotEmpty(sTime) && ObjectUtil.isNotEmpty(eTime), "clickOrder.created_at", sTime, eTime) + .orderByDesc("created_at") + ; + + return qw; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickOrderSupplementDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickOrderSupplementDto.java new file mode 100644 index 0000000..16043a3 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtClickOrderSupplementDto.java @@ -0,0 +1,58 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * 刷单-订单信息手动补录 + * + * @author rch + * @since 2022-10-15 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("补录订单信息") +public class CtClickOrderSupplementDto { + /** 刷单id */ + @NotNull + @ApiModelProperty(value = "刷单id", required = true) + private Long clickFarmingId; + + /** 总金额 */ + @NotNull + @ApiModelProperty(value = "总金额", required = true) + private String amount; + + /** 状态描述 */ + @NotNull + @ApiModelProperty(value = "状态描述", required = true) + private String paymentResults; + + /** 店铺名称 */ + @NotNull + @ApiModelProperty(value = "店铺名称", required = true) + private String shop; + + /** 购买数量 */ + @NotNull + @ApiModelProperty(value = "购买数量", required = true) + private String pricesNumber; + + /** 订单id */ + @ApiModelProperty(value = "订单id") + private String orderId; + + /** 商品名称 */ + @ApiModelProperty(value = "商品名称") + private String shopName; + + /** 时间 */ + @ApiModelProperty(value = "时间") + private String orderDate; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCompanyAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCompanyAddDTO.java new file mode 100644 index 0000000..dfad073 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCompanyAddDTO.java @@ -0,0 +1,29 @@ +package me.zhengjie.modules.group.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 公司信息 DTO + * + * @author rch + * @create 2022-06-28 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtCompanyAddDTO { + + /** 名称 */ + private String name; + /** 地址 */ + private String address; + /** 电话 */ + private String phone; + + // 下面这两个需要新增的时候生成 + /** 商户码(公司调用api公司唯一标识) */ + /** 商户token(公司调用api公司token身份标识) */ +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCompanyListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCompanyListDTO.java new file mode 100644 index 0000000..72aa00a --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCompanyListDTO.java @@ -0,0 +1,47 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.Data; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtBuyer; + + +/** + * @Description 分页查询 公司信息 + * @Date 2022-06-28 + * @Author rch + */ +@Data +public class CtCompanyListDTO extends PageDTO { + /** 名称 */ + private String name; + /** 电话 */ + private String phone; + /** 地址 */ + private String address; + /** 商户码(公司调用api公司唯一标识) */ + private String number; + /** 商户token(公司调用api公司token身份标识) */ + private String token; + + /** 操作人账号*/ + private String gmName; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .like(ObjectUtil.isNotEmpty(name), "name", name) + .like(ObjectUtil.isNotEmpty(phone), "phone", phone) + .like(ObjectUtil.isNotEmpty(address), "address", address) + .like(ObjectUtil.isNotEmpty(number), "number", number) + .like(ObjectUtil.isNotEmpty(token), "token", token) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + .orderByDesc("updated_at") + ; + + return qw; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCompanyUpdateDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCompanyUpdateDTO.java new file mode 100644 index 0000000..0309484 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtCompanyUpdateDTO.java @@ -0,0 +1,30 @@ +package me.zhengjie.modules.group.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + + +/** + * 修改 买家 + * + * @author rch + * @create 2022-06-22 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtCompanyUpdateDTO { + + @NotNull + private Integer id; + /** 名称 */ + private String name; + /** 地址 */ + private String address; + /** 电话 */ + private String phone; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtDhPayAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtDhPayAddDTO.java new file mode 100644 index 0000000..22d3499 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtDhPayAddDTO.java @@ -0,0 +1,30 @@ +package me.zhengjie.modules.group.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; + +/** + * 敦煌支付信息 DTO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtDhPayAddDTO { + + /** 买家名称 */ + @NotBlank + private String buyerName; + + /** 支付订单ID(敦煌的) */ + @NotBlank + @Pattern(regexp = "^[0-9]+(,[0-9]+)*$", message = "订单编号不符合要求") + private String orderId; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtDhPayListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtDhPayListDTO.java new file mode 100644 index 0000000..3f3fa01 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtDhPayListDTO.java @@ -0,0 +1,39 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.Data; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtBuyer; + + +/** + * @Description 分页查询 敦煌支付信息 + * @Date 2022-07-28 + * @Author rch + */ +@Data +public class CtDhPayListDTO extends PageDTO { + + /** 买家名称 */ + private String buyerName; + /** 支付订单ID(敦煌的) */ + private String orderId; + /** 状态 0.待处理 1.支付成功 2.支付失败 3.删除*/ + private Integer status; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .eq(ObjectUtil.isNotEmpty(status), "status", status) + .like(ObjectUtil.isNotEmpty(buyerName), "buyer_name", buyerName) + .like(ObjectUtil.isNotEmpty(orderId), "order_id", orderId) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + .orderByDesc("updated_at") + ; + + return qw; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtExcelAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtExcelAddDTO.java new file mode 100644 index 0000000..891b5f4 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtExcelAddDTO.java @@ -0,0 +1,27 @@ +package me.zhengjie.modules.group.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * Excel 导入信息(CtExcel)表实体类 DTO + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtExcelAddDTO{ + + /** 备注 */ + @NotNull + private String remarks; + + /** excel路径 */ + @NotNull + private String path; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtExcelImportInfoListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtExcelImportInfoListDTO.java new file mode 100644 index 0000000..582100c --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtExcelImportInfoListDTO.java @@ -0,0 +1,41 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.Data; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtBuyer; + + +/** + * @Description 分页查询 买家信息 + * @Date 2022-06-22 + * @Author rch + */ +@Data +public class CtExcelImportInfoListDTO extends PageDTO { + + /** 公司主键 */ + private Long companyId; + + /** 鉴权枚举 */ + private Integer tokenEnum; + + /** 状态 1.待处理 2.处理成功 3.处理失败 */ + private Integer status; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .eq(ObjectUtil.isNotEmpty(companyId), "company_id", companyId) + .eq(ObjectUtil.isNotEmpty(tokenEnum), "token_enum", tokenEnum) + .eq(ObjectUtil.isNotEmpty(status), "status", status) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + .orderByDesc("updated_at") + ; + + return qw; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtExcelListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtExcelListDTO.java new file mode 100644 index 0000000..e51b0f5 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtExcelListDTO.java @@ -0,0 +1,40 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtExcel; + +/** + * Excel 导入信息(CtExcel)表实体类 DTO + * + * @author rch + * @since 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtExcelListDTO extends PageDTO { + + /** 备注 */ + private String remarks; + + /** 状态1.待处理 2.已处理 */ + private Integer status; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .like(ObjectUtil.isNotEmpty(remarks), "remarks", remarks) + .eq(ObjectUtil.isNotEmpty(status), "status", status) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + .orderByDesc("updated_at") + ; + + return qw; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtExcelUpdateDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtExcelUpdateDTO.java new file mode 100644 index 0000000..0dbd06b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtExcelUpdateDTO.java @@ -0,0 +1,27 @@ +package me.zhengjie.modules.group.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + + +/** + * 修改 Excel + * + * @author rch + * @create 2022-06-22 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtExcelUpdateDTO { + + @NotNull + private Integer id; + + /** 备注 */ + private String remarks; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtOrderListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtOrderListDTO.java new file mode 100644 index 0000000..75ce756 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtOrderListDTO.java @@ -0,0 +1,42 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.Data; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtBuyer; + + +/** + * @Description 分页查询 订单信息 + * @Date 2022-07-01 + * @Author rch + */ +@Data +public class CtOrderListDTO extends PageDTO { + + /** 公司Id */ + private Long companyId; + /** ExcelId 信息 */ + private Long excelInfoId; + /** 我们平台订单编号 */ + private String ctOrderNo; + /** 订单号,下单成功响应的订单号(冗余字段 下单成功响应订单信息里有) */ + private Long orderNo; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .eq(ObjectUtil.isNotEmpty(companyId), "company_id", companyId) + .eq(ObjectUtil.isNotEmpty(excelInfoId), "excel_info_id", excelInfoId) + .eq(ObjectUtil.isNotEmpty(ctOrderNo), "ct_order_no", ctOrderNo) + .eq(ObjectUtil.isNotEmpty(orderNo), "order_no", orderNo) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + .orderByDesc("updated_at") + ; + + return qw; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtPlatformAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtPlatformAddDTO.java new file mode 100644 index 0000000..88a1c82 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtPlatformAddDTO.java @@ -0,0 +1,25 @@ +package me.zhengjie.modules.group.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 平台信息 DTO + * + * @author rch + * @create 2022-06-23 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtPlatformAddDTO { + + /** 名称 */ + private String name; + /** 地址 */ + private String address; + /** 电话 */ + private String phone; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtPlatformListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtPlatformListDTO.java new file mode 100644 index 0000000..a7d71a9 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtPlatformListDTO.java @@ -0,0 +1,39 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.Data; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtPlatform; + + +/** + * @Description 分页查询 平台信息 + * @Date 2022-06-23 + * @Author rch + */ +@Data +public class CtPlatformListDTO extends PageDTO { + + /** 名称 */ + private String name; + /** 地址 */ + private String address; + /** 电话 */ + private String phone; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .like(ObjectUtil.isNotEmpty(name), "name", name) + .like(ObjectUtil.isNotEmpty(address), "address", address) + .like(ObjectUtil.isNotEmpty(phone), "phone", phone) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + .orderByDesc("updated_at") + ; + + return qw; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtPlatformUpdateDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtPlatformUpdateDTO.java new file mode 100644 index 0000000..e04fcd9 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtPlatformUpdateDTO.java @@ -0,0 +1,31 @@ +package me.zhengjie.modules.group.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + + +/** + * 修改 平台信息 + * + * @author rch + * @create 2022-06-22 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtPlatformUpdateDTO { + + @NotNull + private Integer id; + + /** 名称 */ + private String name; + /** 地址 */ + private String address; + /** 电话 */ + private String phone; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtRebotAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtRebotAddDTO.java new file mode 100644 index 0000000..0e58d38 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtRebotAddDTO.java @@ -0,0 +1,26 @@ +package me.zhengjie.modules.group.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * 影刀机器人(ct_rebot) 新增DTO + * + * @Author zhw + * @Date 2022-07-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtRebotAddDTO { + + /** 机器人账号 */ + @NotNull + private String accountName; + /** 机器人Uuid信息 */ + @NotNull + private String robotClientUuid; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtRebotListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtRebotListDTO.java new file mode 100644 index 0000000..3393a56 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtRebotListDTO.java @@ -0,0 +1,42 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtRebot; + +/** + * 影刀机器人 分页查询DTO + * + * @Author zhw + * @Date 2022-07-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtRebotListDTO extends PageDTO { + + /** 机器人账号 */ + private String accountName; + /** 机器人Uuid信息 */ + private String robotClientUuid; + + public Wrapper getWrapper(){ + QueryWrapper qw = new QueryWrapper<>(); + qw + .like(ObjectUtil.isNotEmpty(accountName),"account_name",accountName) + .like(ObjectUtil.isNotEmpty(robotClientUuid),"robot_client_uuid",robotClientUuid) + .orderBy(ObjectUtil.isNotEmpty(getSort()),isAsc(),getSort()) + .orderByDesc("id") + ; + return qw; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtRebotUpdateDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtRebotUpdateDTO.java new file mode 100644 index 0000000..f5b9a4e --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtRebotUpdateDTO.java @@ -0,0 +1,33 @@ +package me.zhengjie.modules.group.dto; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * 根据ID修改影刀机器人(ct_rebot) 信息 + * + * @Author zhw + * @Date 2022-07-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtRebotUpdateDTO { + + @NotNull + private Long id; + + /** 机器人账号 */ + private String accountName; + /** 机器人Uuid信息 */ + private String robotClientUuid; + /** 任务id(任务id 不为0说明机器被占用) */ + private Integer jobId; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtRebotUpdateStatusDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtRebotUpdateStatusDTO.java new file mode 100644 index 0000000..fba3f4b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtRebotUpdateStatusDTO.java @@ -0,0 +1,24 @@ +package me.zhengjie.modules.group.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * 根据ID修改影刀机器人(ct_rebot) 状态测试使用 + * + * @Author zhw + * @Date 2022-07-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtRebotUpdateStatusDTO { + + @NotNull + private Long id; + + private Integer status; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtVpnAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtVpnAddDTO.java new file mode 100644 index 0000000..4c92a85 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtVpnAddDTO.java @@ -0,0 +1,50 @@ +package me.zhengjie.modules.group.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * @Author zhw + * @Date 2022-07-07 + * @Description Vpn新增DTO + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtVpnAddDTO { + /** 所属国家简称 */ + @NotNull + private String contntryShort; + /** IP地址 */ + @NotNull + private String ipAddress; + /** 父ip地址 */ + @NotNull + private String parentIpAddress; + /** 端口 */ + @NotNull + private Integer port; + /** 名称 */ + @NotNull + private String name; + /** 密码 */ + @NotNull + private String pwd; + /** VPS类型 1.传统 */ + @NotNull + private Integer vpsType; + /** 经销商 1.V2 */ + @NotNull + private Integer dealer; + /** mac地址 */ + @NotNull + public String mac; + /** 链接 */ + private String link; + /** 状态 1.可用 2.禁用 */ + public Integer status;; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtVpnListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtVpnListDTO.java new file mode 100644 index 0000000..06348ea --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtVpnListDTO.java @@ -0,0 +1,59 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.Data; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtVpn; + +/** + * @Description 分页查询 VPN信息 + * @Date 2022/7/7 + * @Author zhw + */ +@Data +public class CtVpnListDTO extends PageDTO { + + /** 所属国家简称 */ + private String contntryShort; + /** IP地址 */ + private String ipAddress; + /** 父ip地址 */ + private String parentIpAddress; + /** 端口 */ + private Integer port; + /** 名称 */ + private String name; + /** 密码 */ + private String pwd; + /** VPS类型 1.传统 */ + private Integer vpsType; + /** 经销商 1.V2 */ + private Integer dealer; + /** mac地址 */ + public String mac; + /** 状态 1.可用 2.禁用 */ + public Integer status; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .like(ObjectUtil.isNotEmpty(contntryShort), "contntry_short", contntryShort) + .like(ObjectUtil.isNotEmpty(ipAddress), "ip_address", ipAddress) + .like(ObjectUtil.isNotEmpty(parentIpAddress), "parent_ip_address", parentIpAddress) + .like(ObjectUtil.isNotEmpty(port), "port", port) + .like(ObjectUtil.isNotEmpty(name), "name", name) + .like(ObjectUtil.isNotEmpty(pwd), "pwd", pwd) + .like(ObjectUtil.isNotEmpty(vpsType), "vps_type", vpsType) + .like(ObjectUtil.isNotEmpty(dealer), "dealer", dealer) + .like(ObjectUtil.isNotEmpty(mac), "mac", mac) + .like(ObjectUtil.isNotEmpty(status), "status", status) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + .orderByDesc("updated_at") + ; + return qw; + } + + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtVpnUpdateDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtVpnUpdateDTO.java new file mode 100644 index 0000000..cfc9a4e --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/CtVpnUpdateDTO.java @@ -0,0 +1,43 @@ +package me.zhengjie.modules.group.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * @Author zhw + * @Date 2022-07-08 + * @Description VPN信息更新 dto + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CtVpnUpdateDTO { + @NotNull + private Integer id; + /** 所属国家简称 */ + private String contntryShort; + /** IP地址 */ + private String ipAddress; + /** 父ip地址 */ + private String parentIpAddress; + /** 端口 */ + private Integer port; + /** 名称 */ + private String name; + /** 密码 */ + private String pwd; + /** VPS类型 1.传统 */ + private Integer vpsType; + /** 经销商 1.V2 */ + private Integer dealer; + /** mac地址 */ + public String mac; + /** 链接 */ + private String link; + /** 经销商 1.可用 2.禁用 */ + public Integer status; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/DhCarGoodWellReceivedDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/DhCarGoodWellReceivedDTO.java new file mode 100644 index 0000000..0a7a804 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/DhCarGoodWellReceivedDTO.java @@ -0,0 +1,30 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * + * @Description IdDTO + * @Date 2022-06-22 + * @Author rch + */ +@Data +@ApiModel("敦煌加购好评商品细腻洗") +public class DhCarGoodWellReceivedDTO { + + @NotNull + @ApiModelProperty(value = "id", required = true) + private Long id; + + @NotNull + @ApiModelProperty(value = "评论内容", required = true) + private String comment; + + @NotNull + @ApiModelProperty(value = "图片路径", required = true) + private String paths; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/DhCarWellReceivedDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/DhCarWellReceivedDTO.java new file mode 100644 index 0000000..be59ac0 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/DhCarWellReceivedDTO.java @@ -0,0 +1,29 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * + * @Description IdDTO + * @Date 2022-06-22 + * @Author rch + */ +@Data +@ApiModel("敦煌加购好评") +public class DhCarWellReceivedDTO { + + @NotNull + @ApiModelProperty(value = "id", required = true) + private Long id; + + @Valid + @ApiModelProperty(value = "评论内容", required = true) + private List dialogWellReceivedGoods; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/IdDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/IdDTO.java new file mode 100644 index 0000000..8304628 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/IdDTO.java @@ -0,0 +1,22 @@ +package me.zhengjie.modules.group.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * + * @Description IdDTO + * @Date 2022-06-22 + * @Author rch + */ +@Data +@ApiModel("IdDto") +public class IdDTO { + + @NotNull + @ApiModelProperty(value = "id", required = true) + private Long id; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SearchOrderListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SearchOrderListDTO.java new file mode 100644 index 0000000..fab304d --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SearchOrderListDTO.java @@ -0,0 +1,69 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtClickOrder; + + +/** + * @Description 分页查询 开放刷单订单接口给到ERP + * @Date 2022-11-10 + * @Author rch + */ +@Data +@ApiModel("分页查询刷单订单") +public class SearchOrderListDTO extends PageDTO { + + /** 店铺 */ + @ApiModelProperty(value = "店铺") + private String shop; + + /** 订单id */ + @ApiModelProperty(value = "订单id") + private String orderId; + + /** 公司id */ + @ApiModelProperty(value = "公司id") + private Long companyId; + + /** 类型 */ + @ApiModelProperty(value = "类型") + private Integer type; + + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + @ApiModelProperty(value = "状态 1.待执行 2.执行中 3.执行成功 4.执行失败", allowableValues = "1,2,3,4") + private Integer status; + + /** 开始时间 */ + @ApiModelProperty(value = "开始时间") + private String sTime; + + /** 结束时间 */ + @ApiModelProperty(value = "结束时间") + private String eTime; + + @ApiModelProperty(value = "是否评论") + private Boolean commentBoolean; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .eq(ObjectUtil.isNotEmpty(companyId), "company.id", companyId) + .eq(ObjectUtil.isNotEmpty(status), "clickOrder.status", status) + .eq(ObjectUtil.isNotEmpty(type), "clickOrder.type", type) + .isNotNull((ObjectUtil.isNotEmpty(commentBoolean) && commentBoolean), "comment") + .like(ObjectUtil.isNotEmpty(shop), "clickOrder.shop", shop) + .like(ObjectUtil.isNotEmpty(orderId), "clickOrder.order_id", orderId) + .between(ObjectUtil.isNotEmpty(sTime) && ObjectUtil.isNotEmpty(eTime), "clickOrder.created_at", sTime, eTime) + .orderByDesc("created_at") + ; + + return qw; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SysQuartzJobAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SysQuartzJobAddDTO.java new file mode 100644 index 0000000..4c86419 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SysQuartzJobAddDTO.java @@ -0,0 +1,54 @@ +package me.zhengjie.modules.group.dto; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * @Description 影刀定时任务新增 DTO + * @Date 2022-07-21 + * @Author zhw + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SysQuartzJobAddDTO { + + private Long taskNum; + /** 任务名称 */ + @NotNull + private String jobName; + /** 备注 */ + @NotNull + private String description; + /** 应用id:根据应用查找bean名称和方法名称 */ + @NotNull + private Long applyId; + /** cron 表达式 */ + @NotNull + private String cronExpression; + /** 子任务ID */ + private String subTask; + /** 负责人 */ + @NotNull + private String personInCharge; + /** 报警邮箱 */ + private String email; + /** 失败后暂停:1暂停、0启用 */ + @NotNull + private Integer pauseAfterFailure; + /** 状态:1暂停、0启用 */ + @NotNull + private Integer isPause; + /** 参数 */ + @NotNull + private String params; + /** 参数类型 */ + @NotNull + private Integer paramsType; + + private String paramId; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SysQuartzJobListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SysQuartzJobListDTO.java new file mode 100644 index 0000000..fcb02fe --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SysQuartzJobListDTO.java @@ -0,0 +1,43 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.Data; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.SysQuartzJob; +import me.zhengjie.enums.TaskTypeEnum; + +/** + * @Description 分页查询 影刀定时任务 + * @Date 2022-07-21 + * @Author zhw + */ +@Data +public class SysQuartzJobListDTO extends PageDTO { + + /** 任务名称 */ + private String jobName; + + /** 是否暂停 */ + private Integer isPause; + + /** 开始时间 */ + private String sTime; + + /** 结束时间 */ + private String eTime; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper<>(); + qw + .eq("type", TaskTypeEnum.SHADOW_KNIFE.value()) + .like(ObjectUtil.isNotEmpty(jobName), "job_name", jobName) + .eq(ObjectUtil.isNotEmpty(isPause), "is_pause", isPause) + .between(ObjectUtil.isNotEmpty(sTime) && ObjectUtil.isNotNull(eTime), "create_time", sTime, eTime) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + ; + return qw; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SysQuartzJobUpdateDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SysQuartzJobUpdateDTO.java new file mode 100644 index 0000000..2c40feb --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SysQuartzJobUpdateDTO.java @@ -0,0 +1,49 @@ +package me.zhengjie.modules.group.dto; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + + +/** + * @Author zhw + * @Date 2022-07-21 + * @Description 影刀信息更新 dto + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SysQuartzJobUpdateDTO { + + @NotNull + private Long jobId; + /** 任务名称 */ + private String jobName; + /** 备注 */ + private String description; + /** Spring Bean名称 */ + private String beanName; + /** 方法名称 */ + private String methodName; + /** 应用ID 通过ID查找Bean名称、方法名称 */ + private Long applyId; + /** cron 表达式 */ + private String cronExpression; + /** 子任务ID */ + private String subTask; + /** 负责人 */ + private String personInCharge; + /** 报警邮箱 */ + private String email; + /** 失败后暂停:1暂停、0启用 */ + private Integer pauseAfterFailure; + /** 状态:1暂停、0启用 */ + private Integer isPause; + /** 参数 */ + private String params; + /** 参数类型 */ + private Integer paramsType; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SysQuartzLogListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SysQuartzLogListDTO.java new file mode 100644 index 0000000..7bb972d --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/SysQuartzLogListDTO.java @@ -0,0 +1,42 @@ +package me.zhengjie.modules.group.dto; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.Data; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.SysQuartzLog; +import me.zhengjie.enums.TaskTypeEnum; + + +/** + * @Description 分页查询 影刀定时任务日志 + * @Date 2022-07-9 + * @Author rch + */ +@Data +public class SysQuartzLogListDTO extends PageDTO { + + /** 卡号 */ + private String jobName; + + private Integer isSuccess; + + private String sTime; + + private String eTime; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .eq("type", TaskTypeEnum.SHADOW_KNIFE.value()) + .eq(ObjectUtil.isNotEmpty(isSuccess), "is_success", isSuccess) + .like(ObjectUtil.isNotEmpty(jobName), "job_name", jobName) + .between(ObjectUtil.isNotEmpty(sTime) && ObjectUtil.isNotEmpty(eTime), "create_time", sTime, eTime) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + ; + + return qw; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhaddcar/DhAddCarAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhaddcar/DhAddCarAddDTO.java new file mode 100644 index 0000000..098ca04 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhaddcar/DhAddCarAddDTO.java @@ -0,0 +1,46 @@ +package me.zhengjie.modules.group.dto.dhaddcar; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.modules.group.dto.dhcargood.DhCarGoodKeyAddDTO; +import me.zhengjie.modules.group.dto.dhcargood.DhCarGoodKeyEditDTO; +import me.zhengjie.modules.group.dto.dhcargood.DhCarGoodLinkAddDTO; +import me.zhengjie.modules.group.dto.dhcargood.DhCarGoodLinkEditDTO; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 新增敦煌加购 DTO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("新增敦煌加购") +public class DhAddCarAddDTO { + + /** 商品属性类型:1.关键词 2.链接 */ + @NotNull + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接", required = true, allowableValues = "1,2") + private Integer paramsType; + + /** 买家ID */ + @NotNull + @ApiModelProperty(value = "买家ID", required = true) + private Integer buyerId; + + /** 加购物车商品ids */ + @ApiModelProperty(value = "加购物车商品ids") + private List carGoodKeys; + + /** 加购物车商品ids */ + @ApiModelProperty(value = "加购物车商品ids") + private List carGoodLinks; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhaddcar/DhAddCarEditDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhaddcar/DhAddCarEditDTO.java new file mode 100644 index 0000000..b26d485 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhaddcar/DhAddCarEditDTO.java @@ -0,0 +1,48 @@ +package me.zhengjie.modules.group.dto.dhaddcar; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.modules.group.dto.dhcargood.DhCarGoodKeyEditDTO; +import me.zhengjie.modules.group.dto.dhcargood.DhCarGoodLinkEditDTO; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 修改敦煌加购信息 DTO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("修改敦煌加购信息") +public class DhAddCarEditDTO { + + /** ID */ + @ApiModelProperty(value = "ID", required = true) + private Long id; + + /** 商品属性类型:1.关键词 2.链接 */ + @NotNull + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接", required = true, allowableValues = "1,2") + private Integer paramsType; + + /** 买家ID */ + @NotNull + @ApiModelProperty(value = "买家ID", required = true) + private Integer buyerId; + + /** 加购物车商品ids */ + @ApiModelProperty(value = "加购物车商品ids") + private List carGoodKeys; + + /** 加购物车商品ids */ + @ApiModelProperty(value = "加购物车商品ids") + private List carGoodLinks; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhaddcar/DhAddCarListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhaddcar/DhAddCarListDTO.java new file mode 100644 index 0000000..e6a63c1 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhaddcar/DhAddCarListDTO.java @@ -0,0 +1,73 @@ +package me.zhengjie.modules.group.dto.dhaddcar; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtBuyer; +import me.zhengjie.enums.DhAddCarStatusEnum; + +import java.util.Arrays; + +/** + * 分页查询-敦煌加购-信息 DTO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("新增刷单信息") +public class DhAddCarListDTO extends PageDTO { + + /** 商品属性类型:1.关键词 2.链接 */ + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接", allowableValues = "1,2") + private Integer paramsType; + + /** 账号 */ + @ApiModelProperty(value = "账号") + private String account; + + /** 账号 */ + @ApiModelProperty(value = "国家") + private String country; + + /** 账号 */ + @ApiModelProperty(value = "1.获取敦煌加购列表(状态:1.待执行 4.加购失败); 2.获取敦煌抓单列表(状态:6.待抓单 9.抓单失败)") + private Integer inStatusList; + + /** 状态 1.待执行 2.执行中 3.加购成功 4.加购失败 5.下单成功 6.支付成功 7.抓单成功 8.抓单失败 */ + @ApiModelProperty(value = "状态 1.待执行 2.执行中 3.加购成功 4.加购失败 5.下单成功 6.支付成功 7.抓单成功 8.抓单失败", allowableValues = "1,2,3,4,5,6,7,8") + private Integer status; + +// /** 加购物车商品ids */ +// @ApiModelProperty(value = "加购物车商品ids") +// private List carGoodKeys; +// +// /** 加购物车商品ids */ +// @ApiModelProperty(value = "加购物车商品ids") +// private List carGoodLinks; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .eq(ObjectUtil.isNotEmpty(paramsType), "dhAddCar.params_type", paramsType) + .eq(ObjectUtil.isNotEmpty(account), "buyer.account", account) + .in(ObjectUtil.isNotEmpty(inStatusList) && inStatusList == 1, "dhAddCar.status", Arrays.asList(DhAddCarStatusEnum.TOBE_EXECUTION.value(), DhAddCarStatusEnum.ADD_CARD_FAILE.value())) + .in(ObjectUtil.isNotEmpty(inStatusList) && inStatusList == 2, "dhAddCar.status", Arrays.asList(DhAddCarStatusEnum.TO_BE_CATCH_ORDER.value(), DhAddCarStatusEnum.CATCH_ORDER_FAILE.value())) + .eq(ObjectUtil.isNotEmpty(status), "dhAddCar.status", status) + .eq(ObjectUtil.isNotEmpty(country), "company.name", country) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + .orderByDesc("updated_at") + ; + + return qw; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcargood/DhCarGoodKeyAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcargood/DhCarGoodKeyAddDTO.java new file mode 100644 index 0000000..a4d8fb9 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcargood/DhCarGoodKeyAddDTO.java @@ -0,0 +1,70 @@ +package me.zhengjie.modules.group.dto.dhcargood; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Null; + +/** + * 敦煌-加购商品(根据关键词) DTO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("敦煌-加购商品(根据关键词)") +public class DhCarGoodKeyAddDTO { + + /** 商品属性类型:1.关键词 2.链接 */ + @Null + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接", required = true, allowableValues = "1,2") + private Integer paramsType; + + /** 店铺名称 */ + @NotBlank + @ApiModelProperty(value = "NotBlank", required = true) + private String shopName; + + /** 关键词 */ + @NotBlank + @ApiModelProperty(value = "关键词", required = true) + private String keyWord; + + /** 标题 */ + @NotBlank + @ApiModelProperty(value = "标题", required = true) + private String title; + + /** 数量 */ + @NotBlank + @ApiModelProperty(value = "数量", required = true) + private Integer number; + + /** 规格 */ + @ApiModelProperty(value = "规格") + private String specification; + + /** 颜色 */ + @ApiModelProperty(value = "颜色") + private String color; + + /** item */ + @NotBlank + @ApiModelProperty(value = "item", required = true) + private String item; + + /** 最小价格区间 */ + @ApiModelProperty(value = "最小价格区间") + private String sectionMin; + + /** 最大价格区间 */ + @ApiModelProperty(value = "最大价格区间") + private String sectionMax; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcargood/DhCarGoodKeyEditDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcargood/DhCarGoodKeyEditDTO.java new file mode 100644 index 0000000..3bdadc0 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcargood/DhCarGoodKeyEditDTO.java @@ -0,0 +1,74 @@ +package me.zhengjie.modules.group.dto.dhcargood; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Null; + +/** + * 敦煌-加购商品(根据关键词) DTO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("敦煌-加购商品(根据关键词)") +public class DhCarGoodKeyEditDTO { + + /** ID */ + @ApiModelProperty(value = "ID", required = true) + private Long id; + + /** 商品属性类型:1.关键词 2.链接 */ + @Null + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接", required = true, allowableValues = "1,2") + private Integer paramsType; + + /** 店铺名称 */ + @NotBlank + @ApiModelProperty(value = "NotBlank", required = true) + private String shopName; + + /** 关键词 */ + @NotBlank + @ApiModelProperty(value = "关键词", required = true) + private String keyWord; + + /** 标题 */ + @NotBlank + @ApiModelProperty(value = "标题", required = true) + private String title; + + /** 数量 */ + @NotBlank + @ApiModelProperty(value = "数量", required = true) + private Integer number; + + /** 规格 */ + @ApiModelProperty(value = "规格") + private String specification; + + /** 颜色 */ + @ApiModelProperty(value = "颜色") + private String color; + + /** item */ + @NotBlank + @ApiModelProperty(value = "item", required = true) + private String item; + + /** 最小价格区间 */ + @ApiModelProperty(value = "最小价格区间") + private String sectionMin; + + /** 最大价格区间 */ + @ApiModelProperty(value = "最大价格区间") + private String sectionMax; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcargood/DhCarGoodLinkAddDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcargood/DhCarGoodLinkAddDTO.java new file mode 100644 index 0000000..5911106 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcargood/DhCarGoodLinkAddDTO.java @@ -0,0 +1,49 @@ +package me.zhengjie.modules.group.dto.dhcargood; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Null; + +/** + * 敦煌-加购商品(根据链接) DTO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("敦煌-加购商品(根据链接)") +public class DhCarGoodLinkAddDTO { + + /** 商品属性类型:1.关键词 2.链接 */ + @Null + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接", required = true, allowableValues = "1,2") + private Integer paramsType; + + /** 链接 */ + @NotBlank + @ApiModelProperty(value = "链接", required = true) + private String link; + + /** 数量 */ + @NotBlank + @ApiModelProperty(value = "数量", required = true) + private Integer number; + + /** 规格 */ + @NotBlank + @ApiModelProperty(value = "规格", required = true) + private String specification; + + /** 颜色 */ + @NotBlank + @ApiModelProperty(value = "颜色", required = true) + private String color; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcargood/DhCarGoodLinkEditDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcargood/DhCarGoodLinkEditDTO.java new file mode 100644 index 0000000..e9c4a4a --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcargood/DhCarGoodLinkEditDTO.java @@ -0,0 +1,53 @@ +package me.zhengjie.modules.group.dto.dhcargood; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Null; + +/** + * 敦煌-加购商品(根据链接) DTO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("敦煌-加购商品(根据链接)") +public class DhCarGoodLinkEditDTO { + + /** ID */ + @ApiModelProperty(value = "ID", required = true) + private Long id; + + /** 商品属性类型:1.关键词 2.链接 */ + @Null + @ApiModelProperty(value = "商品属性类型:1.关键词 2.链接", required = true, allowableValues = "1,2") + private Integer paramsType; + + /** 链接 */ + @NotBlank + @ApiModelProperty(value = "链接", required = true) + private String link; + + /** 数量 */ + @NotBlank + @ApiModelProperty(value = "数量", required = true) + private Integer number; + + /** 规格 */ + @NotBlank + @ApiModelProperty(value = "规格", required = true) + private String specification; + + /** 颜色 */ + @NotBlank + @ApiModelProperty(value = "颜色", required = true) + private String color; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcarorder/DhAddCarOrderListDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcarorder/DhAddCarOrderListDTO.java new file mode 100644 index 0000000..e3ad0f3 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/group/dto/dhcarorder/DhAddCarOrderListDTO.java @@ -0,0 +1,66 @@ +package me.zhengjie.modules.group.dto.dhcarorder; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.dto.PageDTO; +import me.zhengjie.entity.CtBuyer; +import me.zhengjie.enums.ClickOrderStatusEnum; +import me.zhengjie.enums.DhAddCarStatusEnum; + +import java.util.Arrays; + +/** + * 分页查询-敦煌加购-订单-信息 DTO + * + * @author rch + * @create 2022-07-09 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel("敦煌加购订单信息") +public class DhAddCarOrderListDTO extends PageDTO { + + /** 类型: 1.导入 2.刷单 */ + @ApiModelProperty(value = "类型: 1.导入 2.刷单", allowableValues = "1,2") + private Integer type; + + /** 关联敦煌加购的id */ + @ApiModelProperty(value = "关联敦煌加购的id") + private Long addCarId; + + /** 订单id */ + @ApiModelProperty(value = "订单id") + private String orderId; + + /** 好评 */ + @ApiModelProperty(value = "1.获取敦煌好评列表(状态:1.待执行 4.加购失败)") + private Integer inStatusList; + + + /** 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 */ + @ApiModelProperty(value = "状态 1.待执行 2.执行中 3.执行成功 4.执行失败", allowableValues = "1,2,3,4") + private Integer status; + + public Wrapper getWrapper() { + QueryWrapper qw = new QueryWrapper(); + qw + .eq(ObjectUtil.isNotEmpty(type), "type", type) + .eq(ObjectUtil.isNotEmpty(addCarId), "add_car_id", addCarId) + .eq(ObjectUtil.isNotEmpty(orderId), "order_id", orderId) + .eq(ObjectUtil.isNotEmpty(status), "status", status) + .in(ObjectUtil.isNotEmpty(inStatusList) && inStatusList == 1, "status", Arrays.asList(ClickOrderStatusEnum.TOBE_EXECUTION.value(), ClickOrderStatusEnum.EXECUTION_FAILE.value())) + .orderBy(ObjectUtil.isNotEmpty(getSort()), isAsc(), getSort()) + .orderByDesc("updated_at") + ; + + return qw; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/App.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/App.java new file mode 100644 index 0000000..cf5789c --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/App.java @@ -0,0 +1,67 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.domain; + +import io.swagger.annotations.ApiModelProperty; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseEntity; +import javax.persistence.*; +import java.io.Serializable; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Entity +@Getter +@Setter +@Table(name="mnt_app") +public class App extends BaseEntity implements Serializable { + + @Id + @Column(name = "app_id") + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ApiModelProperty(value = "名称") + private String name; + + @ApiModelProperty(value = "端口") + private int port; + + @ApiModelProperty(value = "上传路径") + private String uploadPath; + + @ApiModelProperty(value = "部署路径") + private String deployPath; + + @ApiModelProperty(value = "备份路径") + private String backupPath; + + @ApiModelProperty(value = "启动脚本") + private String startScript; + + @ApiModelProperty(value = "部署脚本") + private String deployScript; + + public void copy(App source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/Database.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/Database.java new file mode 100644 index 0000000..6b3a68a --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/Database.java @@ -0,0 +1,57 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.domain; + +import io.swagger.annotations.ApiModelProperty; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseEntity; +import javax.persistence.*; +import java.io.Serializable; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Entity +@Getter +@Setter +@Table(name="mnt_database") +public class Database extends BaseEntity implements Serializable { + + @Id + @Column(name = "db_id") + @ApiModelProperty(value = "ID", hidden = true) + private String id; + + @ApiModelProperty(value = "数据库名称") + private String name; + + @ApiModelProperty(value = "数据库连接地址") + private String jdbcUrl; + + @ApiModelProperty(value = "数据库密码") + private String pwd; + + @ApiModelProperty(value = "用户名") + private String userName; + + public void copy(Database source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/Deploy.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/Deploy.java new file mode 100644 index 0000000..bcf61e5 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/Deploy.java @@ -0,0 +1,59 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.domain; + +import io.swagger.annotations.ApiModelProperty; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseEntity; +import javax.persistence.*; +import java.io.Serializable; +import java.util.Set; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Entity +@Getter +@Setter +@Table(name="mnt_deploy") +public class Deploy extends BaseEntity implements Serializable { + + @Id + @Column(name = "deploy_id") + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToMany + @ApiModelProperty(name = "服务器", hidden = true) + @JoinTable(name = "mnt_deploy_server", + joinColumns = {@JoinColumn(name = "deploy_id",referencedColumnName = "deploy_id")}, + inverseJoinColumns = {@JoinColumn(name = "server_id",referencedColumnName = "server_id")}) + private Set deploys; + + @ManyToOne + @JoinColumn(name = "app_id") + @ApiModelProperty(value = "应用编号") + private App app; + + public void copy(Deploy source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/DeployHistory.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/DeployHistory.java new file mode 100644 index 0000000..6e07e13 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/DeployHistory.java @@ -0,0 +1,62 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.domain; + +import io.swagger.annotations.ApiModelProperty; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.annotations.CreationTimestamp; +import javax.persistence.*; +import java.io.Serializable; +import java.sql.Timestamp; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Entity +@Getter +@Setter +@Table(name="mnt_deploy_history") +public class DeployHistory implements Serializable { + + @Id + @Column(name = "history_id") + @ApiModelProperty(value = "ID", hidden = true) + private String id; + + @ApiModelProperty(value = "应用名称") + private String appName; + + @ApiModelProperty(value = "IP") + private String ip; + + @CreationTimestamp + @ApiModelProperty(value = "部署时间") + private Timestamp deployDate; + + @ApiModelProperty(value = "部署者") + private String deployUser; + + @ApiModelProperty(value = "部署ID") + private Long deployId; + + public void copy(DeployHistory source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/ServerDeploy.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/ServerDeploy.java new file mode 100644 index 0000000..f523562 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/domain/ServerDeploy.java @@ -0,0 +1,80 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.domain; + +import io.swagger.annotations.ApiModelProperty; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseEntity; +import javax.persistence.*; +import java.io.Serializable; +import java.util.Objects; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Entity +@Getter +@Setter +@Table(name="mnt_server") +public class ServerDeploy extends BaseEntity implements Serializable { + + @Id + @Column(name = "server_id") + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ApiModelProperty(value = "服务器名称") + private String name; + + @ApiModelProperty(value = "IP") + private String ip; + + @ApiModelProperty(value = "端口") + private Integer port; + + @ApiModelProperty(value = "账号") + private String account; + + @ApiModelProperty(value = "密码") + private String password; + + public void copy(ServerDeploy source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ServerDeploy that = (ServerDeploy) o; + return Objects.equals(id, that.id) && + Objects.equals(name, that.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/AppRepository.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/AppRepository.java new file mode 100644 index 0000000..41e5f5c --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/AppRepository.java @@ -0,0 +1,27 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.repository; + +import me.zhengjie.modules.mnt.domain.App; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface AppRepository extends JpaRepository, JpaSpecificationExecutor { +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/DatabaseRepository.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/DatabaseRepository.java new file mode 100644 index 0000000..695e0ad --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/DatabaseRepository.java @@ -0,0 +1,27 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.repository; + +import me.zhengjie.modules.mnt.domain.Database; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface DatabaseRepository extends JpaRepository, JpaSpecificationExecutor { +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/DeployHistoryRepository.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/DeployHistoryRepository.java new file mode 100644 index 0000000..3c8980e --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/DeployHistoryRepository.java @@ -0,0 +1,27 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.repository; + +import me.zhengjie.modules.mnt.domain.DeployHistory; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface DeployHistoryRepository extends JpaRepository, JpaSpecificationExecutor { +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/DeployRepository.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/DeployRepository.java new file mode 100644 index 0000000..2ea4498 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/DeployRepository.java @@ -0,0 +1,27 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.repository; + +import me.zhengjie.modules.mnt.domain.Deploy; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface DeployRepository extends JpaRepository, JpaSpecificationExecutor { +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/ServerDeployRepository.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/ServerDeployRepository.java new file mode 100644 index 0000000..4ca336c --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/repository/ServerDeployRepository.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.repository; + +import me.zhengjie.modules.mnt.domain.ServerDeploy; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface ServerDeployRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据IP查询 + * @param ip / + * @return / + */ + ServerDeploy findByIp(String ip); +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/AppController.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/AppController.java new file mode 100644 index 0000000..9b5b08f --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/AppController.java @@ -0,0 +1,87 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.modules.mnt.domain.App; +import me.zhengjie.modules.mnt.service.AppService; +import me.zhengjie.modules.mnt.service.dto.AppQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "运维:应用管理") +@RequestMapping("/api/app") +public class AppController { + + private final AppService appService; + + @ApiOperation("导出应用数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('app:list')") + public void download(HttpServletResponse response, AppQueryCriteria criteria) throws IOException { + appService.download(appService.queryAll(criteria), response); + } + + @ApiOperation(value = "查询应用") + @GetMapping + @PreAuthorize("@el.check('app:list')") + public ResponseEntity query(AppQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(appService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @Log("新增应用") + @ApiOperation(value = "新增应用") + @PostMapping + @PreAuthorize("@el.check('app:add')") + public ResponseEntity create(@Validated @RequestBody App resources){ + appService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改应用") + @ApiOperation(value = "修改应用") + @PutMapping + @PreAuthorize("@el.check('app:edit')") + public ResponseEntity update(@Validated @RequestBody App resources){ + appService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除应用") + @ApiOperation(value = "删除应用") + @DeleteMapping + @PreAuthorize("@el.check('app:del')") + public ResponseEntity delete(@RequestBody Set ids){ + appService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/DatabaseController.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/DatabaseController.java new file mode 100644 index 0000000..9dfb43c --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/DatabaseController.java @@ -0,0 +1,123 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.mnt.domain.Database; +import me.zhengjie.modules.mnt.service.DatabaseService; +import me.zhengjie.modules.mnt.service.dto.DatabaseDto; +import me.zhengjie.modules.mnt.service.dto.DatabaseQueryCriteria; +import me.zhengjie.modules.mnt.util.SqlUtils; +import me.zhengjie.utils.FileUtil; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.util.Set; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Api(tags = "运维:数据库管理") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/database") +public class DatabaseController { + + private final String fileSavePath = FileUtil.getTmpDirPath()+"/"; + private final DatabaseService databaseService; + + @ApiOperation("导出数据库数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('database:list')") + public void download(HttpServletResponse response, DatabaseQueryCriteria criteria) throws IOException { + databaseService.download(databaseService.queryAll(criteria), response); + } + + @ApiOperation(value = "查询数据库") + @GetMapping + @PreAuthorize("@el.check('database:list')") + public ResponseEntity query(DatabaseQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(databaseService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @Log("新增数据库") + @ApiOperation(value = "新增数据库") + @PostMapping + @PreAuthorize("@el.check('database:add')") + public ResponseEntity create(@Validated @RequestBody Database resources){ + databaseService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改数据库") + @ApiOperation(value = "修改数据库") + @PutMapping + @PreAuthorize("@el.check('database:edit')") + public ResponseEntity update(@Validated @RequestBody Database resources){ + databaseService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除数据库") + @ApiOperation(value = "删除数据库") + @DeleteMapping + @PreAuthorize("@el.check('database:del')") + public ResponseEntity delete(@RequestBody Set ids){ + databaseService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + @Log("测试数据库链接") + @ApiOperation(value = "测试数据库链接") + @PostMapping("/testConnect") + @PreAuthorize("@el.check('database:testConnect')") + public ResponseEntity testConnect(@Validated @RequestBody Database resources){ + return new ResponseEntity<>(databaseService.testConnection(resources),HttpStatus.CREATED); + } + + @Log("执行SQL脚本") + @ApiOperation(value = "执行SQL脚本") + @PostMapping(value = "/upload") + @PreAuthorize("@el.check('database:add')") + public ResponseEntity upload(@RequestBody MultipartFile file, HttpServletRequest request)throws Exception{ + String id = request.getParameter("id"); + DatabaseDto database = databaseService.findById(id); + String fileName; + if(database != null){ + fileName = file.getOriginalFilename(); + File executeFile = new File(fileSavePath+fileName); + FileUtil.del(executeFile); + file.transferTo(executeFile); + String result = SqlUtils.executeFile(database.getJdbcUrl(), database.getUserName(), database.getPwd(), executeFile); + return new ResponseEntity<>(result,HttpStatus.OK); + }else{ + throw new BadRequestException("Database not exist"); + } + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/DeployController.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/DeployController.java new file mode 100644 index 0000000..72b7b3e --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/DeployController.java @@ -0,0 +1,153 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.modules.mnt.domain.Deploy; +import me.zhengjie.modules.mnt.domain.DeployHistory; +import me.zhengjie.modules.mnt.service.DeployService; +import me.zhengjie.modules.mnt.service.dto.DeployQueryCriteria; +import me.zhengjie.utils.FileUtil; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@RestController +@Api(tags = "运维:部署管理") +@RequiredArgsConstructor +@RequestMapping("/api/deploy") +public class DeployController { + + private final String fileSavePath = FileUtil.getTmpDirPath()+"/"; + private final DeployService deployService; + + + @ApiOperation("导出部署数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('database:list')") + public void download(HttpServletResponse response, DeployQueryCriteria criteria) throws IOException { + deployService.download(deployService.queryAll(criteria), response); + } + + @ApiOperation(value = "查询部署") + @GetMapping + @PreAuthorize("@el.check('deploy:list')") + public ResponseEntity query(DeployQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(deployService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @Log("新增部署") + @ApiOperation(value = "新增部署") + @PostMapping + @PreAuthorize("@el.check('deploy:add')") + public ResponseEntity create(@Validated @RequestBody Deploy resources){ + deployService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改部署") + @ApiOperation(value = "修改部署") + @PutMapping + @PreAuthorize("@el.check('deploy:edit')") + public ResponseEntity update(@Validated @RequestBody Deploy resources){ + deployService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除部署") + @ApiOperation(value = "删除部署") + @DeleteMapping + @PreAuthorize("@el.check('deploy:del')") + public ResponseEntity delete(@RequestBody Set ids){ + deployService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + @Log("上传文件部署") + @ApiOperation(value = "上传文件部署") + @PostMapping(value = "/upload") + @PreAuthorize("@el.check('deploy:edit')") + public ResponseEntity upload(@RequestBody MultipartFile file, HttpServletRequest request)throws Exception{ + Long id = Long.valueOf(request.getParameter("id")); + String fileName = ""; + if(file != null){ + fileName = file.getOriginalFilename(); + File deployFile = new File(fileSavePath+fileName); + FileUtil.del(deployFile); + file.transferTo(deployFile); + //文件下一步要根据文件名字来 + deployService.deploy(fileSavePath+fileName ,id); + }else{ + System.out.println("没有找到相对应的文件"); + } + System.out.println("文件上传的原名称为:"+ Objects.requireNonNull(file).getOriginalFilename()); + Map map = new HashMap<>(2); + map.put("errno",0); + map.put("id",fileName); + return new ResponseEntity<>(map,HttpStatus.OK); + } + @Log("系统还原") + @ApiOperation(value = "系统还原") + @PostMapping(value = "/serverReduction") + @PreAuthorize("@el.check('deploy:edit')") + public ResponseEntity serverReduction(@Validated @RequestBody DeployHistory resources){ + String result = deployService.serverReduction(resources); + return new ResponseEntity<>(result,HttpStatus.OK); + } + @Log("服务运行状态") + @ApiOperation(value = "服务运行状态") + @PostMapping(value = "/serverStatus") + @PreAuthorize("@el.check('deploy:edit')") + public ResponseEntity serverStatus(@Validated @RequestBody Deploy resources){ + String result = deployService.serverStatus(resources); + return new ResponseEntity<>(result,HttpStatus.OK); + } + @Log("启动服务") + @ApiOperation(value = "启动服务") + @PostMapping(value = "/startServer") + @PreAuthorize("@el.check('deploy:edit')") + public ResponseEntity startServer(@Validated @RequestBody Deploy resources){ + String result = deployService.startServer(resources); + return new ResponseEntity<>(result,HttpStatus.OK); + } + @Log("停止服务") + @ApiOperation(value = "停止服务") + @PostMapping(value = "/stopServer") + @PreAuthorize("@el.check('deploy:edit')") + public ResponseEntity stopServer(@Validated @RequestBody Deploy resources){ + String result = deployService.stopServer(resources); + return new ResponseEntity<>(result,HttpStatus.OK); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/DeployHistoryController.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/DeployHistoryController.java new file mode 100644 index 0000000..49fb694 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/DeployHistoryController.java @@ -0,0 +1,67 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.modules.mnt.service.DeployHistoryService; +import me.zhengjie.modules.mnt.service.dto.DeployHistoryQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "运维:部署历史管理") +@RequestMapping("/api/deployHistory") +public class DeployHistoryController { + + private final DeployHistoryService deployhistoryService; + + @ApiOperation("导出部署历史数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('deployHistory:list')") + public void download(HttpServletResponse response, DeployHistoryQueryCriteria criteria) throws IOException { + deployhistoryService.download(deployhistoryService.queryAll(criteria), response); + } + + @ApiOperation(value = "查询部署历史") + @GetMapping + @PreAuthorize("@el.check('deployHistory:list')") + public ResponseEntity query(DeployHistoryQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(deployhistoryService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @Log("删除DeployHistory") + @ApiOperation(value = "删除部署历史") + @DeleteMapping + @PreAuthorize("@el.check('deployHistory:del')") + public ResponseEntity delete(@RequestBody Set ids){ + deployhistoryService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/ServerDeployController.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/ServerDeployController.java new file mode 100644 index 0000000..d4a135b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/rest/ServerDeployController.java @@ -0,0 +1,95 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.modules.mnt.domain.ServerDeploy; +import me.zhengjie.modules.mnt.service.ServerDeployService; +import me.zhengjie.modules.mnt.service.dto.ServerDeployQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@RestController +@Api(tags = "运维:服务器管理") +@RequiredArgsConstructor +@RequestMapping("/api/serverDeploy") +public class ServerDeployController { + + private final ServerDeployService serverDeployService; + + @ApiOperation("导出服务器数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('serverDeploy:list')") + public void download(HttpServletResponse response, ServerDeployQueryCriteria criteria) throws IOException { + serverDeployService.download(serverDeployService.queryAll(criteria), response); + } + + @ApiOperation(value = "查询服务器") + @GetMapping + @PreAuthorize("@el.check('serverDeploy:list')") + public ResponseEntity query(ServerDeployQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(serverDeployService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @Log("新增服务器") + @ApiOperation(value = "新增服务器") + @PostMapping + @PreAuthorize("@el.check('serverDeploy:add')") + public ResponseEntity create(@Validated @RequestBody ServerDeploy resources){ + serverDeployService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改服务器") + @ApiOperation(value = "修改服务器") + @PutMapping + @PreAuthorize("@el.check('serverDeploy:edit')") + public ResponseEntity update(@Validated @RequestBody ServerDeploy resources){ + serverDeployService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除服务器") + @ApiOperation(value = "删除Server") + @DeleteMapping + @PreAuthorize("@el.check('serverDeploy:del')") + public ResponseEntity delete(@RequestBody Set ids){ + serverDeployService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + @Log("测试连接服务器") + @ApiOperation(value = "测试连接服务器") + @PostMapping("/testConnect") + @PreAuthorize("@el.check('serverDeploy:add')") + public ResponseEntity testConnect(@Validated @RequestBody ServerDeploy resources){ + return new ResponseEntity<>(serverDeployService.testConnect(resources),HttpStatus.CREATED); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/AppService.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/AppService.java new file mode 100644 index 0000000..c822778 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/AppService.java @@ -0,0 +1,81 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service; + +import me.zhengjie.modules.mnt.domain.App; +import me.zhengjie.modules.mnt.service.dto.AppDto; +import me.zhengjie.modules.mnt.service.dto.AppQueryCriteria; +import org.springframework.data.domain.Pageable; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface AppService { + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(AppQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部数据 + * @param criteria 条件 + * @return / + */ + List queryAll(AppQueryCriteria criteria); + + /** + * 根据ID查询 + * @param id / + * @return / + */ + AppDto findById(Long id); + + /** + * 创建 + * @param resources / + */ + void create(App resources); + + /** + * 编辑 + * @param resources / + */ + void update(App resources); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 导出数据 + * @param queryAll / + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/DatabaseService.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/DatabaseService.java new file mode 100644 index 0000000..e8a3acb --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/DatabaseService.java @@ -0,0 +1,88 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service; + +import me.zhengjie.modules.mnt.domain.Database; +import me.zhengjie.modules.mnt.service.dto.DatabaseDto; +import me.zhengjie.modules.mnt.service.dto.DatabaseQueryCriteria; +import org.springframework.data.domain.Pageable; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** + * @author ZhangHouYing + * @date 2019-08-24 + */ +public interface DatabaseService { + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(DatabaseQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部 + * @param criteria 条件 + * @return / + */ + List queryAll(DatabaseQueryCriteria criteria); + + /** + * 根据ID查询 + * @param id / + * @return / + */ + DatabaseDto findById(String id); + + /** + * 创建 + * @param resources / + */ + void create(Database resources); + + /** + * 编辑 + * @param resources / + */ + void update(Database resources); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 测试连接数据库 + * @param resources / + * @return / + */ + boolean testConnection(Database resources); + + /** + * 导出数据 + * @param queryAll / + * @param response / + * @throws IOException e + */ + void download(List queryAll, HttpServletResponse response) throws IOException; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/DeployHistoryService.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/DeployHistoryService.java new file mode 100644 index 0000000..5eb1b3d --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/DeployHistoryService.java @@ -0,0 +1,74 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service; + +import me.zhengjie.modules.mnt.domain.DeployHistory; +import me.zhengjie.modules.mnt.service.dto.DeployHistoryDto; +import me.zhengjie.modules.mnt.service.dto.DeployHistoryQueryCriteria; +import org.springframework.data.domain.Pageable; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** + * @author zhanghouying + */ +public interface DeployHistoryService { + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(DeployHistoryQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部 + * @param criteria 条件 + * @return / + */ + List queryAll(DeployHistoryQueryCriteria criteria); + + /** + * 根据ID查询 + * @param id / + * @return / + */ + DeployHistoryDto findById(String id); + + /** + * 创建 + * @param resources / + */ + void create(DeployHistory resources); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 导出数据 + * @param queryAll / + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/DeployService.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/DeployService.java new file mode 100644 index 0000000..583474d --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/DeployService.java @@ -0,0 +1,116 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service; + +import me.zhengjie.modules.mnt.domain.Deploy; +import me.zhengjie.modules.mnt.domain.DeployHistory; +import me.zhengjie.modules.mnt.service.dto.DeployDto; +import me.zhengjie.modules.mnt.service.dto.DeployQueryCriteria; +import org.springframework.data.domain.Pageable; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface DeployService { + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(DeployQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部数据 + * @param criteria 条件 + * @return / + */ + List queryAll(DeployQueryCriteria criteria); + + /** + * 根据ID查询 + * @param id / + * @return / + */ + DeployDto findById(Long id); + + /** + * 创建 + * @param resources / + */ + void create(Deploy resources); + + + /** + * 编辑 + * @param resources / + */ + void update(Deploy resources); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 部署文件到服务器 + * @param fileSavePath 文件路径 + * @param appId 应用ID + */ + void deploy(String fileSavePath, Long appId); + + /** + * 查询部署状态 + * @param resources / + * @return / + */ + String serverStatus(Deploy resources); + /** + * 启动服务 + * @param resources / + * @return / + */ + String startServer(Deploy resources); + /** + * 停止服务 + * @param resources / + * @return / + */ + String stopServer(Deploy resources); + + /** + * 停止服务 + * @param resources / + * @return / + */ + String serverReduction(DeployHistory resources); + + /** + * 导出数据 + * @param queryAll / + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/ServerDeployService.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/ServerDeployService.java new file mode 100644 index 0000000..be8bb57 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/ServerDeployService.java @@ -0,0 +1,95 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service; + +import me.zhengjie.modules.mnt.domain.ServerDeploy; +import me.zhengjie.modules.mnt.service.dto.ServerDeployDto; +import me.zhengjie.modules.mnt.service.dto.ServerDeployQueryCriteria; +import org.springframework.data.domain.Pageable; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface ServerDeployService { + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(ServerDeployQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部数据 + * @param criteria 条件 + * @return / + */ + List queryAll(ServerDeployQueryCriteria criteria); + + /** + * 根据ID查询 + * @param id / + * @return / + */ + ServerDeployDto findById(Long id); + + /** + * 创建 + * @param resources / + */ + void create(ServerDeploy resources); + + /** + * 编辑 + * @param resources / + */ + void update(ServerDeploy resources); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 根据IP查询 + * @param ip / + * @return / + */ + ServerDeployDto findByIp(String ip); + + /** + * 测试登录服务器 + * @param resources / + * @return / + */ + Boolean testConnect(ServerDeploy resources); + + /** + * 导出数据 + * @param queryAll / + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/AppDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/AppDto.java new file mode 100644 index 0000000..c6fd6f7 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/AppDto.java @@ -0,0 +1,71 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseDTO; +import java.io.Serializable; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Getter +@Setter +public class AppDto extends BaseDTO implements Serializable { + + /** + * 应用编号 + */ + private Long id; + + /** + * 应用名称 + */ + private String name; + + /** + * 端口 + */ + private Integer port; + + /** + * 上传目录 + */ + private String uploadPath; + + /** + * 部署目录 + */ + private String deployPath; + + /** + * 备份目录 + */ + private String backupPath; + + /** + * 启动脚本 + */ + private String startScript; + + /** + * 部署脚本 + */ + private String deployScript; + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/AppQueryCriteria.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/AppQueryCriteria.java new file mode 100644 index 0000000..17f358f --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/AppQueryCriteria.java @@ -0,0 +1,38 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class AppQueryCriteria{ + + /** + * 模糊 + */ + @Query(type = Query.Type.INNER_LIKE) + private String name; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DatabaseDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DatabaseDto.java new file mode 100644 index 0000000..689b06b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DatabaseDto.java @@ -0,0 +1,55 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseDTO; +import java.io.Serializable; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Getter +@Setter +public class DatabaseDto extends BaseDTO implements Serializable { + + /** + * id + */ + private String id; + + /** + * 数据库名称 + */ + private String name; + + /** + * 数据库连接地址 + */ + private String jdbcUrl; + + /** + * 数据库密码 + */ + private String pwd; + + /** + * 用户名 + */ + private String userName; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DatabaseQueryCriteria.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DatabaseQueryCriteria.java new file mode 100644 index 0000000..53d619d --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DatabaseQueryCriteria.java @@ -0,0 +1,44 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class DatabaseQueryCriteria{ + + /** + * 模糊 + */ + @Query(type = Query.Type.INNER_LIKE) + private String name; + + /** + * 精确 + */ + @Query + private String jdbcUrl; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployDto.java new file mode 100644 index 0000000..f3d77b8 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployDto.java @@ -0,0 +1,78 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.dto; + +import cn.hutool.core.collection.CollectionUtil; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseDTO; +import java.io.Serializable; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Getter +@Setter +public class DeployDto extends BaseDTO implements Serializable { + + /** + * 部署编号 + */ + private String id; + + private AppDto app; + + /** + * 服务器 + */ + private Set deploys; + + private String servers; + + /** + * 服务状态 + */ + private String status; + + public String getServers() { + if(CollectionUtil.isNotEmpty(deploys)){ + return deploys.stream().map(ServerDeployDto::getName).collect(Collectors.joining(",")); + } + return servers; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DeployDto deployDto = (DeployDto) o; + return Objects.equals(id, deployDto.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployHistoryDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployHistoryDto.java new file mode 100644 index 0000000..a9f480c --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployHistoryDto.java @@ -0,0 +1,58 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import java.io.Serializable; +import java.sql.Timestamp; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class DeployHistoryDto implements Serializable { + + /** + * 编号 + */ + private String id; + + /** + * 应用名称 + */ + private String appName; + + /** + * 部署IP + */ + private String ip; + + /** + * 部署时间 + */ + private Timestamp deployDate; + + /** + * 部署人员 + */ + private String deployUser; + + /** + * 部署编号 + */ + private Long deployId; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployHistoryQueryCriteria.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployHistoryQueryCriteria.java new file mode 100644 index 0000000..c34f124 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployHistoryQueryCriteria.java @@ -0,0 +1,41 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class DeployHistoryQueryCriteria{ + + /** + * 精确 + */ + @Query(blurry = "appName,ip,deployUser") + private String blurry; + + @Query + private Long deployId; + + @Query(type = Query.Type.BETWEEN) + private List deployDate; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployQueryCriteria.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployQueryCriteria.java new file mode 100644 index 0000000..c404620 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployQueryCriteria.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class DeployQueryCriteria{ + + /** + * 模糊 + */ + @Query(type = Query.Type.INNER_LIKE, propName = "name", joinName = "app") + private String appName; + + @Query(type = Query.Type.BETWEEN) + private List createTime; + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerDeployDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerDeployDto.java new file mode 100644 index 0000000..a49c795 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerDeployDto.java @@ -0,0 +1,61 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseDTO; +import java.io.Serializable; +import java.util.Objects; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Getter +@Setter +public class ServerDeployDto extends BaseDTO implements Serializable { + + private Long id; + + private String name; + + private String ip; + + private Integer port; + + private String account; + + private String password; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ServerDeployDto that = (ServerDeployDto) o; + return Objects.equals(id, that.id) && + Objects.equals(name, that.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerDeployQueryCriteria.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerDeployQueryCriteria.java new file mode 100644 index 0000000..bb8bd41 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerDeployQueryCriteria.java @@ -0,0 +1,38 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class ServerDeployQueryCriteria{ + + /** + * 模糊 + */ + @Query(blurry = "name,ip,account") + private String blurry; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/AppServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/AppServiceImpl.java new file mode 100644 index 0000000..42b088f --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/AppServiceImpl.java @@ -0,0 +1,123 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.impl; + +import lombok.RequiredArgsConstructor; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.mnt.domain.App; +import me.zhengjie.modules.mnt.repository.AppRepository; +import me.zhengjie.modules.mnt.service.AppService; +import me.zhengjie.modules.mnt.service.dto.AppDto; +import me.zhengjie.modules.mnt.service.dto.AppQueryCriteria; +import me.zhengjie.modules.mnt.service.mapstruct.AppMapper; +import me.zhengjie.utils.FileUtil; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.QueryHelp; +import me.zhengjie.utils.ValidationUtil; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Service +@RequiredArgsConstructor +public class AppServiceImpl implements AppService { + + private final AppRepository appRepository; + private final AppMapper appMapper; + + @Override + public Object queryAll(AppQueryCriteria criteria, Pageable pageable){ + Page page = appRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(appMapper::toDto)); + } + + @Override + public List queryAll(AppQueryCriteria criteria){ + return appMapper.toDto(appRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); + } + + @Override + public AppDto findById(Long id) { + App app = appRepository.findById(id).orElseGet(App::new); + ValidationUtil.isNull(app.getId(),"App","id",id); + return appMapper.toDto(app); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(App resources) { + verification(resources); + appRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(App resources) { + verification(resources); + App app = appRepository.findById(resources.getId()).orElseGet(App::new); + ValidationUtil.isNull(app.getId(),"App","id",resources.getId()); + app.copy(resources); + appRepository.save(app); + } + + private void verification(App resources){ + String opt = "/opt"; + String home = "/home"; + if (!(resources.getUploadPath().startsWith(opt) || resources.getUploadPath().startsWith(home))) { + throw new BadRequestException("文件只能上传在opt目录或者home目录 "); + } + if (!(resources.getDeployPath().startsWith(opt) || resources.getDeployPath().startsWith(home))) { + throw new BadRequestException("文件只能部署在opt目录或者home目录 "); + } + if (!(resources.getBackupPath().startsWith(opt) || resources.getBackupPath().startsWith(home))) { + throw new BadRequestException("文件只能备份在opt目录或者home目录 "); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + for (Long id : ids) { + appRepository.deleteById(id); + } + } + + @Override + public void download(List queryAll, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (AppDto appDto : queryAll) { + Map map = new LinkedHashMap<>(); + map.put("应用名称", appDto.getName()); + map.put("端口", appDto.getPort()); + map.put("上传目录", appDto.getUploadPath()); + map.put("部署目录", appDto.getDeployPath()); + map.put("备份目录", appDto.getBackupPath()); + map.put("启动脚本", appDto.getStartScript()); + map.put("部署脚本", appDto.getDeployScript()); + map.put("创建日期", appDto.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DatabaseServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DatabaseServiceImpl.java new file mode 100644 index 0000000..c774028 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DatabaseServiceImpl.java @@ -0,0 +1,117 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.impl; + +import cn.hutool.core.util.IdUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.modules.mnt.domain.Database; +import me.zhengjie.modules.mnt.repository.DatabaseRepository; +import me.zhengjie.modules.mnt.service.DatabaseService; +import me.zhengjie.modules.mnt.service.dto.DatabaseDto; +import me.zhengjie.modules.mnt.service.dto.DatabaseQueryCriteria; +import me.zhengjie.modules.mnt.service.mapstruct.DatabaseMapper; +import me.zhengjie.modules.mnt.util.SqlUtils; +import me.zhengjie.utils.FileUtil; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.QueryHelp; +import me.zhengjie.utils.ValidationUtil; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Slf4j +@Service +@RequiredArgsConstructor +public class DatabaseServiceImpl implements DatabaseService { + + private final DatabaseRepository databaseRepository; + private final DatabaseMapper databaseMapper; + + @Override + public Object queryAll(DatabaseQueryCriteria criteria, Pageable pageable){ + Page page = databaseRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(databaseMapper::toDto)); + } + + @Override + public List queryAll(DatabaseQueryCriteria criteria){ + return databaseMapper.toDto(databaseRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); + } + + @Override + public DatabaseDto findById(String id) { + Database database = databaseRepository.findById(id).orElseGet(Database::new); + ValidationUtil.isNull(database.getId(),"Database","id",id); + return databaseMapper.toDto(database); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Database resources) { + resources.setId(IdUtil.simpleUUID()); + databaseRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Database resources) { + Database database = databaseRepository.findById(resources.getId()).orElseGet(Database::new); + ValidationUtil.isNull(database.getId(),"Database","id",resources.getId()); + database.copy(resources); + databaseRepository.save(database); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + for (String id : ids) { + databaseRepository.deleteById(id); + } + } + + @Override + public boolean testConnection(Database resources) { + try { + return SqlUtils.testConnection(resources.getJdbcUrl(), resources.getUserName(), resources.getPwd()); + } catch (Exception e) { + log.error(e.getMessage()); + return false; + } + } + + @Override + public void download(List queryAll, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (DatabaseDto databaseDto : queryAll) { + Map map = new LinkedHashMap<>(); + map.put("数据库名称", databaseDto.getName()); + map.put("数据库连接地址", databaseDto.getJdbcUrl()); + map.put("用户名", databaseDto.getUserName()); + map.put("创建日期", databaseDto.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployHistoryServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployHistoryServiceImpl.java new file mode 100644 index 0000000..7431113 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployHistoryServiceImpl.java @@ -0,0 +1,96 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.impl; + +import cn.hutool.core.util.IdUtil; +import lombok.RequiredArgsConstructor; +import me.zhengjie.modules.mnt.domain.DeployHistory; +import me.zhengjie.modules.mnt.repository.DeployHistoryRepository; +import me.zhengjie.modules.mnt.service.DeployHistoryService; +import me.zhengjie.modules.mnt.service.dto.DeployHistoryDto; +import me.zhengjie.modules.mnt.service.dto.DeployHistoryQueryCriteria; +import me.zhengjie.modules.mnt.service.mapstruct.DeployHistoryMapper; +import me.zhengjie.utils.FileUtil; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.QueryHelp; +import me.zhengjie.utils.ValidationUtil; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Service +@RequiredArgsConstructor +public class DeployHistoryServiceImpl implements DeployHistoryService { + + private final DeployHistoryRepository deployhistoryRepository; + private final DeployHistoryMapper deployhistoryMapper; + + @Override + public Object queryAll(DeployHistoryQueryCriteria criteria, Pageable pageable){ + Page page = deployhistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(deployhistoryMapper::toDto)); + } + + @Override + public List queryAll(DeployHistoryQueryCriteria criteria){ + return deployhistoryMapper.toDto(deployhistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); + } + + @Override + public DeployHistoryDto findById(String id) { + DeployHistory deployhistory = deployhistoryRepository.findById(id).orElseGet(DeployHistory::new); + ValidationUtil.isNull(deployhistory.getId(),"DeployHistory","id",id); + return deployhistoryMapper.toDto(deployhistory); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(DeployHistory resources) { + resources.setId(IdUtil.simpleUUID()); + deployhistoryRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + for (String id : ids) { + deployhistoryRepository.deleteById(id); + } + } + + @Override + public void download(List queryAll, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (DeployHistoryDto deployHistoryDto : queryAll) { + Map map = new LinkedHashMap<>(); + map.put("部署编号", deployHistoryDto.getDeployId()); + map.put("应用名称", deployHistoryDto.getAppName()); + map.put("部署IP", deployHistoryDto.getIp()); + map.put("部署时间", deployHistoryDto.getDeployDate()); + map.put("部署人员", deployHistoryDto.getDeployUser()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployServiceImpl.java new file mode 100644 index 0000000..f2491cd --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployServiceImpl.java @@ -0,0 +1,430 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.impl; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.mnt.domain.App; +import me.zhengjie.modules.mnt.domain.Deploy; +import me.zhengjie.modules.mnt.domain.DeployHistory; +import me.zhengjie.modules.mnt.domain.ServerDeploy; +import me.zhengjie.modules.mnt.repository.DeployRepository; +import me.zhengjie.modules.mnt.service.DeployHistoryService; +import me.zhengjie.modules.mnt.service.DeployService; +import me.zhengjie.modules.mnt.service.ServerDeployService; +import me.zhengjie.modules.mnt.service.dto.AppDto; +import me.zhengjie.modules.mnt.service.dto.DeployDto; +import me.zhengjie.modules.mnt.service.dto.DeployQueryCriteria; +import me.zhengjie.modules.mnt.service.dto.ServerDeployDto; +import me.zhengjie.modules.mnt.service.mapstruct.DeployMapper; +import me.zhengjie.modules.mnt.util.ExecuteShellUtil; +import me.zhengjie.modules.mnt.util.ScpClientUtil; +import me.zhengjie.modules.mnt.websocket.MsgType; +import me.zhengjie.modules.mnt.websocket.SocketMsg; +import me.zhengjie.modules.mnt.websocket.WebSocketServer; +import me.zhengjie.utils.*; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** + * @author zhanghouying + * @date 2019-08-24 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class DeployServiceImpl implements DeployService { + + private final String FILE_SEPARATOR = "/"; + private final DeployRepository deployRepository; + private final DeployMapper deployMapper; + private final ServerDeployService serverDeployService; + private final DeployHistoryService deployHistoryService; + /** + * 循环次数 + */ + private final Integer count = 30; + + + @Override + public Object queryAll(DeployQueryCriteria criteria, Pageable pageable) { + Page page = deployRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable); + return PageUtil.toPage(page.map(deployMapper::toDto)); + } + + @Override + public List queryAll(DeployQueryCriteria criteria) { + return deployMapper.toDto(deployRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder))); + } + + @Override + public DeployDto findById(Long id) { + Deploy deploy = deployRepository.findById(id).orElseGet(Deploy::new); + ValidationUtil.isNull(deploy.getId(), "Deploy", "id", id); + return deployMapper.toDto(deploy); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Deploy resources) { + deployRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Deploy resources) { + Deploy deploy = deployRepository.findById(resources.getId()).orElseGet(Deploy::new); + ValidationUtil.isNull(deploy.getId(), "Deploy", "id", resources.getId()); + deploy.copy(resources); + deployRepository.save(deploy); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + for (Long id : ids) { + deployRepository.deleteById(id); + } + } + + @Override + public void deploy(String fileSavePath, Long id) { + deployApp(fileSavePath, id); + } + + /** + * @param fileSavePath 本机路径 + * @param id ID + */ + private void deployApp(String fileSavePath, Long id) { + + DeployDto deploy = findById(id); + if (deploy == null) { + sendMsg("部署信息不存在", MsgType.ERROR); + throw new BadRequestException("部署信息不存在"); + } + AppDto app = deploy.getApp(); + if (app == null) { + sendMsg("包对应应用信息不存在", MsgType.ERROR); + throw new BadRequestException("包对应应用信息不存在"); + } + int port = app.getPort(); + //这个是服务器部署路径 + String uploadPath = app.getUploadPath(); + StringBuilder sb = new StringBuilder(); + String msg; + Set deploys = deploy.getDeploys(); + for (ServerDeployDto deployDTO : deploys) { + String ip = deployDTO.getIp(); + ExecuteShellUtil executeShellUtil = getExecuteShellUtil(ip); + //判断是否第一次部署 + boolean flag = checkFile(executeShellUtil, app); + //第一步要确认服务器上有这个目录 + executeShellUtil.execute("mkdir -p " + app.getUploadPath()); + executeShellUtil.execute("mkdir -p " + app.getBackupPath()); + executeShellUtil.execute("mkdir -p " + app.getDeployPath()); + //上传文件 + msg = String.format("登陆到服务器:%s", ip); + ScpClientUtil scpClientUtil = getScpClientUtil(ip); + log.info(msg); + sendMsg(msg, MsgType.INFO); + msg = String.format("上传文件到服务器:%s
目录:%s下,请稍等...", ip, uploadPath); + sendMsg(msg, MsgType.INFO); + scpClientUtil.putFile(fileSavePath, uploadPath); + if (flag) { + sendMsg("停止原来应用", MsgType.INFO); + //停止应用 + stopApp(port, executeShellUtil); + sendMsg("备份原来应用", MsgType.INFO); + //备份应用 + backupApp(executeShellUtil, ip, app.getDeployPath()+FILE_SEPARATOR, app.getName(), app.getBackupPath()+FILE_SEPARATOR, id); + } + sendMsg("部署应用", MsgType.INFO); + //部署文件,并启动应用 + String deployScript = app.getDeployScript(); + executeShellUtil.execute(deployScript); + sleep(3); + sendMsg("应用部署中,请耐心等待部署结果,或者稍后手动查看部署状态", MsgType.INFO); + int i = 0; + boolean result = false; + // 由于启动应用需要时间,所以需要循环获取状态,如果超过30次,则认为是启动失败 + while (i++ < count){ + result = checkIsRunningStatus(port, executeShellUtil); + if(result){ + break; + } + // 休眠6秒 + sleep(6); + } + sb.append("服务器:").append(deployDTO.getName()).append("
应用:").append(app.getName()); + sendResultMsg(result, sb); + executeShellUtil.close(); + } + } + + private void sleep(int second) { + try { + Thread.sleep(second * 1000); + } catch (InterruptedException e) { + log.error(e.getMessage(),e); + } + } + + private void backupApp(ExecuteShellUtil executeShellUtil, String ip, String fileSavePath, String appName, String backupPath, Long id) { + String deployDate = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN); + StringBuilder sb = new StringBuilder(); + backupPath += appName + FILE_SEPARATOR + deployDate + "\n"; + sb.append("mkdir -p ").append(backupPath); + sb.append("mv -f ").append(fileSavePath); + sb.append(appName).append(" ").append(backupPath); + log.info("备份应用脚本:" + sb.toString()); + executeShellUtil.execute(sb.toString()); + //还原信息入库 + DeployHistory deployHistory = new DeployHistory(); + deployHistory.setAppName(appName); + deployHistory.setDeployUser(SecurityUtils.getCurrentUsername()); + deployHistory.setIp(ip); + deployHistory.setDeployId(id); + deployHistoryService.create(deployHistory); + } + + /** + * 停App + * + * @param port 端口 + * @param executeShellUtil / + */ + private void stopApp(int port, ExecuteShellUtil executeShellUtil) { + //发送停止命令 + executeShellUtil.execute(String.format("lsof -i :%d|grep -v \"PID\"|awk '{print \"kill -9\",$2}'|sh", port)); + + } + + /** + * 指定端口程序是否在运行 + * + * @param port 端口 + * @param executeShellUtil / + * @return true 正在运行 false 已经停止 + */ + private boolean checkIsRunningStatus(int port, ExecuteShellUtil executeShellUtil) { + String result = executeShellUtil.executeForResult(String.format("fuser -n tcp %d", port)); + return result.indexOf("/tcp:")>0; + } + + private void sendMsg(String msg, MsgType msgType) { + try { + WebSocketServer.sendInfo(new SocketMsg(msg, msgType), "deploy"); + } catch (IOException e) { + log.error(e.getMessage(),e); + } + } + + @Override + public String serverStatus(Deploy resources) { + Set serverDeploys = resources.getDeploys(); + App app = resources.getApp(); + for (ServerDeploy serverDeploy : serverDeploys) { + StringBuilder sb = new StringBuilder(); + ExecuteShellUtil executeShellUtil = getExecuteShellUtil(serverDeploy.getIp()); + sb.append("服务器:").append(serverDeploy.getName()).append("
应用:").append(app.getName()); + boolean result = checkIsRunningStatus(app.getPort(), executeShellUtil); + if (result) { + sb.append("
正在运行"); + sendMsg(sb.toString(), MsgType.INFO); + } else { + sb.append("
已停止!"); + sendMsg(sb.toString(), MsgType.ERROR); + } + log.info(sb.toString()); + executeShellUtil.close(); + } + return "执行完毕"; + } + + private boolean checkFile(ExecuteShellUtil executeShellUtil, AppDto appDTO) { + String result = executeShellUtil.executeForResult("find " + appDTO.getDeployPath() + " -name " + appDTO.getName()); + return result.indexOf(appDTO.getName())>0; + } + + /** + * 启动服务 + * @param resources / + * @return / + */ + @Override + public String startServer(Deploy resources) { + Set deploys = resources.getDeploys(); + App app = resources.getApp(); + for (ServerDeploy deploy : deploys) { + StringBuilder sb = new StringBuilder(); + ExecuteShellUtil executeShellUtil = getExecuteShellUtil(deploy.getIp()); + //为了防止重复启动,这里先停止应用 + stopApp(app.getPort(), executeShellUtil); + sb.append("服务器:").append(deploy.getName()).append("
应用:").append(app.getName()); + sendMsg("下发启动命令", MsgType.INFO); + executeShellUtil.execute(app.getStartScript()); + sleep(3); + sendMsg("应用启动中,请耐心等待启动结果,或者稍后手动查看运行状态", MsgType.INFO); + int i = 0; + boolean result = false; + // 由于启动应用需要时间,所以需要循环获取状态,如果超过30次,则认为是启动失败 + while (i++ < count){ + result = checkIsRunningStatus(app.getPort(), executeShellUtil); + if(result){ + break; + } + // 休眠6秒 + sleep(6); + } + sendResultMsg(result, sb); + log.info(sb.toString()); + executeShellUtil.close(); + } + return "执行完毕"; + } + + /** + * 停止服务 + * @param resources / + * @return / + */ + @Override + public String stopServer(Deploy resources) { + Set deploys = resources.getDeploys(); + App app = resources.getApp(); + for (ServerDeploy deploy : deploys) { + StringBuilder sb = new StringBuilder(); + ExecuteShellUtil executeShellUtil = getExecuteShellUtil(deploy.getIp()); + sb.append("服务器:").append(deploy.getName()).append("
应用:").append(app.getName()); + sendMsg("下发停止命令", MsgType.INFO); + //停止应用 + stopApp(app.getPort(), executeShellUtil); + sleep(1); + boolean result = checkIsRunningStatus(app.getPort(), executeShellUtil); + if (result) { + sb.append("
关闭失败!"); + sendMsg(sb.toString(), MsgType.ERROR); + } else { + sb.append("
关闭成功!"); + sendMsg(sb.toString(), MsgType.INFO); + } + log.info(sb.toString()); + executeShellUtil.close(); + } + return "执行完毕"; + } + + @Override + public String serverReduction(DeployHistory resources) { + Long deployId = resources.getDeployId(); + Deploy deployInfo = deployRepository.findById(deployId).orElseGet(Deploy::new); + String deployDate = DateUtil.format(resources.getDeployDate(), DatePattern.PURE_DATETIME_PATTERN); + App app = deployInfo.getApp(); + if (app == null) { + sendMsg("应用信息不存在:" + resources.getAppName(), MsgType.ERROR); + throw new BadRequestException("应用信息不存在:" + resources.getAppName()); + } + String backupPath = app.getBackupPath()+FILE_SEPARATOR; + backupPath += resources.getAppName() + FILE_SEPARATOR + deployDate; + //这个是服务器部署路径 + String deployPath = app.getDeployPath(); + String ip = resources.getIp(); + ExecuteShellUtil executeShellUtil = getExecuteShellUtil(ip); + String msg; + + msg = String.format("登陆到服务器:%s", ip); + log.info(msg); + sendMsg(msg, MsgType.INFO); + sendMsg("停止原来应用", MsgType.INFO); + //停止应用 + stopApp(app.getPort(), executeShellUtil); + //删除原来应用 + sendMsg("删除应用", MsgType.INFO); + executeShellUtil.execute("rm -rf " + deployPath + FILE_SEPARATOR + resources.getAppName()); + //还原应用 + sendMsg("还原应用", MsgType.INFO); + executeShellUtil.execute("cp -r " + backupPath + "/. " + deployPath); + sendMsg("启动应用", MsgType.INFO); + executeShellUtil.execute(app.getStartScript()); + sendMsg("应用启动中,请耐心等待启动结果,或者稍后手动查看启动状态", MsgType.INFO); + int i = 0; + boolean result = false; + // 由于启动应用需要时间,所以需要循环获取状态,如果超过30次,则认为是启动失败 + while (i++ < count){ + result = checkIsRunningStatus(app.getPort(), executeShellUtil); + if(result){ + break; + } + // 休眠6秒 + sleep(6); + } + StringBuilder sb = new StringBuilder(); + sb.append("服务器:").append(ip).append("
应用:").append(resources.getAppName()); + sendResultMsg(result, sb); + executeShellUtil.close(); + return ""; + } + + private ExecuteShellUtil getExecuteShellUtil(String ip) { + ServerDeployDto serverDeployDTO = serverDeployService.findByIp(ip); + if (serverDeployDTO == null) { + sendMsg("IP对应服务器信息不存在:" + ip, MsgType.ERROR); + throw new BadRequestException("IP对应服务器信息不存在:" + ip); + } + return new ExecuteShellUtil(ip, serverDeployDTO.getAccount(), serverDeployDTO.getPassword(),serverDeployDTO.getPort()); + } + + private ScpClientUtil getScpClientUtil(String ip) { + ServerDeployDto serverDeployDTO = serverDeployService.findByIp(ip); + if (serverDeployDTO == null) { + sendMsg("IP对应服务器信息不存在:" + ip, MsgType.ERROR); + throw new BadRequestException("IP对应服务器信息不存在:" + ip); + } + return ScpClientUtil.getInstance(ip, serverDeployDTO.getPort(), serverDeployDTO.getAccount(), serverDeployDTO.getPassword()); + } + + private void sendResultMsg(boolean result, StringBuilder sb) { + if (result) { + sb.append("
启动成功!"); + sendMsg(sb.toString(), MsgType.INFO); + } else { + sb.append("
启动失败!"); + sendMsg(sb.toString(), MsgType.ERROR); + } + } + + @Override + public void download(List queryAll, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (DeployDto deployDto : queryAll) { + Map map = new LinkedHashMap<>(); + map.put("应用名称", deployDto.getApp().getName()); + map.put("服务器", deployDto.getServers()); + map.put("部署日期", deployDto.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/ServerDeployServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/ServerDeployServiceImpl.java new file mode 100644 index 0000000..63272da --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/impl/ServerDeployServiceImpl.java @@ -0,0 +1,125 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.impl; + +import lombok.RequiredArgsConstructor; +import me.zhengjie.modules.mnt.domain.ServerDeploy; +import me.zhengjie.modules.mnt.repository.ServerDeployRepository; +import me.zhengjie.modules.mnt.service.ServerDeployService; +import me.zhengjie.modules.mnt.service.dto.ServerDeployDto; +import me.zhengjie.modules.mnt.service.dto.ServerDeployQueryCriteria; +import me.zhengjie.modules.mnt.service.mapstruct.ServerDeployMapper; +import me.zhengjie.modules.mnt.util.ExecuteShellUtil; +import me.zhengjie.utils.FileUtil; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.QueryHelp; +import me.zhengjie.utils.ValidationUtil; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Service +@RequiredArgsConstructor +public class ServerDeployServiceImpl implements ServerDeployService { + + private final ServerDeployRepository serverDeployRepository; + private final ServerDeployMapper serverDeployMapper; + + @Override + public Object queryAll(ServerDeployQueryCriteria criteria, Pageable pageable){ + Page page = serverDeployRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(serverDeployMapper::toDto)); + } + + @Override + public List queryAll(ServerDeployQueryCriteria criteria){ + return serverDeployMapper.toDto(serverDeployRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); + } + + @Override + public ServerDeployDto findById(Long id) { + ServerDeploy server = serverDeployRepository.findById(id).orElseGet(ServerDeploy::new); + ValidationUtil.isNull(server.getId(),"ServerDeploy","id",id); + return serverDeployMapper.toDto(server); + } + + @Override + public ServerDeployDto findByIp(String ip) { + ServerDeploy deploy = serverDeployRepository.findByIp(ip); + return serverDeployMapper.toDto(deploy); + } + + @Override + public Boolean testConnect(ServerDeploy resources) { + ExecuteShellUtil executeShellUtil = null; + try { + executeShellUtil = new ExecuteShellUtil(resources.getIp(), resources.getAccount(), resources.getPassword(),resources.getPort()); + return executeShellUtil.execute("ls")==0; + } catch (Exception e) { + return false; + }finally { + if (executeShellUtil != null) { + executeShellUtil.close(); + } + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(ServerDeploy resources) { + serverDeployRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(ServerDeploy resources) { + ServerDeploy serverDeploy = serverDeployRepository.findById(resources.getId()).orElseGet(ServerDeploy::new); + ValidationUtil.isNull( serverDeploy.getId(),"ServerDeploy","id",resources.getId()); + serverDeploy.copy(resources); + serverDeployRepository.save(serverDeploy); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + for (Long id : ids) { + serverDeployRepository.deleteById(id); + } + } + + @Override + public void download(List queryAll, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (ServerDeployDto deployDto : queryAll) { + Map map = new LinkedHashMap<>(); + map.put("服务器名称", deployDto.getName()); + map.put("服务器IP", deployDto.getIp()); + map.put("端口", deployDto.getPort()); + map.put("账号", deployDto.getAccount()); + map.put("创建日期", deployDto.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/AppMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/AppMapper.java new file mode 100644 index 0000000..fc39eeb --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/AppMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.mnt.domain.App; +import me.zhengjie.modules.mnt.service.dto.AppDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Mapper(componentModel = "spring",uses = {},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface AppMapper extends BaseMapper { + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/DatabaseMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/DatabaseMapper.java new file mode 100644 index 0000000..3cc6e8d --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/DatabaseMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.mnt.domain.Database; +import me.zhengjie.modules.mnt.service.dto.DatabaseDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DatabaseMapper extends BaseMapper { + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/DeployHistoryMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/DeployHistoryMapper.java new file mode 100644 index 0000000..2522ab0 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/DeployHistoryMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.mnt.domain.DeployHistory; +import me.zhengjie.modules.mnt.service.dto.DeployHistoryDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Mapper(componentModel = "spring",uses = {},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DeployHistoryMapper extends BaseMapper { + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/DeployMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/DeployMapper.java new file mode 100644 index 0000000..cd3edee --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/DeployMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.mnt.domain.Deploy; +import me.zhengjie.modules.mnt.service.dto.DeployDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Mapper(componentModel = "spring",uses = {AppMapper.class, ServerDeployMapper.class},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DeployMapper extends BaseMapper { + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/ServerDeployMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/ServerDeployMapper.java new file mode 100644 index 0000000..960b25b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/service/mapstruct/ServerDeployMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.mnt.domain.ServerDeploy; +import me.zhengjie.modules.mnt.service.dto.ServerDeployDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Mapper(componentModel = "spring",uses = {},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface ServerDeployMapper extends BaseMapper { + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/util/DataTypeEnum.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/util/DataTypeEnum.java new file mode 100644 index 0000000..e104b9e --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/util/DataTypeEnum.java @@ -0,0 +1,140 @@ +/* + * << + * Davinci + * == + * Copyright (C) 2016 - 2019 EDP + * == + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * >> + * + */ + +package me.zhengjie.modules.mnt.util; +import lombok.extern.slf4j.Slf4j; + +/** + * @author / + */ +@Slf4j +@SuppressWarnings({"unchecked","all"}) +public enum DataTypeEnum { + + /** mysql */ + MYSQL("mysql", "mysql", "com.mysql.jdbc.Driver", "`", "`", "'", "'"), + + /** oracle */ + ORACLE("oracle", "oracle", "oracle.jdbc.driver.OracleDriver", "\"", "\"", "\"", "\""), + + /** sql server */ + SQLSERVER("sqlserver", "sqlserver", "com.microsoft.sqlserver.jdbc.SQLServerDriver", "\"", "\"", "\"", "\""), + + /** h2 */ + H2("h2", "h2", "org.h2.Driver", "`", "`", "\"", "\""), + + /** phoenix */ + PHOENIX("phoenix", "hbase phoenix", "org.apache.phoenix.jdbc.PhoenixDriver", "", "", "\"", "\""), + + /** mongo */ + MONGODB("mongo", "mongodb", "mongodb.jdbc.MongoDriver", "`", "`", "\"", "\""), + + /** sql4es */ + ELASTICSEARCH("sql4es", "elasticsearch", "nl.anchormen.sql4es.jdbc.ESDriver", "", "", "'", "'"), + + /** presto */ + PRESTO("presto", "presto", "com.facebook.presto.jdbc.PrestoDriver", "", "", "\"", "\""), + + /** moonbox */ + MOONBOX("moonbox", "moonbox", "moonbox.jdbc.MbDriver", "`", "`", "`", "`"), + + /** cassandra */ + CASSANDRA("cassandra", "cassandra", "com.github.adejanovski.cassandra.jdbc.CassandraDriver", "", "", "'", "'"), + + /** click house */ + CLICKHOUSE("clickhouse", "clickhouse", "ru.yandex.clickhouse.ClickHouseDriver", "", "", "\"", "\""), + + /** kylin */ + KYLIN("kylin", "kylin", "org.apache.kylin.jdbc.Driver", "\"", "\"", "\"", "\""), + + /** vertica */ + VERTICA("vertica", "vertica", "com.vertica.jdbc.Driver", "", "", "'", "'"), + + /** sap */ + HANA("sap", "sap hana", "com.sap.db.jdbc.Driver", "", "", "'", "'"), + + /** impala */ + IMPALA("impala", "impala", "com.cloudera.impala.jdbc41.Driver", "", "", "'", "'"); + + private String feature; + private String desc; + private String driver; + private String keywordPrefix; + private String keywordSuffix; + private String aliasPrefix; + private String aliasSuffix; + + private static final String JDBC_URL_PREFIX = "jdbc:"; + + DataTypeEnum(String feature, String desc, String driver, String keywordPrefix, String keywordSuffix, String aliasPrefix, String aliasSuffix) { + this.feature = feature; + this.desc = desc; + this.driver = driver; + this.keywordPrefix = keywordPrefix; + this.keywordSuffix = keywordSuffix; + this.aliasPrefix = aliasPrefix; + this.aliasSuffix = aliasSuffix; + } + + public static DataTypeEnum urlOf(String jdbcUrl) { + String url = jdbcUrl.toLowerCase().trim(); + for (DataTypeEnum dataTypeEnum : values()) { + if (url.startsWith(JDBC_URL_PREFIX + dataTypeEnum.feature)) { + try { + Class aClass = Class.forName(dataTypeEnum.getDriver()); + if (null == aClass) { + throw new RuntimeException("Unable to get driver instance for jdbcUrl: " + jdbcUrl); + } + } catch (ClassNotFoundException e) { + throw new RuntimeException("Unable to get driver instance: " + jdbcUrl); + } + return dataTypeEnum; + } + } + return null; + } + + public String getFeature() { + return feature; + } + + public String getDesc() { + return desc; + } + + public String getDriver() { + return driver; + } + + public String getKeywordPrefix() { + return keywordPrefix; + } + + public String getKeywordSuffix() { + return keywordSuffix; + } + + public String getAliasPrefix() { + return aliasPrefix; + } + + public String getAliasSuffix() { + return aliasSuffix; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/util/ExecuteShellUtil.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/util/ExecuteShellUtil.java new file mode 100644 index 0000000..a5d5b59 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/util/ExecuteShellUtil.java @@ -0,0 +1,101 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.util; + +import cn.hutool.core.io.IoUtil; +import com.jcraft.jsch.ChannelShell; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.Session; +import lombok.extern.slf4j.Slf4j; + +import java.io.*; +import java.util.Vector; + +/** + * 执行shell命令 + * + * @author: ZhangHouYing + * @date: 2019/8/10 + */ +@Slf4j +public class ExecuteShellUtil { + + private Vector stdout; + + Session session; + + public ExecuteShellUtil(final String ipAddress, final String username, final String password,int port) { + try { + JSch jsch = new JSch(); + session = jsch.getSession(username, ipAddress, port); + session.setPassword(password); + session.setConfig("StrictHostKeyChecking", "no"); + session.connect(3000); + } catch (Exception e) { + log.error(e.getMessage(),e); + } + + } + + public int execute(final String command) { + int returnCode = 0; + ChannelShell channel = null; + PrintWriter printWriter = null; + BufferedReader input = null; + stdout = new Vector(); + try { + channel = (ChannelShell) session.openChannel("shell"); + channel.connect(); + input = new BufferedReader(new InputStreamReader(channel.getInputStream())); + printWriter = new PrintWriter(channel.getOutputStream()); + printWriter.println(command); + printWriter.println("exit"); + printWriter.flush(); + log.info("The remote command is: "); + String line; + while ((line = input.readLine()) != null) { + stdout.add(line); + System.out.println(line); + } + } catch (Exception e) { + log.error(e.getMessage(),e); + return -1; + }finally { + IoUtil.close(printWriter); + IoUtil.close(input); + if (channel != null) { + channel.disconnect(); + } + } + return returnCode; + } + + public void close(){ + if (session != null) { + session.disconnect(); + } + } + + public String executeForResult(String command) { + execute(command); + StringBuilder sb = new StringBuilder(); + for (String str : stdout) { + sb.append(str); + } + return sb.toString(); + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/util/ScpClientUtil.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/util/ScpClientUtil.java new file mode 100644 index 0000000..7cb83aa --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/util/ScpClientUtil.java @@ -0,0 +1,105 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.util; + +import ch.ethz.ssh2.Connection; +import ch.ethz.ssh2.SCPClient; +import com.google.common.collect.Maps; + +import java.io.IOException; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * 远程执行linux命令 + * @author: ZhangHouYing + * @date: 2019-08-10 10:06 + */ +public class ScpClientUtil { + + static private Map instance = Maps.newHashMap(); + + static synchronized public ScpClientUtil getInstance(String ip, int port, String username, String password) { + if (instance.get(ip) == null) { + instance.put(ip, new ScpClientUtil(ip, port, username, password)); + } + return instance.get(ip); + } + + public ScpClientUtil(String ip, int port, String username, String password) { + this.ip = ip; + this.port = port; + this.username = username; + this.password = password; + } + + public void getFile(String remoteFile, String localTargetDirectory) { + Connection conn = new Connection(ip, port); + try { + conn.connect(); + boolean isAuthenticated = conn.authenticateWithPassword(username, password); + if (!isAuthenticated) { + System.err.println("authentication failed"); + } + SCPClient client = new SCPClient(conn); + client.get(remoteFile, localTargetDirectory); + } catch (IOException ex) { + Logger.getLogger(SCPClient.class.getName()).log(Level.SEVERE, null, ex); + }finally{ + conn.close(); + } + } + + public void putFile(String localFile, String remoteTargetDirectory) { + putFile(localFile, null, remoteTargetDirectory); + } + + public void putFile(String localFile, String remoteFileName, String remoteTargetDirectory) { + putFile(localFile, remoteFileName, remoteTargetDirectory,null); + } + + public void putFile(String localFile, String remoteFileName, String remoteTargetDirectory, String mode) { + Connection conn = new Connection(ip, port); + try { + conn.connect(); + boolean isAuthenticated = conn.authenticateWithPassword(username, password); + if (!isAuthenticated) { + System.err.println("authentication failed"); + } + SCPClient client = new SCPClient(conn); + if ((mode == null) || (mode.length() == 0)) { + mode = "0600"; + } + if (remoteFileName == null) { + client.put(localFile, remoteTargetDirectory); + } else { + client.put(localFile, remoteFileName, remoteTargetDirectory, mode); + } + } catch (IOException ex) { + Logger.getLogger(ScpClientUtil.class.getName()).log(Level.SEVERE, null, ex); + }finally{ + conn.close(); + } + } + + private String ip; + private int port; + private String username; + private String password; + + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/util/SqlUtils.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/util/SqlUtils.java new file mode 100644 index 0000000..d7e06b1 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/util/SqlUtils.java @@ -0,0 +1,201 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.util; + +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.util.StringUtils; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.utils.CloseUtil; +import javax.sql.DataSource; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.sql.*; +import java.util.List; + +/** + * @author / + */ +@Slf4j +public class SqlUtils { + + /** + * 获取数据源 + * + * @param jdbcUrl / + * @param userName / + * @param password / + * @return DataSource + */ + private static DataSource getDataSource(String jdbcUrl, String userName, String password) { + DruidDataSource druidDataSource = new DruidDataSource(); + String className; + try { + className = DriverManager.getDriver(jdbcUrl.trim()).getClass().getName(); + } catch (SQLException e) { + throw new RuntimeException("Get class name error: =" + jdbcUrl); + } + if (StringUtils.isEmpty(className)) { + DataTypeEnum dataTypeEnum = DataTypeEnum.urlOf(jdbcUrl); + if (null == dataTypeEnum) { + throw new RuntimeException("Not supported data type: jdbcUrl=" + jdbcUrl); + } + druidDataSource.setDriverClassName(dataTypeEnum.getDriver()); + } else { + druidDataSource.setDriverClassName(className); + } + + + druidDataSource.setUrl(jdbcUrl); + druidDataSource.setUsername(userName); + druidDataSource.setPassword(password); + // 配置获取连接等待超时的时间 + druidDataSource.setMaxWait(3000); + // 配置初始化大小、最小、最大 + druidDataSource.setInitialSize(1); + druidDataSource.setMinIdle(1); + druidDataSource.setMaxActive(1); + + // 如果链接出现异常则直接判定为失败而不是一直重试 + druidDataSource.setBreakAfterAcquireFailure(true); + try { + druidDataSource.init(); + } catch (SQLException e) { + log.error("Exception during pool initialization", e); + throw new RuntimeException(e.getMessage()); + } + + return druidDataSource; + } + + private static Connection getConnection(String jdbcUrl, String userName, String password) { + DataSource dataSource = getDataSource(jdbcUrl, userName, password); + Connection connection = null; + try { + connection = dataSource.getConnection(); + } catch (Exception ignored) {} + try { + int timeOut = 5; + if (null == connection || connection.isClosed() || !connection.isValid(timeOut)) { + log.info("connection is closed or invalid, retry get connection!"); + connection = dataSource.getConnection(); + } + } catch (Exception e) { + log.error("create connection error, jdbcUrl: {}", jdbcUrl); + throw new RuntimeException("create connection error, jdbcUrl: " + jdbcUrl); + } finally { + CloseUtil.close(connection); + } + return connection; + } + + private static void releaseConnection(Connection connection) { + if (null != connection) { + try { + connection.close(); + } catch (Exception e) { + log.error(e.getMessage(),e); + log.error("connection close error:" + e.getMessage()); + } + } + } + + public static boolean testConnection(String jdbcUrl, String userName, String password) { + Connection connection = null; + try { + connection = getConnection(jdbcUrl, userName, password); + if (null != connection) { + return true; + } + } catch (Exception e) { + log.info("Get connection failed:" + e.getMessage()); + } finally { + releaseConnection(connection); + } + return false; + } + + public static String executeFile(String jdbcUrl, String userName, String password, File sqlFile) { + Connection connection = getConnection(jdbcUrl, userName, password); + try { + batchExecute(connection, readSqlList(sqlFile)); + } catch (Exception e) { + log.error("sql脚本执行发生异常:{}",e.getMessage()); + return e.getMessage(); + }finally { + releaseConnection(connection); + } + return "success"; + } + + + /** + * 批量执行sql + * @param connection / + * @param sqlList / + */ + public static void batchExecute(Connection connection, List sqlList) { + Statement st = null; + try { + st = connection.createStatement(); + for (String sql : sqlList) { + if (sql.endsWith(";")) { + sql = sql.substring(0, sql.length() - 1); + } + st.addBatch(sql); + } + st.executeBatch(); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } finally { + CloseUtil.close(st); + } + } + + /** + * 将文件中的sql语句以;为单位读取到列表中 + * @param sqlFile / + * @return / + * @throws Exception e + */ + private static List readSqlList(File sqlFile) throws Exception { + List sqlList = Lists.newArrayList(); + StringBuilder sb = new StringBuilder(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader( + new FileInputStream(sqlFile), StandardCharsets.UTF_8))) { + String tmp; + while ((tmp = reader.readLine()) != null) { + log.info("line:{}", tmp); + if (tmp.endsWith(";")) { + sb.append(tmp); + sqlList.add(sb.toString()); + sb.delete(0, sb.length()); + } else { + sb.append(tmp); + } + } + if (!"".endsWith(sb.toString().trim())) { + sqlList.add(sb.toString()); + } + } + + return sqlList; + } + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/websocket/MsgType.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/websocket/MsgType.java new file mode 100644 index 0000000..2fc473d --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/websocket/MsgType.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.websocket; + +/** + * @author ZhangHouYing + * @date 2019-08-10 9:56 + */ +public enum MsgType { + /** 连接 */ + CONNECT, + /** 关闭 */ + CLOSE, + /** 信息 */ + INFO, + /** 错误 */ + ERROR +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/websocket/SocketMsg.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/websocket/SocketMsg.java new file mode 100644 index 0000000..ade33a2 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/websocket/SocketMsg.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.websocket; + +import lombok.Data; + +/** + * @author ZhangHouYing + * @date 2019-08-10 9:55 + */ +@Data +public class SocketMsg { + private String msg; + private MsgType msgType; + + public SocketMsg(String msg, MsgType msgType) { + this.msg = msg; + this.msgType = msgType; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/mnt/websocket/WebSocketServer.java b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/websocket/WebSocketServer.java new file mode 100644 index 0000000..9c92165 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/mnt/websocket/WebSocketServer.java @@ -0,0 +1,139 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.mnt.websocket; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.websocket.*; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.io.IOException; +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArraySet; +/** + * @author ZhangHouYing + * @date 2019-08-10 15:46 + */ +@ServerEndpoint("/webSocket/{sid}") +@Slf4j +@Component +public class WebSocketServer { + + /** + * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。 + */ + private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet(); + + /** + * 与某个客户端的连接会话,需要通过它来给客户端发送数据 + */ + private Session session; + + /** + * 接收sid + */ + private String sid=""; + /** + * 连接建立成功调用的方法 + * */ + @OnOpen + public void onOpen(Session session,@PathParam("sid") String sid) { + this.session = session; + //如果存在就先删除一个,防止重复推送消息 + for (WebSocketServer webSocket:webSocketSet) { + if (webSocket.sid.equals(sid)) { + webSocketSet.remove(webSocket); + } + } + webSocketSet.add(this); + this.sid=sid; + } + + /** + * 连接关闭调用的方法 + */ + @OnClose + public void onClose() { + webSocketSet.remove(this); + } + + /** + * 收到客户端消息后调用的方法 + * @param message 客户端发送过来的消息*/ + @OnMessage + public void onMessage(String message, Session session) { + log.info("收到来"+sid+"的信息:"+message); + //群发消息 + for (WebSocketServer item : webSocketSet) { + try { + item.sendMessage(message); + } catch (IOException e) { + log.error(e.getMessage(),e); + } + } + } + + @OnError + public void onError(Session session, Throwable error) { + log.error("发生错误"); + error.printStackTrace(); + } + /** + * 实现服务器主动推送 + */ + private void sendMessage(String message) throws IOException { + this.session.getBasicRemote().sendText(message); + } + + + /** + * 群发自定义消息 + * */ + public static void sendInfo(SocketMsg socketMsg,@PathParam("sid") String sid) throws IOException { + String message = JSONObject.toJSONString(socketMsg); + log.info("推送消息到"+sid+",推送内容:"+message); + for (WebSocketServer item : webSocketSet) { + try { + //这里可以设定只推送给这个sid的,为null则全部推送 + if(sid==null) { + item.sendMessage(message); + }else if(item.sid.equals(sid)){ + item.sendMessage(message); + } + } catch (IOException ignored) { } + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + WebSocketServer that = (WebSocketServer) o; + return Objects.equals(session, that.session) && + Objects.equals(sid, that.sid); + } + + @Override + public int hashCode() { + return Objects.hash(session, sid); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/config/JobRunner.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/config/JobRunner.java new file mode 100644 index 0000000..9b903e9 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/config/JobRunner.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.config; + +import cn.hutool.json.JSONUtil; +import lombok.RequiredArgsConstructor; +import me.zhengjie.modules.quartz.domain.QuartzJob; +import me.zhengjie.modules.quartz.repository.QuartzJobRepository; +import me.zhengjie.modules.quartz.utils.QuartzManage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @author Zheng Jie + * @date 2019-01-07 + */ +@Component +@RequiredArgsConstructor +public class JobRunner implements ApplicationRunner { + private static final Logger log = LoggerFactory.getLogger(JobRunner.class); + private final QuartzJobRepository quartzJobRepository; + private final QuartzManage quartzManage; + + /** + * 项目启动时重新激活启用的定时任务 + * + * @param applicationArguments / + */ + @Override + public void run(ApplicationArguments applicationArguments) { + log.info("--------------------注入定时任务---------------------"); + List quartzJobs = quartzJobRepository.findByIsPauseIsFalse(); + quartzJobs.forEach(quartzManage::addJob); + log.info("--------------------定时任务注入完成---------------------"); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/config/QuartzConfig.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/config/QuartzConfig.java new file mode 100644 index 0000000..99f2e50 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/config/QuartzConfig.java @@ -0,0 +1,52 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.config; + +import org.quartz.spi.TriggerFiredBundle; +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.quartz.AdaptableJobFactory; +import org.springframework.stereotype.Component; + +/** + * 定时任务配置 + * @author / + * @date 2019-01-07 + */ +@Configuration +public class QuartzConfig { + + /** + * 解决Job中注入Spring Bean为null的问题 + */ + @Component("quartzJobFactory") + public static class QuartzJobFactory extends AdaptableJobFactory { + + private final AutowireCapableBeanFactory capableBeanFactory; + + public QuartzJobFactory(AutowireCapableBeanFactory capableBeanFactory) { + this.capableBeanFactory = capableBeanFactory; + } + + @Override + protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { + //调用父类的方法,把Job注入到spring中 + Object jobInstance = super.createJobInstance(bundle); + capableBeanFactory.autowireBean(jobInstance); + return jobInstance; + } + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/domain/QuartzJob.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/domain/QuartzJob.java new file mode 100644 index 0000000..d4048fc --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/domain/QuartzJob.java @@ -0,0 +1,92 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.annotation.Query; +import me.zhengjie.base.BaseEntity; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * @author Zheng Jie + * @date 2019-01-07 + */ +@Getter +@Setter +@Entity +@Table(name = "sys_quartz_job") +public class QuartzJob extends BaseEntity implements Serializable { + + public static final String JOB_KEY = "JOB_KEY"; + + @Id + @Column(name = "job_id") + @NotNull(groups = {Update.class}) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** 任务编号 -雪花算法生成 */ + private Long taskNum; + + @ApiModelProperty(value = "类型 1.普通 2.影刀") + private Integer type = 1; + + @Transient + @ApiModelProperty(value = "用于子任务唯一标识", hidden = true) + private String uuid; + + @ApiModelProperty(value = "定时器名称") + private String jobName; + + @NotBlank + @ApiModelProperty(value = "Bean名称") + private String beanName; + + @NotBlank + @ApiModelProperty(value = "方法名称") + private String methodName; + + @ApiModelProperty(value = "参数") + private String params; + + @NotBlank + @ApiModelProperty(value = "cron表达式") + private String cronExpression; + + @ApiModelProperty(value = "状态,暂时或启动") + private Boolean isPause = false; + + @ApiModelProperty(value = "负责人") + private String personInCharge; + + @ApiModelProperty(value = "报警邮箱") + private String email; + + @ApiModelProperty(value = "子任务") + private String subTask; + + @ApiModelProperty(value = "失败后暂停") + private Boolean pauseAfterFailure; + + @NotBlank + @ApiModelProperty(value = "备注") + private String description; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/domain/QuartzLog.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/domain/QuartzLog.java new file mode 100644 index 0000000..4dc510b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/domain/QuartzLog.java @@ -0,0 +1,70 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.annotations.CreationTimestamp; +import javax.persistence.*; +import java.io.Serializable; +import java.sql.Timestamp; + +/** + * @author Zheng Jie + * @date 2019-01-07 + */ +@Entity +@Data +@Table(name = "sys_quartz_log") +public class QuartzLog implements Serializable { + + @Id + @Column(name = "log_id") + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ApiModelProperty(value = "任务名称", hidden = true) + private String jobName; + + @ApiModelProperty(value = "类型 1.普通 2.影刀") + private Integer type = 1; + + @ApiModelProperty(value = "bean名称", hidden = true) + private String beanName; + + @ApiModelProperty(value = "方法名称", hidden = true) + private String methodName; + + @ApiModelProperty(value = "参数", hidden = true) + private String params; + + @ApiModelProperty(value = "cron表达式", hidden = true) + private String cronExpression; + + @ApiModelProperty(value = "状态", hidden = true) + private Boolean isSuccess; + + @ApiModelProperty(value = "异常详情", hidden = true) + private String exceptionDetail; + + @ApiModelProperty(value = "执行耗时", hidden = true) + private Long time; + + @CreationTimestamp + @ApiModelProperty(value = "创建时间", hidden = true) + private Timestamp createTime; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/repository/QuartzJobRepository.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/repository/QuartzJobRepository.java new file mode 100644 index 0000000..79b222b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/repository/QuartzJobRepository.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.repository; + +import me.zhengjie.modules.quartz.domain.QuartzJob; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import java.util.List; + +/** + * @author Zheng Jie + * @date 2019-01-07 + */ +public interface QuartzJobRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 查询启用的任务 + * @return List + */ + List findByIsPauseIsFalse(); +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/repository/QuartzLogRepository.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/repository/QuartzLogRepository.java new file mode 100644 index 0000000..db724aa --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/repository/QuartzLogRepository.java @@ -0,0 +1,28 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.repository; + +import me.zhengjie.modules.quartz.domain.QuartzLog; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** + * @author Zheng Jie + * @date 2019-01-07 + */ +public interface QuartzLogRepository extends JpaRepository, JpaSpecificationExecutor { + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/rest/QuartzJobController.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/rest/QuartzJobController.java new file mode 100644 index 0000000..7a4a3db --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/rest/QuartzJobController.java @@ -0,0 +1,127 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.quartz.domain.QuartzJob; +import me.zhengjie.modules.quartz.service.QuartzJobService; +import me.zhengjie.modules.quartz.service.dto.JobQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2019-01-07 + */ +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/jobs") +@Api(tags = "系统:定时任务管理") +public class QuartzJobController { + + private static final String ENTITY_NAME = "quartzJob"; + private final QuartzJobService quartzJobService; + + @ApiOperation("查询定时任务") + @GetMapping + @PreAuthorize("@el.check('timing:list')") + public ResponseEntity query(JobQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(quartzJobService.queryAll(criteria,pageable), HttpStatus.OK); + } + + @ApiOperation("导出任务数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('timing:list')") + public void download(HttpServletResponse response, JobQueryCriteria criteria) throws IOException { + quartzJobService.download(quartzJobService.queryAll(criteria), response); + } + + @ApiOperation("导出日志数据") + @GetMapping(value = "/logs/download") + @PreAuthorize("@el.check('timing:list')") + public void downloadLog(HttpServletResponse response, JobQueryCriteria criteria) throws IOException { + quartzJobService.downloadLog(quartzJobService.queryAllLog(criteria), response); + } + + @ApiOperation("查询任务执行日志") + @GetMapping(value = "/logs") + @PreAuthorize("@el.check('timing:list')") + public ResponseEntity queryJobLog(JobQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(quartzJobService.queryAllLog(criteria,pageable), HttpStatus.OK); + } + + @Log("新增定时任务") + @ApiOperation("新增定时任务") + @PostMapping + @PreAuthorize("@el.check('timing:add')") + public ResponseEntity create(@Validated @RequestBody QuartzJob resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + quartzJobService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改定时任务") + @ApiOperation("修改定时任务") + @PutMapping + @PreAuthorize("@el.check('timing:edit')") + public ResponseEntity update(@Validated(QuartzJob.Update.class) @RequestBody QuartzJob resources){ + quartzJobService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("更改定时任务状态") + @ApiOperation("更改定时任务状态") + @PutMapping(value = "/{id}") + @PreAuthorize("@el.check('timing:edit')") + public ResponseEntity update(@PathVariable Long id){ + quartzJobService.updateIsPause(quartzJobService.findById(id)); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("执行定时任务") + @ApiOperation("执行定时任务") + @PutMapping(value = "/exec/{id}") + @PreAuthorize("@el.check('timing:edit')") + public ResponseEntity execution(@PathVariable Long id){ + quartzJobService.execution(quartzJobService.findById(id)); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除定时任务") + @ApiOperation("删除定时任务") + @DeleteMapping + @PreAuthorize("@el.check('timing:del')") + public ResponseEntity delete(@RequestBody Set ids){ + quartzJobService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/QuartzJobService.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/QuartzJobService.java new file mode 100644 index 0000000..7be008e --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/QuartzJobService.java @@ -0,0 +1,128 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.service; + +import me.zhengjie.modules.quartz.domain.QuartzJob; +import me.zhengjie.modules.quartz.domain.QuartzLog; +import me.zhengjie.modules.quartz.service.dto.JobQueryCriteria; +import org.springframework.data.domain.Pageable; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2019-01-07 + */ +public interface QuartzJobService { + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(JobQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部 + * @param criteria 条件 + * @return / + */ + List queryAll(JobQueryCriteria criteria); + + /** + * 查询全部 + * @return / + */ + void delAllLog(); + + /** + * 分页查询日志 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAllLog(JobQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部 + * @param criteria 条件 + * @return / + */ + List queryAllLog(JobQueryCriteria criteria); + + /** + * 创建 + * @param resources / + */ + void create(QuartzJob resources); + + /** + * 编辑 + * @param resources / + */ + void update(QuartzJob resources); + + /** + * 删除任务 + * @param ids / + */ + void delete(Set ids); + + /** + * 根据ID查询 + * @param id ID + * @return / + */ + QuartzJob findById(Long id); + + /** + * 更改定时任务状态 + * @param quartzJob / + */ + void updateIsPause(QuartzJob quartzJob); + + /** + * 立即执行定时任务 + * @param quartzJob / + */ + void execution(QuartzJob quartzJob); + + /** + * 导出定时任务 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 导出定时任务日志 + * @param queryAllLog 待导出的数据 + * @param response / + * @throws IOException / + */ + void downloadLog(List queryAllLog, HttpServletResponse response) throws IOException; + + /** + * 执行子任务 + * @param tasks / + * @throws InterruptedException / + */ + void executionSubJob(String[] tasks) throws InterruptedException; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/SysQuartzJobService.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/SysQuartzJobService.java new file mode 100644 index 0000000..d2a58f1 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/SysQuartzJobService.java @@ -0,0 +1,77 @@ +package me.zhengjie.modules.quartz.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.SysQuartzJob; +import me.zhengjie.modules.group.dto.SysQuartzJobAddDTO; +import me.zhengjie.modules.group.dto.SysQuartzJobUpdateDTO; +import me.zhengjie.service.vo.SysQuartzJobListVO; +import me.zhengjie.utils.PageUtils; + +/** + * 定时任务(SysQuartzJob)表服务接口 + * + * @author zhw + * @since 2022-07-21 + */ +public interface SysQuartzJobService extends IService { + + PageUtils searchPageList(IPage page, Wrapper wrapper); + + /** + * 根据任务id修改任务运行状态 + * @param jobId + * @return boolean + */ + Boolean modifyJobStatus(Long jobId); + + /** + * 根据任务id修改任务信息 + * @param dto + * @return boolean + */ + Dto updateQuartzJobById(SysQuartzJobUpdateDTO dto); + + /** + * 根据任务id删除影刀任务 + * @param id + * @return boolean + */ + Boolean deleteQuartzJobById(Long id); + + /** + * 重新新建任务-为了任务失败做的 + * @param sysQuartzJob + * @return + */ + public Boolean reAddQuartzJob(SysQuartzJob sysQuartzJob); + + /** + * 新增影刀任务信息 + * @param dto + * @return boolean + */ + Dto addQuartzJob(SysQuartzJobAddDTO dto); + + /** + * 执行影刀任务信息 + * @param id + * @return boolean + */ + Boolean executionById(Long id); + + /** + * 根据刷单item拼装参数 + */ + String assemblyParamAccordingToItem(String params, String taskName, Long taskNum); + + /** + * 更加任务编号获取任务信息 + * @param taskNum + * @return + */ + SysQuartzJob getByTaskNum(String taskNum); +} + diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/dto/JobQueryCriteria.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/dto/JobQueryCriteria.java new file mode 100644 index 0000000..89d8070 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/dto/JobQueryCriteria.java @@ -0,0 +1,41 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** + * @author Zheng Jie + * @date 2019-6-4 10:33:02 + */ +@Data +public class JobQueryCriteria { + + @Query(type = Query.Type.INNER_LIKE) + private String jobName; + + @Query + private Boolean isSuccess; + + @Query + private Integer type = 1; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/impl/QuartzJobServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/impl/QuartzJobServiceImpl.java new file mode 100644 index 0000000..35c6070 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/impl/QuartzJobServiceImpl.java @@ -0,0 +1,205 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.service.impl; + +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import lombok.RequiredArgsConstructor; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.quartz.domain.QuartzJob; +import me.zhengjie.modules.quartz.domain.QuartzLog; +import me.zhengjie.modules.quartz.repository.QuartzJobRepository; +import me.zhengjie.modules.quartz.repository.QuartzLogRepository; +import me.zhengjie.modules.quartz.service.QuartzJobService; +import me.zhengjie.modules.quartz.service.dto.JobQueryCriteria; +import me.zhengjie.modules.quartz.utils.QuartzManage; +import me.zhengjie.utils.*; +import org.quartz.CronExpression; +import org.springframework.data.domain.Pageable; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** + * @author Zheng Jie + * @date 2019-01-07 + */ +@RequiredArgsConstructor +@Service(value = "quartzJobService") +public class QuartzJobServiceImpl implements QuartzJobService { + + private final QuartzJobRepository quartzJobRepository; + private final QuartzLogRepository quartzLogRepository; + private final QuartzManage quartzManage; + private final RedisUtils redisUtils; + private final Snowflake snowflake; + + @Override + public Object queryAll(JobQueryCriteria criteria, Pageable pageable){ + return PageUtil.toPage(quartzJobRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable)); + } + + @Override + public Object queryAllLog(JobQueryCriteria criteria, Pageable pageable){ + return PageUtil.toPage(quartzLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable)); + } + + @Override + public List queryAll(JobQueryCriteria criteria) { + return quartzJobRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)); + } + + @Override + public void delAllLog() { + quartzLogRepository.deleteAll(); + } + + @Override + public List queryAllLog(JobQueryCriteria criteria) { + return quartzLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)); + } + + @Override + public QuartzJob findById(Long id) { + QuartzJob quartzJob = quartzJobRepository.findById(id).orElseGet(QuartzJob::new); + ValidationUtil.isNull(quartzJob.getId(),"QuartzJob","id",id); + return quartzJob; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(QuartzJob resources) { + if (!CronExpression.isValidExpression(resources.getCronExpression())){ + throw new BadRequestException("cron表达式格式错误"); + } + resources.setTaskNum(snowflake.nextId()); + resources = quartzJobRepository.save(resources); + quartzManage.addJob(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(QuartzJob resources) { + if (!CronExpression.isValidExpression(resources.getCronExpression())){ + throw new BadRequestException("cron表达式格式错误"); + } + if(StringUtils.isNotBlank(resources.getSubTask())){ + List tasks = Arrays.asList(resources.getSubTask().split("[,,]")); + if (tasks.contains(resources.getId().toString())) { + throw new BadRequestException("子任务中不能添加当前任务ID"); + } + } + resources = quartzJobRepository.save(resources); + quartzManage.updateJobCron(resources); + } + + @Override + public void updateIsPause(QuartzJob quartzJob) { + if (quartzJob.getIsPause()) { + quartzManage.resumeJob(quartzJob); + quartzJob.setIsPause(false); + } else { + quartzManage.pauseJob(quartzJob); + quartzJob.setIsPause(true); + } + quartzJobRepository.save(quartzJob); + } + + @Override + public void execution(QuartzJob quartzJob) { + quartzManage.runJobNow(quartzJob); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + for (Long id : ids) { + QuartzJob quartzJob = findById(id); + quartzManage.deleteJob(quartzJob); + quartzJobRepository.delete(quartzJob); + } + } + + @Async + @Override + @Transactional(rollbackFor = Exception.class) + public void executionSubJob(String[] tasks) throws InterruptedException { + for (String id : tasks) { + if (StrUtil.isBlank(id)) { + // 如果是手动清除子任务id,会出现id为空字符串的问题 + continue; + } + QuartzJob quartzJob = findById(Long.parseLong(id)); + // 执行任务 + String uuid = IdUtil.simpleUUID(); + quartzJob.setUuid(uuid); + // 执行任务 + execution(quartzJob); + // 获取执行状态,如果执行失败则停止后面的子任务执行 + Boolean result = (Boolean) redisUtils.get(uuid); + while (result == null) { + // 休眠5秒,再次获取子任务执行情况 + Thread.sleep(5000); + result = (Boolean) redisUtils.get(uuid); + } + if(!result){ + redisUtils.del(uuid); + break; + } + } + } + + @Override + public void download(List quartzJobs, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (QuartzJob quartzJob : quartzJobs) { + Map map = new LinkedHashMap<>(); + map.put("任务名称", quartzJob.getJobName()); + map.put("Bean名称", quartzJob.getBeanName()); + map.put("执行方法", quartzJob.getMethodName()); + map.put("参数", quartzJob.getParams()); + map.put("表达式", quartzJob.getCronExpression()); + map.put("状态", quartzJob.getIsPause() ? "暂停中" : "运行中"); + map.put("描述", quartzJob.getDescription()); + map.put("创建日期", quartzJob.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + @Override + public void downloadLog(List queryAllLog, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (QuartzLog quartzLog : queryAllLog) { + Map map = new LinkedHashMap<>(); + map.put("任务名称", quartzLog.getJobName()); + map.put("Bean名称", quartzLog.getBeanName()); + map.put("执行方法", quartzLog.getMethodName()); + map.put("参数", quartzLog.getParams()); + map.put("表达式", quartzLog.getCronExpression()); + map.put("异常详情", quartzLog.getExceptionDetail()); + map.put("耗时/毫秒", quartzLog.getTime()); + map.put("状态", quartzLog.getIsSuccess() ? "成功" : "失败"); + map.put("创建日期", quartzLog.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/impl/SysQuartzJobServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/impl/SysQuartzJobServiceImpl.java new file mode 100644 index 0000000..45b09bd --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/service/impl/SysQuartzJobServiceImpl.java @@ -0,0 +1,521 @@ +package me.zhengjie.modules.quartz.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.RequiredArgsConstructor; +import me.zhengjie.config.SystemConfig; +import me.zhengjie.dao.SysQuartzJobDao; +import me.zhengjie.dto.Dto; +import me.zhengjie.entity.*; +import me.zhengjie.entity.quartz.Boss; +import me.zhengjie.entity.quartz.Param; +import me.zhengjie.entity.quartz.Params; +import me.zhengjie.enums.*; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.group.dto.SysQuartzJobAddDTO; +import me.zhengjie.modules.group.dto.SysQuartzJobUpdateDTO; +import me.zhengjie.modules.quartz.domain.QuartzJob; +import me.zhengjie.modules.quartz.service.QuartzJobService; +import me.zhengjie.modules.quartz.service.SysQuartzJobService; +import me.zhengjie.modules.quartz.utils.QuartzManage; +import me.zhengjie.service.*; +import me.zhengjie.service.vo.CtBrowseDetailVO; +import me.zhengjie.service.vo.SysQuartzJobListVO; +import me.zhengjie.service.vo.dhaddcar.DhAddCarListVO; +import me.zhengjie.service.vo.dhaddcar.DhAddCarYdParamsVO; +import me.zhengjie.service.vo.dhcargood.DhCarGoodKeyVO; +import me.zhengjie.service.vo.dhcargood.DhCarGoodLinkVO; +import me.zhengjie.service.vo.dhcarorder.DhCarOrderParamsVO; +import me.zhengjie.utils.PageUtils; +import me.zhengjie.utils.StringUtils; +import org.quartz.CronExpression; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 定时任务(SysQuartzJob)表服务实现类 + * + * @author rch + * @since 2022-07-20 + */ +@Service +@RequiredArgsConstructor +public class SysQuartzJobServiceImpl extends ServiceImpl implements SysQuartzJobService { + + @Resource + private SysQuartzJobDao sysQuartzJobDao; + @Resource + private QuartzJobService quartzJobService; + @Resource + private CtApplyService ctApplyService; + @Resource + private CtClickFarmingService ctClickFarmingService; + @Resource + private DhAddCarService dhAddCarService; + @Resource + private DhAddCarOrderService dhAddCarOrderService; + @Resource + private CtClickOrderService ctClickOrderService; + @Resource + private CtBrowseService ctBrowseService; + private final QuartzManage quartzManage; + + @Override + public PageUtils searchPageList(IPage page, Wrapper wrapper) { + sysQuartzJobDao.searchPageList(page, wrapper); + return new PageUtils(page.getTotal(), page.getRecords()); + } + + @Override + public Boolean modifyJobStatus(Long jobId) { + SysQuartzJob sysQuartzJobIsExist = getById(jobId); + if (sysQuartzJobIsExist == null) { + return false; + } else { + QuartzJob quartzJob = new QuartzJob(); + BeanUtil.copyProperties(sysQuartzJobIsExist, quartzJob); + quartzJob.setId(sysQuartzJobIsExist.getJobId()); + + quartzJob.setType(TaskTypeEnum.SHADOW_KNIFE.value()); + SysQuartzJob updateSysQuartzJob = new SysQuartzJob(); + updateSysQuartzJob.setJobId(jobId); + + if (sysQuartzJobIsExist.getIsPause() == 1) { + quartzManage.resumeJob(quartzJob); + updateSysQuartzJob.setIsPause(0); + } else { + quartzManage.pauseJob(quartzJob); + updateSysQuartzJob.setIsPause(1); + } + return updateById(updateSysQuartzJob); + } + } + + @Override + public Dto updateQuartzJobById(SysQuartzJobUpdateDTO dto) { + SysQuartzJob sysQuartzJob = getById(dto.getJobId()); + if (sysQuartzJob == null) { + return Dto.getInstance(ErrorCodeEnum.ERROR_NOT_FIND_JOB); + } + if (!CronExpression.isValidExpression(dto.getCronExpression())) { + //hrow new BadRequestException("cron表达式格式错误"); + return Dto.returnErrorResult("cron表达式格式错误"); + } + if (StringUtils.isNotBlank(dto.getSubTask())) { + List tasks = Arrays.asList(dto.getSubTask().split("[,,]")); + if (tasks.contains(dto.getJobId().toString())) { + //throw new BadRequestException("子任务中不能添加当前任务ID"); + return Dto.returnErrorResult("子任务中不能添加当前任务ID"); + } + } + SysQuartzJob updateSysQuartzJob = new SysQuartzJob(); + + updateSysQuartzJob.setJobId(dto.getJobId()); + BeanUtil.copyProperties(dto, updateSysQuartzJob); + CtApply ctApply = ctApplyService.getById(dto.getApplyId()); + updateSysQuartzJob.setBeanName(ctApply.getTaskName()); + updateSysQuartzJob.setMethodName(ctApply.getMethodName()); + updateSysQuartzJob.setUpdateTime(DateUtil.now()); + + + QuartzJob quartzJob = new QuartzJob(); + BeanUtil.copyProperties(updateSysQuartzJob, quartzJob); + quartzJob.setId(dto.getJobId()); + quartzJob.setType(TaskTypeEnum.SHADOW_KNIFE.value()); + + quartzManage.updateJobCron(quartzJob); + return Dto.returnResult(updateById(updateSysQuartzJob)); + } + + + @Override + public Boolean deleteQuartzJobById(Long id) { + QuartzJob quartzJob = quartzJobService.findById(id); + quartzManage.deleteJob(quartzJob); + return removeById(id); + } + + @Override + public Dto addQuartzJob(SysQuartzJobAddDTO dto) { + if (!CronExpression.isValidExpression(dto.getCronExpression())) { + //throw new BadRequestException("cron表达式格式错误"); + return Dto.returnErrorResult("cron表达式格式错误"); + } + SysQuartzJob sysQuartzJob = new SysQuartzJob(); + BeanUtil.copyProperties(dto, sysQuartzJob); + ; + sysQuartzJob.setCreateTime(DateUtil.now()); + sysQuartzJob.setType(TaskTypeEnum.SHADOW_KNIFE.value()); + CtApply ctApply = ctApplyService.getById(dto.getApplyId()); + sysQuartzJob.setBeanName(ctApply.getTaskName()); + sysQuartzJob.setMethodName(ctApply.getMethodName()); + + QuartzJob quartzJob = new QuartzJob(); + quartzJob.setType(TaskTypeEnum.SHADOW_KNIFE.value()); + Boolean returnBoolean = save(sysQuartzJob); + if (returnBoolean) { + BeanUtil.copyProperties(sysQuartzJob, quartzJob); + quartzJob.setId(sysQuartzJob.getJobId()); + quartzManage.addJob(quartzJob); + } + //return returnBoolean; + return Dto.returnResult(returnBoolean); + } + + @Override + public Boolean reAddQuartzJob(SysQuartzJob sysQuartzJob) { + if (!CronExpression.isValidExpression(sysQuartzJob.getCronExpression())) { + throw new BadRequestException("cron表达式格式错误"); + } + sysQuartzJob.setCreateTime(DateUtil.now()); + QuartzJob quartzJob = new QuartzJob(); + quartzJob.setType(TaskTypeEnum.SHADOW_KNIFE.value()); + Boolean returnBoolean = save(sysQuartzJob); + if (returnBoolean) { + BeanUtil.copyProperties(sysQuartzJob, quartzJob); + quartzJob.setId(sysQuartzJob.getJobId()); + quartzManage.addJob(quartzJob); + } + return returnBoolean; + } + + @Override + public Boolean executionById(Long id) { + QuartzJob quartzJob = quartzJobService.findById(id); + quartzManage.runJobNow(quartzJob); + return true; + } + + @Override + public String assemblyParamAccordingToItem(String params, String taskName, Long taskNum) { + if (StringUtils.isEmpty(params) || StringUtils.isEmpty(taskName)) { + return null; + } + // 测试的第一个应用 刷单 拼装params + if (TaskInfoEnum.CLICK_FARMING.getTaskName().equals(taskName)) { + // 刷单 + Params paramsObj = JSONUtil.toBean(params, Params.class); + Boss bossObj = JSONUtil.toBean(params, Boss.class); + CtClickFarming ctClickFarming = ctClickFarmingService.getByIdLock(Long.valueOf(paramsObj.getParams())); + if (ObjectUtil.isEmpty(ctClickFarming)) { + return null; + // 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 5.待支付 + } else if (ClickFarmingStatusEnum.IN_EXECUTION.value().equals(ctClickFarming.getStatus()) || ClickFarmingStatusEnum.EXECUTION_SUCCESS.value().equals(ctClickFarming.getStatus())) { + return null; + } else { + // 关联查询 得到对应传值任务参数 不特殊处理统一返回好了,影刀脚本那边自行判断 + CtClickFarmYdParams ctClickFarmYdParams = ctClickFarmingService.getCtClickFarmYdParams(Long.valueOf(paramsObj.getParams())); + if (ObjectUtil.isEmpty(ctClickFarmYdParams)) { + log.error("根据刷单id关联查询相关信息空值异常!!!"); + return null; + } + List paramList = new ArrayList<>(); + Map maps = BeanUtil.beanToMap(ctClickFarmYdParams); + maps.entrySet().removeIf(entry -> entry.getValue() == null); + + for (Map.Entry map : maps.entrySet()) { + Param ydParam = new Param(); + ydParam.setName(map.getKey()); + ydParam.setValue(map.getValue().toString()); + paramList.add(ydParam); + } + + if (ObjectUtil.isNotEmpty(taskNum)) { + Param ydParam = new Param(); + ydParam.setName("taskNum"); + ydParam.setValue(taskNum.toString()); + paramList.add(ydParam); + } + + // 组装Params + bossObj.setParams(paramList); + return JSONUtil.toJsonStr(bossObj); + } + } else if (TaskInfoEnum.DH_ADD_CAR_FARMING.getTaskName().equals(taskName)) { + // 敦煌 加购 + Params paramsObj = JSONUtil.toBean(params, Params.class); + Boss bossObj = JSONUtil.toBean(params, Boss.class); + DhAddCar dhAddCar = dhAddCarService.getByIdLock(Long.valueOf(paramsObj.getParams())); + if (ObjectUtil.isEmpty(dhAddCar)) { + return null; + } else if (!ClickFarmingStatusEnum.TOBE_EXECUTION.value().equals(dhAddCar.getStatus()) && !ClickFarmingStatusEnum.EXECUTION_FAILE.value().equals(dhAddCar.getStatus())) { + return null; + } else { + // 关联查询 得到对应传值任务参数 不特殊处理统一返回好了,影刀脚本那边自行判断 + DhAddCarYdParamsVO dhAddCarYdParamsVO = dhAddCarService.getAddCarYdParams(Long.valueOf(paramsObj.getParams())); + if (ObjectUtil.isEmpty(dhAddCarYdParamsVO)) { + log.error("根据刷单id关联查询相关信息空值异常!!!"); + return null; + } + List paramList = new ArrayList<>(); + Map maps = BeanUtil.beanToMap(dhAddCarYdParamsVO); + maps.entrySet().removeIf(entry -> entry.getValue() == null); + + for (Map.Entry map : maps.entrySet()) { + Param ydParam = new Param(); + String value = null; + // 特殊处理 + if ("carGoodKeys".equals(map.getKey()) || "carGoodLinks".equals(map.getKey())) { + Object carGoodKeysObj = map.getValue(); + value = JSONUtil.parseArray(carGoodKeysObj).toString(); + } else { + value = map.getValue().toString(); + } + + ydParam.setName(map.getKey()); + ydParam.setValue(value); + paramList.add(ydParam); + } + + if (ObjectUtil.isNotEmpty(taskNum)) { + Param ydParam = new Param(); + ydParam.setName("taskNum"); + ydParam.setValue(taskNum.toString()); + paramList.add(ydParam); + } + + // 组装Params + bossObj.setParams(paramList); + return JSONUtil.toJsonStr(bossObj); + } + } else if (TaskInfoEnum.DH_ADD_CAR_CATCH_ORDER.getTaskName().equals(taskName)) { + // 敦煌 - 抓单 + Params paramsObj = JSONUtil.toBean(params, Params.class); + Boss bossObj = JSONUtil.toBean(params, Boss.class); + DhAddCar dhAddCar = dhAddCarService.getByIdLock(Long.valueOf(paramsObj.getParams())); + if (ObjectUtil.isEmpty(dhAddCar)) { + return null; + } else if (!DhAddCarStatusEnum.TO_BE_CATCH_ORDER.value().equals(dhAddCar.getStatus()) && !DhAddCarStatusEnum.CATCH_ORDER_FAILE.value().equals(dhAddCar.getStatus())) { + return null; + } else { + // 关联查询 得到对应传值任务参数 不特殊处理统一返回好了,影刀脚本那边自行判断 + DhAddCarYdParamsVO dhAddCarYdParamsVO = dhAddCarService.getAddCarYdParams(Long.valueOf(paramsObj.getParams())); + if (ObjectUtil.isEmpty(dhAddCarYdParamsVO)) { + log.error("根据刷单id关联查询相关信息空值异常!!!"); + return null; + } + List paramList = new ArrayList<>(); + Map maps = BeanUtil.beanToMap(dhAddCarYdParamsVO); + maps.entrySet().removeIf(entry -> entry.getValue() == null); + + for (Map.Entry map : maps.entrySet()) { + Param ydParam = new Param(); + String value = null; + // 特殊处理 + if ("carGoodKeys".equals(map.getKey()) || "carGoodLinks".equals(map.getKey())) { + Object carGoodKeysObj = map.getValue(); + value = JSONUtil.parseArray(carGoodKeysObj).toString(); + } else { + value = map.getValue().toString(); + } + + ydParam.setName(map.getKey()); + ydParam.setValue(value); + paramList.add(ydParam); + } + + if (ObjectUtil.isNotEmpty(taskNum)) { + Param ydParam = new Param(); + ydParam.setName("taskNum"); + ydParam.setValue(taskNum.toString()); + paramList.add(ydParam); + } + // 组装Params + bossObj.setParams(paramList); + return JSONUtil.toJsonStr(bossObj); + } + } else if (TaskInfoEnum.CLICK_FARMING_SUPPLE_MENY.getTaskName().equals(taskName)) { + // 补录 + Params paramsObj = JSONUtil.toBean(params, Params.class); + Boss bossObj = JSONUtil.toBean(params, Boss.class); + CtClickFarming ctClickFarming = ctClickFarmingService.getByIdLock(Long.valueOf(paramsObj.getParams())); + if (ObjectUtil.isEmpty(ctClickFarming)) { + return null; + // 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 5.待支付 + } else if (ClickFarmingStatusEnum.IN_EXECUTION.value().equals(ctClickFarming.getStatus()) || ClickFarmingStatusEnum.EXECUTION_SUCCESS.value().equals(ctClickFarming.getStatus())) { + return null; + } else { + CtClickFarmYdParams ctClickFarmYdParams = ctClickFarmingService.getCtClickFarmYdParams(Long.valueOf(paramsObj.getParams())); + if (ObjectUtil.isEmpty(ctClickFarmYdParams)) { + log.error("根据刷单id关联查询相关信息空值异常!!!"); + return null; + } + CtClickFarmSupplyMentYdParams ctClickFarmSupplyMentYdParams = new CtClickFarmSupplyMentYdParams(); + BeanUtil.copyProperties(ctClickFarmYdParams, ctClickFarmSupplyMentYdParams); + + List paramList = new ArrayList<>(); + Map maps = BeanUtil.beanToMap(ctClickFarmSupplyMentYdParams); + maps.entrySet().removeIf(entry -> entry.getValue() == null); + for (Map.Entry map : maps.entrySet()) { + Param ydParam = new Param(); + ydParam.setName(map.getKey()); + ydParam.setValue(map.getValue().toString()); + paramList.add(ydParam); + } + + // 组装Params + bossObj.setParams(paramList); + return JSONUtil.toJsonStr(bossObj); + } + } else if (TaskInfoEnum.WELL_RECEIVED.getTaskName().equals(taskName)) { + // 速卖通好评 + Params paramsObj = JSONUtil.toBean(params, Params.class); + Boss bossObj = JSONUtil.toBean(params, Boss.class); + CtClickOrder ctClickOrder = ctClickOrderService.getByIdLock(Long.valueOf(paramsObj.getParams())); + if (ObjectUtil.isEmpty(ctClickOrder)) { + return null; + // 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 5.待支付 + } else if (ClickOrderStatusEnum.IN_EXECUTION.value().equals(ctClickOrder.getStatus()) || ClickFarmingStatusEnum.EXECUTION_SUCCESS.value().equals(ctClickOrder.getStatus())) { + return null; + } else { + CtClickOrderYdParams ctClickOrderYdParams = new CtClickOrderYdParams(); + CtClickFarmingOrderInfo ctClickFarmingOrderInfo = ctClickOrderService.getClickFarmOrderById(Long.valueOf(paramsObj.getParams())); + if (ObjectUtil.isEmpty(ctClickFarmingOrderInfo)) { + log.error("根据刷单id关联查询相关信息空值异常!!!"); + return null; + } + BeanUtil.copyProperties(ctClickFarmingOrderInfo, ctClickOrderYdParams); + String paths = joinPath(ctClickOrderYdParams.getPaths()); + if (ObjectUtil.isNotEmpty(paths)) { + ctClickOrderYdParams.setPaths(paths); + } + List paramList = new ArrayList<>(); + Map maps = BeanUtil.beanToMap(ctClickOrderYdParams); + maps.entrySet().removeIf(entry -> entry.getValue() == null); + + for (Map.Entry map : maps.entrySet()) { + Param ydParam = new Param(); + ydParam.setName(map.getKey()); + ydParam.setValue(map.getValue().toString()); + paramList.add(ydParam); + } + + // 组装Params + bossObj.setParams(paramList); + return JSONUtil.toJsonStr(bossObj); + } + } else if (TaskInfoEnum.DH_WELL_RECEIVED.getTaskName().equals(taskName)) { + // TODO 敦煌好评 + Params paramsObj = JSONUtil.toBean(params, Params.class); + Boss bossObj = JSONUtil.toBean(params, Boss.class); + DhAddCarOrder dhAddCarOrder = dhAddCarOrderService.getByIdLock(Long.valueOf(paramsObj.getParams())); + if (ObjectUtil.isEmpty(dhAddCarOrder)) { + return null; + // 状态 1.抓单成功才允许 好评 + } else if (!ClickOrderStatusEnum.TOBE_EXECUTION.value().equals(dhAddCarOrder.getStatus()) && !ClickOrderStatusEnum.EXECUTION_FAILE.value().equals(dhAddCarOrder.getStatus())) { + return null; + } else { + + // TODO 拼装好评数据 + DhCarOrderParamsVO dhCarOrderParamsVO = dhAddCarOrderService.getYdParams(Long.valueOf(paramsObj.getParams())); + if (ObjectUtil.isEmpty(dhCarOrderParamsVO)) { + log.error("根据刷单id关联查询相关信息空值异常!!!"); + return null; + } + joinImagePath(dhCarOrderParamsVO); + List paramList = new ArrayList<>(); + Map maps = BeanUtil.beanToMap(dhCarOrderParamsVO); + maps.entrySet().removeIf(entry -> entry.getValue() == null); + + for (Map.Entry map : maps.entrySet()) { + Param ydParam = new Param(); + String value = null; + // 特殊处理 + if ("carGoodKeys".equals(map.getKey()) || "carGoodLinks".equals(map.getKey())) { + Object carGoodKeysObj = map.getValue(); + value = JSONUtil.parseArray(carGoodKeysObj).toString(); + } else { + value = map.getValue().toString(); + } + + ydParam.setName(map.getKey()); + ydParam.setValue(value); + paramList.add(ydParam); + } + + // 组装Params + bossObj.setParams(paramList); + return JSONUtil.toJsonStr(bossObj); + } + } else if (TaskInfoEnum.BROWSE.getTaskName().equals(taskName)) { + // 浏览收藏 + Params paramsObj = JSONUtil.toBean(params, Params.class); + Boss bossObj = JSONUtil.toBean(params, Boss.class); + CtBrowse ctBrowse = ctBrowseService.getByIdLock(Long.valueOf(paramsObj.getParams())); + if (ObjectUtil.isEmpty(ctBrowse)) { + return null; + // 状态 1.待执行 2.执行中 3.执行成功 4.执行失败 5.待支付 + } else if (ClickOrderStatusEnum.IN_EXECUTION.value().equals(ctBrowse.getStatus()) || ClickFarmingStatusEnum.EXECUTION_SUCCESS.value().equals(ctBrowse.getStatus())) { + return null; + } else { + // TODO 好评浏览 待修改 + CtBrowseYdParams ctBrowseYdParams = new CtBrowseYdParams(); + CtBrowseDetailVO ctBrowseDetailVO = ctBrowseService.getBrowseDetailById(Long.valueOf(paramsObj.getParams())); + BeanUtil.copyProperties(ctBrowseDetailVO, ctBrowseYdParams); + List paramList = new ArrayList<>(); + Map maps = BeanUtil.beanToMap(ctBrowseYdParams); + maps.entrySet().removeIf(entry -> entry.getValue() == null); + + for (Map.Entry map : maps.entrySet()) { + Param ydParam = new Param(); + ydParam.setName(map.getKey()); + ydParam.setValue(map.getValue().toString()); + paramList.add(ydParam); + } + + // 组装Params + bossObj.setParams(paramList); + return JSONUtil.toJsonStr(bossObj); + } + } else { + return null; + } + } + + private void joinImagePath(DhCarOrderParamsVO dhCarOrderParamsVO) { + if (ParamsTypeEnum.KEY_WORD.eqValue(dhCarOrderParamsVO.getParamsType()) && ObjectUtil.isNotEmpty(dhCarOrderParamsVO.getCarGoodKeys())) { + for (DhCarGoodKeyVO dhCarGoodKeyVO:dhCarOrderParamsVO.getCarGoodKeys()) { + String paths = dhCarGoodKeyVO.getPaths(); + dhCarGoodKeyVO.setPaths(joinPath(paths)); + } + } else if (ParamsTypeEnum.LINK.eqValue(dhCarOrderParamsVO.getParamsType()) && ObjectUtil.isNotEmpty(dhCarOrderParamsVO.getCarGoodLinks())) { + for (DhCarGoodLinkVO dhCarGoodLinkVO:dhCarOrderParamsVO.getCarGoodLinks()) { + String paths = dhCarGoodLinkVO.getPaths(); + dhCarGoodLinkVO.setPaths(joinPath(paths)); + } + } else { + return ; + } + } + + /** + * 拼接域名 + * @param paths + * @return + */ + private String joinPath(String paths) { + if (ObjectUtil.isEmpty(paths)) { + return null; + } + List pathList = Arrays.asList(paths.split(",")); + return pathList.stream().map(s -> s = SystemConfig.FILE_VISIT_ADDR + s).collect(Collectors.joining(",")); + } + + @Override + public SysQuartzJob getByTaskNum(String taskNum) { + return sysQuartzJobDao.getByTaskNum(taskNum); + } +} + diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/BossTask.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/BossTask.java new file mode 100644 index 0000000..85c0202 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/BossTask.java @@ -0,0 +1,51 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.entity.quartz.Boss; +import me.zhengjie.service.YdQuartzService; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 测试用-Boss查询岗位 + * @author rch + * @date 2022-07-23 + */ +@Slf4j +@Component +public class BossTask { + + @Resource + private YdQuartzService ydQuartzService; + + public void run(String str) throws Exception { + Boss boss = JSONUtil.toBean(str, Boss.class); + String REBOT_KEY = PublicConstant.getRebotKeyPrefix(boss.getAccountName()); + ydQuartzService.executeOnLock(REBOT_KEY, 1, 1, callBack -> { + try { + return ydQuartzService.exec(str); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } +} + diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/BossTask22.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/BossTask22.java new file mode 100644 index 0000000..4adf48b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/BossTask22.java @@ -0,0 +1,165 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.config.YdApiProperties; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.entity.CtRebot; +import me.zhengjie.entity.quartz.Boss; +import me.zhengjie.entity.quartz.RebotStatu; +import me.zhengjie.entity.quartz.RebotStatuReturn; +import me.zhengjie.entity.quartz.SecreInfo; +import me.zhengjie.enums.YesOrNoEnum; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.service.CtRebotService; +import me.zhengjie.service.redission.LockCallBack; +import me.zhengjie.utils.HttpClientUtil; +import me.zhengjie.utils.RedissonUtil; +import org.redisson.api.RLock; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * 测试用-Boss查询岗位 + * @author rch + * @date 2022-07-23 + */ +@Slf4j +@Component +public class BossTask22 { + + @Resource + private CtRebotService ctRebotService; + @Resource + private RedissonUtil redissonUtil; + + public final static String REBOT_STATU = "https://api.winrobot360.com/oapi/dispatch/v2/client/query"; + public final static String GET_SECRET = "https://api.winrobot360.com/oapi/token/v2/token/create"; + public final static String STAT_JOB_URL = "https://api.winrobot360.com/oapi/dispatch/v2/job/start"; + + // 测试保证指执行一次 + public static Integer number = 0; + + public void run(){ + try { + Thread.sleep(5000); + log.info("run 执行成功====time:" + DateUtil.now()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + log.info("run---end!"); + } + + public void run2(String str){ + + number ++; + Boss boss = JSONUtil.toBean(str, Boss.class); + String REBOT_KEY = PublicConstant.getRebotKeyPrefix(boss.getAccountName()); + try { + executeOnLock(REBOT_KEY, 1, 1, callBack -> exec(str)); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public void run1(){ + log.info("run2 执行成功"); + } + + Object executeOnLock(String lockKey, long time, long timeout, LockCallBack callBack) throws BadRequestException,InterruptedException { + RLock lock = redissonUtil.getRLock(lockKey); + String currentTime = me.zhengjie.utils.DateUtil.getCurrentTime(); + try { + log.info(currentTime+" 获取锁============= {}",lockKey); + if (lock.tryLock(time, timeout, TimeUnit.SECONDS)) { + System.out.println(" run2 ====== lock success"); + return callBack.execute(true); + } else { + System.out.println(" run2 ====== lock fail "); + throw new BadRequestException(" run2 ====== lock fail "); + } + } catch (InterruptedException e) { + throw e; + } finally { + lock.unlock(); + log.info(currentTime+" 释放锁============= {}",lockKey); + } + } + + public Boolean exec(String str) { + Boss boss = JSONUtil.toBean(str, Boss.class); + // 1.根据设备id获取设备信息 for update + CtRebot ctRebot = ctRebotService.getByAccountNameLock(boss.getAccountName()); + System.out.println("run2================================"); + System.out.println(JSONUtil.toJsonStr(ctRebot)); + if (ObjectUtil.isEmpty(ctRebot) || !YesOrNoEnum.NO.eqValue(ctRebot.getStatus())) { + // 有问题 不执行 + log.info("run2 执行成功 - 结束了,设备信息问题,参数为: {}" + str); + return false; + } + + // token + Map params = new HashMap<>(16); + params.put("accessKeyId", YdApiProperties.ACCESS_KEY_ID); + params.put("accessKeySecret", YdApiProperties.ACCESS_KEY_SECRET); + String secretStr = HttpClientUtil.getHttp(GET_SECRET, params); + SecreInfo secreInfo = JSONUtil.toBean(secretStr, SecreInfo.class); + if (!secreInfo.getSuccess()) { + log.info("=========鉴权异常=========="); + return false; + } + String token = secreInfo.getData().getAccessToken(); + Map headers = new HashMap<>(16); + headers.put("Accept", "application/json"); + headers.put("Content-Type", "application/json;charset=utf-8"); + headers.put("authorization", "Bearer " + token); + + // 判断是否在线 + RebotStatu rebotStatu = new RebotStatu(); + rebotStatu.setAccountName(ctRebot.getAccountName()); + rebotStatu.setRobotClientUuid(ctRebot.getRobotClientUuid()); + String returnStr = HttpClientUtil.postJson(REBOT_STATU, headers, JSONUtil.toJsonStr(rebotStatu), "utf-8"); + RebotStatuReturn rebotStatuReturn = JSONUtil.toBean(returnStr, RebotStatuReturn.class); + if ("offline".equals(rebotStatuReturn.getData().getStatus())) { + log.info("=======设备不在线====="); + return false; + } + + // 修改机器人状态 + CtRebot updateCtRebot = new CtRebot(); + updateCtRebot.setId(ctRebot.getId()); + updateCtRebot.setStatus(YesOrNoEnum.YES.value()); + Boolean resultBoolean = ctRebotService.updateById(updateCtRebot); + if (resultBoolean) { + String returnJobStr = HttpClientUtil.postJson(STAT_JOB_URL, headers, JSONUtil.toJsonStr(boss), "utf-8"); + log.info("run2 执行成功,返回结果为: {}" + returnJobStr); + } else { + log.info("run2 执行成功。 但是修改设备状态失败----- 此处该预警"); + } + return true; + } +} + + diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/BrowseTask.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/BrowseTask.java new file mode 100644 index 0000000..9ca72aa --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/BrowseTask.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.entity.quartz.Boss; +import me.zhengjie.service.YdQuartzService; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 浏览收藏任务 + * @author rch + * @date 2022-11-04 + */ +@Slf4j +@Component +public class BrowseTask { + + @Resource + private YdQuartzService ydQuartzService; + + public void run(String str) throws Exception { + System.out.println("================================BrowseTask=========================1"); + Boss boss = JSONUtil.toBean(str, Boss.class); + String REBOT_KEY = PublicConstant.getRebotKeyPrefix(boss.getAccountName()); + System.out.println("================================BrowseTask=========================2"); + ydQuartzService.executeOnLock(REBOT_KEY, 1, 1, callBack -> { + try { + System.out.println("================================BrowseTask=========================3"); + return ydQuartzService.browseTaskExec(str); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } +} + diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/ClickFarmSuppleMentTask.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/ClickFarmSuppleMentTask.java new file mode 100644 index 0000000..654079b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/ClickFarmSuppleMentTask.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.entity.quartz.Boss; +import me.zhengjie.service.YdQuartzService; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 刷单补录任务 + * @author rch + * @date 2022-10-17 + */ +@Slf4j +@Component +public class ClickFarmSuppleMentTask { + + @Resource + private YdQuartzService ydQuartzService; + + public void run(String str) throws Exception { + System.out.println("================================ClickFarmSuppleMentTask=========================1"); + Boss boss = JSONUtil.toBean(str, Boss.class); + String REBOT_KEY = PublicConstant.getRebotKeyPrefix(boss.getAccountName()); + System.out.println("================================ClickFarmSuppleMentTask=========================2"); + ydQuartzService.executeOnLock(REBOT_KEY, 1, 1, callBack -> { + try { + System.out.println("================================ClickFarmSuppleMentTask=========================3"); + return ydQuartzService.clickFarmSuppleMentExec(str); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } +} + diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/ClickFarmTask.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/ClickFarmTask.java new file mode 100644 index 0000000..701e025 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/ClickFarmTask.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.entity.quartz.Boss; +import me.zhengjie.service.YdQuartzService; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 刷单任务 + * @author rch + * @date 2022-08-16 + */ +@Slf4j +@Component +public class ClickFarmTask { + + @Resource + private YdQuartzService ydQuartzService; + + public void run(String str) throws Exception { + System.out.println("================================ClickFarmTask=========================1"); + Boss boss = JSONUtil.toBean(str, Boss.class); + String REBOT_KEY = PublicConstant.getRebotKeyPrefix(boss.getAccountName()); + System.out.println("================================ClickFarmTask=========================2"); + ydQuartzService.executeOnLock(REBOT_KEY, 1, 1, callBack -> { + try { + System.out.println("================================ClickFarmTask=========================3"); + return ydQuartzService.clickFarmExec(str); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } +} + diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/DhAddCarTask.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/DhAddCarTask.java new file mode 100644 index 0000000..d6f1518 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/DhAddCarTask.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.entity.quartz.Boss; +import me.zhengjie.service.YdQuartzService; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 敦煌-加购 + * @author rch + * @date 2022-11-14 + */ +@Slf4j +@Component +public class DhAddCarTask { + + @Resource + private YdQuartzService ydQuartzService; + + public void run(String str) throws Exception { + System.out.println("================================ClickFarmTask=========================1"); + Boss boss = JSONUtil.toBean(str, Boss.class); + String REBOT_KEY = PublicConstant.getRebotKeyPrefix(boss.getAccountName()); + System.out.println("================================ClickFarmTask=========================2"); + ydQuartzService.executeOnLock(REBOT_KEY, 1, 1, callBack -> { + try { + System.out.println("================================ClickFarmTask=========================3"); + return ydQuartzService.addCarExec(str); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } +} + diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/DhCatchOrderTask.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/DhCatchOrderTask.java new file mode 100644 index 0000000..492a6ac --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/DhCatchOrderTask.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.entity.quartz.Boss; +import me.zhengjie.service.YdQuartzService; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 敦煌-加购抓单任务 + * @author rch + * @date 2022-08-16 + */ +@Slf4j +@Component +public class DhCatchOrderTask { + + @Resource + private YdQuartzService ydQuartzService; + + public void run(String str) throws Exception { + System.out.println("================================DhCatchOrderTask=========================1"); + Boss boss = JSONUtil.toBean(str, Boss.class); + String REBOT_KEY = PublicConstant.getRebotKeyPrefix(boss.getAccountName()); + System.out.println("================================DhCatchOrderTask=========================2"); + ydQuartzService.executeOnLock(REBOT_KEY, 1, 1, callBack -> { + try { + System.out.println("================================DhCatchOrderTask=========================3"); + return ydQuartzService.catchOrderExec(str); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } +} + diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/DhPayTask.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/DhPayTask.java new file mode 100644 index 0000000..6a44236 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/DhPayTask.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.service.CtDhPayService; +import me.zhengjie.service.CtOrderService; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 敦煌 支付 定时器 + * 计划 每10s 执行一次 -串行 + * @author rch + * @date 2022-07-28 + */ +@Slf4j +@Component +public class DhPayTask { + + @Resource + private CtDhPayService ctDhPayService; + + public void dhPayTaskRun(){ + try { + ctDhPayService.toPay(); + log.info("敦煌 支付 定时器---DhPayTask---dhPayTaskRun---执行成功"); + } catch (Exception e) { + e.printStackTrace(); + } + log.info("run---end!"); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/DhWellReceivedTask.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/DhWellReceivedTask.java new file mode 100644 index 0000000..79baee7 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/DhWellReceivedTask.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.entity.quartz.Boss; +import me.zhengjie.service.YdQuartzService; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 敦煌-好评 + * @author rch + * @date 2022-11-14 + */ +@Slf4j +@Component +public class DhWellReceivedTask { + + @Resource + private YdQuartzService ydQuartzService; + + public void run(String str) throws Exception { + System.out.println("================================DhWellReceivedTask=========================1"); + Boss boss = JSONUtil.toBean(str, Boss.class); + String REBOT_KEY = PublicConstant.getRebotKeyPrefix(boss.getAccountName()); + System.out.println("================================DhWellReceivedTask=========================2"); + ydQuartzService.executeOnLock(REBOT_KEY, 1, 1, callBack -> { + try { + System.out.println("================================DhWellReceivedTask=========================3"); + return ydQuartzService.dhWellReceivedExec(str); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } +} + diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/ExcelToOrderTask.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/ExcelToOrderTask.java new file mode 100644 index 0000000..6ce201d --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/ExcelToOrderTask.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.service.CtOrderService; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * Excel 数据转换存储到订单表里 Order 一对多 + * 计划 每10s 执行一次 -串行 + * @author rch + * @date 2022-06-23 + */ +@Slf4j +@Component +public class ExcelToOrderTask { + + @Resource + private CtOrderService ctOrderService; + + public void excelToOrderRun(){ + try { + ctOrderService.excelToOrder(); + log.info("Excel 数据转换存储到订单表里 Order---ExcelToOrderTask---excelToOrderRun---执行成功"); + } catch (Exception e) { + e.printStackTrace(); + } + log.info("run---end!"); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/ExcelmportTask.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/ExcelmportTask.java new file mode 100644 index 0000000..79e5068 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/ExcelmportTask.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.service.CtExcelImportInfoService; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * Excel 数据导入到Mysql定时器 + * 计划 每10s 执行一次 -串行 + * @author rch + * @date 2022-06-23 + */ +@Slf4j +@Component +public class ExcelmportTask { + + @Resource + private CtExcelImportInfoService ctExcelImportInfoService; + + public void importRun(){ + try { + ctExcelImportInfoService.importExcel(); + log.info("Excel数据导入到Mysql定时器---ExcelmportTask---importRun---执行成功"); + } catch (Exception e) { + e.printStackTrace(); + } + log.info("run---end!"); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/OrderToPayTask.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/OrderToPayTask.java new file mode 100644 index 0000000..e62c8bd --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/OrderToPayTask.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.service.CtOrderService; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 订单表里Order支付 定时器 + * 计划 每8s 执行一次 -串行 + * @author rch + * @date 2022-06-23 + */ +@Slf4j +@Component +public class OrderToPayTask { + + @Resource + private CtOrderService ctOrderService; + + public void orderToPayRun(){ + try { + ctOrderService.toPay(); + log.info("订单表里Order支付---OrderToPayTask---orderToPayRun---执行成功"); + } catch (Exception e) { + e.printStackTrace(); + } + log.info("run---end!"); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/RebotStatusTask.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/RebotStatusTask.java new file mode 100644 index 0000000..6266f5e --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/RebotStatusTask.java @@ -0,0 +1,95 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.config.YdApiProperties; +import me.zhengjie.constant.Constants; +import me.zhengjie.entity.CtRebot; +import me.zhengjie.entity.quartz.RebotStatu; +import me.zhengjie.entity.quartz.RebotStatuReturn; +import me.zhengjie.entity.quartz.SecreInfo; +import me.zhengjie.enums.CtReboteStatusEnum; +import me.zhengjie.enums.RobotStatusEnum; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.service.CtRebotService; +import me.zhengjie.utils.HttpClientUtil; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 机器人状态定时检测 + * @author rch + * @date 2022-08-06 + */ +@Slf4j +@Component +public class RebotStatusTask { + + @Resource + private CtRebotService ctRebotService; + + /** + * 计划20s执行一次 等到真的脚本写好了,就多点时间根据实际情况 + */ + public void run(){ + try { + // TODO 获取占用状态的机器人信息 然后定时调用接口 根据结果修改机器人状态 + QueryWrapper ctRebotQueryWrapper = new QueryWrapper<>(); + ctRebotQueryWrapper.eq("status", CtReboteStatusEnum.OCCUPY.value()); + + List ctRebotList = ctRebotService.list(ctRebotQueryWrapper); + + // token + Map params = new HashMap<>(16); + params.put("accessKeyId", YdApiProperties.ACCESS_KEY_ID); + params.put("accessKeySecret", YdApiProperties.ACCESS_KEY_SECRET); + SecreInfo secreInfo = JSONUtil.toBean(HttpClientUtil.getHttp(Constants.GET_SECRET, params), SecreInfo.class); + if (!secreInfo.getSuccess()) { + log.info("=========鉴权异常=========="); + throw new BadRequestException("请求影刀鉴权异常!"); + } + String token = secreInfo.getData().getAccessToken(); + Map headers = new HashMap<>(16); + headers.put("Accept", "application/json"); + headers.put("Content-Type", "application/json;charset=utf-8"); + headers.put("authorization", "Bearer " + token); + for (CtRebot ctRebot:ctRebotList) { + // 判断是否在线 + RebotStatu rebotStatu = new RebotStatu(ctRebot.getRobotClientUuid(), ctRebot.getAccountName()); + String returnStr = HttpClientUtil.postJson(Constants.REBOT_STATU, headers, JSONUtil.toJsonStr(rebotStatu), "utf-8"); + RebotStatuReturn rebotStatuReturn = JSONUtil.toBean(returnStr, RebotStatuReturn.class); + + if (ObjectUtil.isNotEmpty(rebotStatuReturn.getData()) && RobotStatusEnum.IDLE.value().equals(rebotStatuReturn.getData().getStatus())) { + Boolean result = ctRebotService.updateNewStatusByOldStatus(ctRebot.getId(), CtReboteStatusEnum.UNOCCUPIED.value(), ctRebot.getStatus()); + log.info("=======修改设备空闲状态=====ctRebot:{} --oldStatus:{}, ---newStatus{} --result:{}", JSONUtil.toJsonStr(ctRebot), ctRebot.getStatus(), CtReboteStatusEnum.UNOCCUPIED.value(), result); + } + } + + log.info("run 执行成功====time:" + DateUtil.now()); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/TestTask.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/TestTask.java new file mode 100644 index 0000000..5ec4a14 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/TestTask.java @@ -0,0 +1,49 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import cn.hutool.core.date.DateUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 测试用 + * @author Zheng Jie + * @date 2019-01-08 + */ +@Slf4j +@Component +public class TestTask { + + public void run(){ + try { + Thread.sleep(5000); + log.info("run 执行成功====time:" + DateUtil.now()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + log.info("run---end!"); + } + + public void run1(String str){ + log.info("run1 执行成功,参数为: {}" + str); + } + + public void run2(){ + log.info("run2 执行成功"); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/WellReceivedTask.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/WellReceivedTask.java new file mode 100644 index 0000000..eaab091 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/task/WellReceivedTask.java @@ -0,0 +1,55 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.task; + +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.entity.quartz.Boss; +import me.zhengjie.service.YdQuartzService; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; + +/** + * 刷单任务 + * @author rch + * @date 2022-10-17 + */ +@Slf4j +@Component +public class WellReceivedTask { + + @Resource + private YdQuartzService ydQuartzService; + + public void run(String str) throws Exception { + System.out.println("================================WellReceivedTask=========================1"); + Boss boss = JSONUtil.toBean(str, Boss.class); + String REBOT_KEY = PublicConstant.getRebotKeyPrefix(boss.getAccountName()); + System.out.println("================================WellReceivedTask=========================2"); + ydQuartzService.executeOnLock(REBOT_KEY, 1, 1, callBack -> { + try { + System.out.println("================================WellReceivedTask=========================3"); + return ydQuartzService.wellReceivedExec(str); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } +} + diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java new file mode 100644 index 0000000..267f20b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java @@ -0,0 +1,140 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.utils; + +import cn.hutool.extra.template.Template; +import cn.hutool.extra.template.TemplateConfig; +import cn.hutool.extra.template.TemplateEngine; +import cn.hutool.extra.template.TemplateUtil; +import me.zhengjie.config.thread.ThreadPoolExecutorUtil; +import me.zhengjie.domain.vo.EmailVo; +import me.zhengjie.modules.quartz.domain.QuartzJob; +import me.zhengjie.modules.quartz.domain.QuartzLog; +import me.zhengjie.modules.quartz.repository.QuartzLogRepository; +import me.zhengjie.modules.quartz.service.QuartzJobService; +import me.zhengjie.service.EmailService; +import me.zhengjie.utils.RedisUtils; +import me.zhengjie.utils.SpringContextHolder; +import me.zhengjie.utils.StringUtils; +import me.zhengjie.utils.ThrowableUtil; +import org.quartz.DisallowConcurrentExecution; +import org.quartz.JobExecutionContext; +import org.springframework.scheduling.quartz.QuartzJobBean; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Future; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * 参考人人开源,https://gitee.com/renrenio/renren-security + * @author / + * @date 2019-01-07 + */ +//@Async +@DisallowConcurrentExecution +public class ExecutionJob extends QuartzJobBean { + + /** 该处仅供参考 */ + private final static ThreadPoolExecutor EXECUTOR = ThreadPoolExecutorUtil.getPoll(); + + @Override + public void executeInternal(JobExecutionContext context) { + QuartzJob quartzJob = (QuartzJob) context.getMergedJobDataMap().get(QuartzJob.JOB_KEY); + // 获取spring bean + QuartzLogRepository quartzLogRepository = SpringContextHolder.getBean(QuartzLogRepository.class); + QuartzJobService quartzJobService = SpringContextHolder.getBean(QuartzJobService.class); + RedisUtils redisUtils = SpringContextHolder.getBean(RedisUtils.class); + + String uuid = quartzJob.getUuid(); + + QuartzLog log = new QuartzLog(); + log.setJobName(quartzJob.getJobName()); + log.setBeanName(quartzJob.getBeanName()); + log.setMethodName(quartzJob.getMethodName()); + log.setParams(quartzJob.getParams()); + log.setType(quartzJob.getType()); + long startTime = System.currentTimeMillis(); + log.setCronExpression(quartzJob.getCronExpression()); + try { + // 执行任务 + System.out.println("--------------------------------------------------------------"); + System.out.println("任务开始执行,任务名称:" + quartzJob.getJobName()); + QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(), + quartzJob.getParams()); + Future future = EXECUTOR.submit(task); + future.get(); + long times = System.currentTimeMillis() - startTime; + log.setTime(times); + if(StringUtils.isNotBlank(uuid)) { + redisUtils.set(uuid, true); + } + // 任务状态 + log.setIsSuccess(true); + System.out.println("任务执行完毕,任务名称:" + quartzJob.getJobName() + ", 执行时间:" + times + "毫秒"); + System.out.println("--------------------------------------------------------------"); + // 判断是否存在子任务 + if(StringUtils.isNotBlank(quartzJob.getSubTask())){ + String[] tasks = quartzJob.getSubTask().split("[,,]"); + // 执行子任务 + quartzJobService.executionSubJob(tasks); + } + } catch (Exception e) { + if(StringUtils.isNotBlank(uuid)) { + redisUtils.set(uuid, false); + } + System.out.println("任务执行失败,任务名称:" + quartzJob.getJobName()); + System.out.println("--------------------------------------------------------------"); + long times = System.currentTimeMillis() - startTime; + log.setTime(times); + // 任务状态 0:成功 1:失败 + log.setIsSuccess(false); + log.setExceptionDetail(ThrowableUtil.getStackTrace(e)); + // 任务如果失败了则暂停 + if(quartzJob.getPauseAfterFailure() != null && quartzJob.getPauseAfterFailure()){ + quartzJob.setIsPause(false); + //更新状态 + quartzJobService.updateIsPause(quartzJob); + } + if(quartzJob.getEmail() != null){ + EmailService emailService = SpringContextHolder.getBean(EmailService.class); + // 邮箱报警 + if(StringUtils.isNoneBlank(quartzJob.getEmail())){ + EmailVo emailVo = taskAlarm(quartzJob, ThrowableUtil.getStackTrace(e)); + emailService.send(emailVo, emailService.find()); + } + } + } finally { + quartzLogRepository.save(log); + } + } + + private EmailVo taskAlarm(QuartzJob quartzJob, String msg) { + EmailVo emailVo = new EmailVo(); + emailVo.setSubject("定时任务【"+ quartzJob.getJobName() +"】执行失败,请尽快处理!"); + Map data = new HashMap<>(16); + data.put("task", quartzJob); + data.put("msg", msg); + TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH)); + Template template = engine.getTemplate("email/taskAlarm.ftl"); + emailVo.setContent(template.render(data)); + List emails = Arrays.asList(quartzJob.getEmail().split("[,,]")); + emailVo.setTos(emails); + return emailVo; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/utils/QuartzManage.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/utils/QuartzManage.java new file mode 100644 index 0000000..e0cf1e0 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/utils/QuartzManage.java @@ -0,0 +1,174 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.utils; + +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.quartz.domain.QuartzJob; +import org.quartz.*; +import org.quartz.impl.triggers.CronTriggerImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import javax.annotation.Resource; +import java.util.Date; +import static org.quartz.TriggerBuilder.newTrigger; + +/** + * @author Zheng Jie + * @date 2019-01-07 + */ +@Slf4j +@Component +public class QuartzManage { + + private static final String JOB_NAME = "TASK_"; + + @Resource + private Scheduler scheduler; + + public void addJob(QuartzJob quartzJob){ + try { + // 构建job信息 + JobDetail jobDetail = JobBuilder.newJob(ExecutionJob.class). + withIdentity(JOB_NAME + quartzJob.getId()).build(); + + //通过触发器名和cron 表达式创建 Trigger + Trigger cronTrigger = newTrigger() + .withIdentity(JOB_NAME + quartzJob.getId()) + .startNow() + .withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression())) + .build(); + + cronTrigger.getJobDataMap().put(QuartzJob.JOB_KEY, quartzJob); + + //重置启动时间 + ((CronTriggerImpl)cronTrigger).setStartTime(new Date()); + + //执行定时任务 + scheduler.scheduleJob(jobDetail,cronTrigger); + + // 暂停任务 + if (quartzJob.getIsPause()) { + pauseJob(quartzJob); + } + } catch (Exception e){ + log.error("创建定时任务失败", e); + throw new BadRequestException("创建定时任务失败"); + } + } + + /** + * 更新job cron表达式 + * @param quartzJob / + */ + public void updateJobCron(QuartzJob quartzJob){ + try { + TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId()); + CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); + // 如果不存在则创建一个定时任务 + if(trigger == null){ + addJob(quartzJob); + trigger = (CronTrigger) scheduler.getTrigger(triggerKey); + } + CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression()); + trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); + //重置启动时间 + ((CronTriggerImpl)trigger).setStartTime(new Date()); + trigger.getJobDataMap().put(QuartzJob.JOB_KEY,quartzJob); + + scheduler.rescheduleJob(triggerKey, trigger); + // 暂停任务 + if (quartzJob.getIsPause()) { + pauseJob(quartzJob); + } + } catch (Exception e){ + log.error("更新定时任务失败", e); + throw new BadRequestException("更新定时任务失败"); + } + + } + + /** + * 删除一个job + * @param quartzJob / + */ + public void deleteJob(QuartzJob quartzJob){ + try { + JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId()); + scheduler.pauseJob(jobKey); + scheduler.deleteJob(jobKey); + } catch (Exception e){ + log.error("删除定时任务失败", e); + throw new BadRequestException("删除定时任务失败"); + } + } + + /** + * 恢复一个job + * @param quartzJob / + */ + public void resumeJob(QuartzJob quartzJob){ + try { + TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId()); + CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); + // 如果不存在则创建一个定时任务 + if(trigger == null) { + addJob(quartzJob); + } + JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId()); + scheduler.resumeJob(jobKey); + } catch (Exception e){ + log.error("恢复定时任务失败", e); + throw new BadRequestException("恢复定时任务失败"); + } + } + + /** + * 立即执行job + * @param quartzJob / + */ + public void runJobNow(QuartzJob quartzJob){ + try { + TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId()); + CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); + // 如果不存在则创建一个定时任务 + if(trigger == null) { + addJob(quartzJob); + } + JobDataMap dataMap = new JobDataMap(); + dataMap.put(QuartzJob.JOB_KEY, quartzJob); + JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId()); + scheduler.triggerJob(jobKey,dataMap); + } catch (Exception e){ + log.error("定时任务执行失败", e); + throw new BadRequestException("定时任务执行失败"); + } + } + + /** + * 暂停一个job + * @param quartzJob / + */ + public void pauseJob(QuartzJob quartzJob){ + try { + JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId()); + scheduler.pauseJob(jobKey); + } catch (Exception e){ + log.error("定时任务暂停失败", e); + throw new BadRequestException("定时任务暂停失败"); + } + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/utils/QuartzRunnable.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/utils/QuartzRunnable.java new file mode 100644 index 0000000..faf334c --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/utils/QuartzRunnable.java @@ -0,0 +1,58 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.quartz.utils; + +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.utils.SpringContextHolder; +import org.apache.commons.lang3.StringUtils; +import org.springframework.util.ReflectionUtils; +import java.lang.reflect.Method; +import java.util.concurrent.Callable; + +/** + * 执行定时任务 + * @author / + */ +@Slf4j +public class QuartzRunnable implements Callable { + + private final Object target; + private final Method method; + private final String params; + + QuartzRunnable(String beanName, String methodName, String params) + throws NoSuchMethodException, SecurityException { + this.target = SpringContextHolder.getBean(beanName); + this.params = params; + + if (StringUtils.isNotBlank(params)) { + this.method = target.getClass().getDeclaredMethod(methodName, String.class); + } else { + this.method = target.getClass().getDeclaredMethod(methodName); + } + } + + @Override + public Object call() throws Exception { + ReflectionUtils.makeAccessible(method); + if (StringUtils.isNotBlank(params)) { + method.invoke(target, params); + } else { + method.invoke(target); + } + return null; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/quartz/utils/YdApiUtil.java b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/utils/YdApiUtil.java new file mode 100644 index 0000000..228ca67 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/quartz/utils/YdApiUtil.java @@ -0,0 +1,31 @@ +package me.zhengjie.modules.quartz.utils; + +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.config.BeanFactory; +import me.zhengjie.constant.Constants; +import me.zhengjie.entity.CtApply; +import me.zhengjie.entity.CtRebot; +import me.zhengjie.entity.quartz.RebotStatu; +import me.zhengjie.entity.quartz.RebotStatuReturn; +import me.zhengjie.entity.quartz.SecreInfo; +import me.zhengjie.enums.RobotStatusEnum; +import me.zhengjie.enums.YesOrNoEnum; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.service.CtRebotService; +import me.zhengjie.utils.HttpClientUtil; + +import java.util.HashMap; +import java.util.Map; + +/** + * 调用影刀发起Api请求工具类 + * + * @author rch + * @create 2022-08-01 + */ +@Slf4j +public class YdApiUtil { + + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/config/ConfigBeanConfiguration.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/config/ConfigBeanConfiguration.java new file mode 100644 index 0000000..8cbc88d --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/config/ConfigBeanConfiguration.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.config; + +import me.zhengjie.modules.security.config.bean.LoginProperties; +import me.zhengjie.modules.security.config.bean.SecurityProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @apiNote 配置文件转换Pojo类的 统一配置 类 + * @author: liaojinlong + * @date: 2020/6/10 19:04 + */ +@Configuration +public class ConfigBeanConfiguration { + + @Bean + @ConfigurationProperties(prefix = "login") + public LoginProperties loginProperties() { + return new LoginProperties(); + } + + @Bean + @ConfigurationProperties(prefix = "jwt") + public SecurityProperties securityProperties() { + return new SecurityProperties(); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java new file mode 100644 index 0000000..9067f1c --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java @@ -0,0 +1,207 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.config; + +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.config.PropertiesConfig; +import me.zhengjie.modules.security.config.bean.SecurityProperties; +import me.zhengjie.modules.security.security.JwtAccessDeniedHandler; +import me.zhengjie.modules.security.security.JwtAuthenticationEntryPoint; +import me.zhengjie.modules.security.security.TokenConfigurer; +import me.zhengjie.modules.security.security.TokenProvider; +import me.zhengjie.modules.security.service.OnlineUserService; +import me.zhengjie.modules.security.service.UserCacheClean; +import me.zhengjie.service.LoginIpService; +import me.zhengjie.utils.enums.RequestMethodEnum; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.core.GrantedAuthorityDefaults; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import javax.annotation.Resource; +import java.util.*; + +/** + * @author Zheng Jie + */ +@Configuration +@EnableWebSecurity +@RequiredArgsConstructor +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + private final TokenProvider tokenProvider; + private final CorsFilter corsFilter; + private final JwtAuthenticationEntryPoint authenticationErrorHandler; + private final JwtAccessDeniedHandler jwtAccessDeniedHandler; + private final ApplicationContext applicationContext; + private final SecurityProperties properties; + private final OnlineUserService onlineUserService; + private final UserCacheClean userCacheClean; + private final LoginIpService loginIpService; + @Resource + private PropertiesConfig propertiesConfig; + + @Bean + GrantedAuthorityDefaults grantedAuthorityDefaults() { + // 去除 ROLE_ 前缀 + return new GrantedAuthorityDefaults(""); + } + + @Bean + public PasswordEncoder passwordEncoder() { + // 密码加密方式 + return new BCryptPasswordEncoder(); + } + + @Override + protected void configure(HttpSecurity httpSecurity) throws Exception { + // 搜寻匿名标记 url: @AnonymousAccess + // Map handlerMethodMap = applicationContext.getBean(RequestMappingHandlerMapping.class).getHandlerMethods(); + RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping"); + Map handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods(); + + // 获取匿名标记 + Map> anonymousUrls = getAnonymousUrl(handlerMethodMap); + httpSecurity + // 禁用 CSRF + .csrf().disable() + .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class) + // 授权异常 + .exceptionHandling() + .authenticationEntryPoint(authenticationErrorHandler) + .accessDeniedHandler(jwtAccessDeniedHandler) + // 防止iframe 造成跨域 + .and() + .headers() + .frameOptions() + .disable() + // 不创建会话 + .and() + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + .authorizeRequests() + // 静态资源等等 + .antMatchers( + HttpMethod.GET, + "/*.html", + "/**/*.html", + "/**/*.css", + "/**/*.js", + "/webSocket/**" + ).permitAll() + // swagger 文档 + .antMatchers("/swagger-ui.html").permitAll() + .antMatchers("/doc.html").permitAll() + .antMatchers("/swagger-resources/**").permitAll() + .antMatchers("/webjars/**").permitAll() + .antMatchers("/*/api-docs").permitAll() + // 文件 + .antMatchers("/avatar/**").permitAll() + .antMatchers("/file/**").permitAll() + // 图片上传 + .antMatchers("/api/file/**").permitAll() + // 静态资源访问 + .antMatchers(propertiesConfig.getUploadPrefix()+"/**").permitAll() + // 阿里巴巴 druid + .antMatchers("/druid/**").permitAll() + // 放行OPTIONS请求 + .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() + // 代理后台 + .antMatchers("/proxyAdmin/**").permitAll() + // 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型 + // GET + .antMatchers(HttpMethod.GET, anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0])).permitAll() + // POST + .antMatchers(HttpMethod.POST, anonymousUrls.get(RequestMethodEnum.POST.getType()).toArray(new String[0])).permitAll() + // PUT + .antMatchers(HttpMethod.PUT, anonymousUrls.get(RequestMethodEnum.PUT.getType()).toArray(new String[0])).permitAll() + // PATCH + .antMatchers(HttpMethod.PATCH, anonymousUrls.get(RequestMethodEnum.PATCH.getType()).toArray(new String[0])).permitAll() + // DELETE + .antMatchers(HttpMethod.DELETE, anonymousUrls.get(RequestMethodEnum.DELETE.getType()).toArray(new String[0])).permitAll() + // 所有类型的接口都放行 + .antMatchers(anonymousUrls.get(RequestMethodEnum.ALL.getType()).toArray(new String[0])).permitAll() + // 所有请求都需要认证 + .anyRequest().authenticated() + .and().apply(securityConfigurerAdapter()); + } + + private Map> getAnonymousUrl(Map handlerMethodMap) { + Map> anonymousUrls = new HashMap<>(6); + Set get = new HashSet<>(); + Set post = new HashSet<>(); + Set put = new HashSet<>(); + Set patch = new HashSet<>(); + Set delete = new HashSet<>(); + Set all = new HashSet<>(); + for (Map.Entry infoEntry : handlerMethodMap.entrySet()) { + HandlerMethod handlerMethod = infoEntry.getValue(); + AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class); + if (null != anonymousAccess) { + List requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods()); + RequestMethodEnum request = RequestMethodEnum.find(requestMethods.size() == 0 ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name()); + switch (Objects.requireNonNull(request)) { + case GET: + get.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case POST: + post.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case PUT: + put.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case PATCH: + patch.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case DELETE: + delete.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + default: + all.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + } + } + } + anonymousUrls.put(RequestMethodEnum.GET.getType(), get); + anonymousUrls.put(RequestMethodEnum.POST.getType(), post); + anonymousUrls.put(RequestMethodEnum.PUT.getType(), put); + anonymousUrls.put(RequestMethodEnum.PATCH.getType(), patch); + anonymousUrls.put(RequestMethodEnum.DELETE.getType(), delete); + anonymousUrls.put(RequestMethodEnum.ALL.getType(), all); + return anonymousUrls; + } + + private TokenConfigurer securityConfigurerAdapter() { + return new TokenConfigurer(tokenProvider, properties, onlineUserService, userCacheClean,loginIpService); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginCode.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginCode.java new file mode 100644 index 0000000..fefd252 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginCode.java @@ -0,0 +1,61 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.config.bean; + +import lombok.Data; + +/** + * 登录验证码配置信息 + * + * @author liaojinlong + * @date 2020/6/10 18:53 + */ +@Data +public class LoginCode { + + /** + * 验证码配置 + */ + private LoginCodeEnum codeType; + /** + * 验证码有效期 分钟 + */ + private Long expiration = 2L; + /** + * 验证码内容长度 + */ + private int length = 2; + /** + * 验证码宽度 + */ + private int width = 111; + /** + * 验证码高度 + */ + private int height = 36; + /** + * 验证码字体 + */ + private String fontName; + /** + * 字体大小 + */ + private int fontSize = 25; + + public LoginCodeEnum getCodeType() { + return codeType; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginCodeEnum.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginCodeEnum.java new file mode 100644 index 0000000..9ff398f --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginCodeEnum.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.config.bean; + +/** + * 验证码配置枚举 + * + * @author: liaojinlong + * @date: 2020/6/10 17:40 + */ + +public enum LoginCodeEnum { + /** + * 算数 + */ + arithmetic, + /** + * 中文 + */ + chinese, + /** + * 中文闪图 + */ + chinese_gif, + /** + * 闪图 + */ + gif, + spec +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java new file mode 100644 index 0000000..b13f173 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java @@ -0,0 +1,135 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version loginCode.length.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-loginCode.length.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.config.bean; + +import com.wf.captcha.*; +import com.wf.captcha.base.Captcha; +import lombok.Data; +import me.zhengjie.exception.BadConfigurationException; +import me.zhengjie.utils.StringUtils; + +import java.awt.*; +import java.util.Objects; + +/** + * 配置文件读取 + * + * @author liaojinlong + * @date loginCode.length0loginCode.length0/6/10 17:loginCode.length6 + */ +@Data +public class LoginProperties { + + /** + * 账号单用户 登录 + */ + private boolean singleLogin = false; + + private LoginCode loginCode; + + /** + * 用户登录信息缓存 + */ + private boolean cacheEnable; + + public boolean isSingleLogin() { + return singleLogin; + } + + public boolean isCacheEnable() { + return cacheEnable; + } + + /** + * 获取验证码生产类 + * + * @return / + */ + public Captcha getCaptcha() { + if (Objects.isNull(loginCode)) { + loginCode = new LoginCode(); + if (Objects.isNull(loginCode.getCodeType())) { + loginCode.setCodeType(LoginCodeEnum.arithmetic); + } + } + return switchCaptcha(loginCode); + } + + /** + * 依据配置信息生产验证码 + * + * @param loginCode 验证码配置信息 + * @return / + */ + private Captcha switchCaptcha(LoginCode loginCode) { + Captcha captcha; + synchronized (this) { + switch (loginCode.getCodeType()) { + case arithmetic: + // 算术类型 https://gitee.com/whvse/EasyCaptcha + captcha = new FixedArithmeticCaptcha(loginCode.getWidth(), loginCode.getHeight()); + // 几位数运算,默认是两位 + captcha.setLen(loginCode.getLength()); + break; + case chinese: + captcha = new ChineseCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + case chinese_gif: + captcha = new ChineseGifCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + case gif: + captcha = new GifCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + case spec: + captcha = new SpecCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + default: + throw new BadConfigurationException("验证码配置信息错误!正确配置查看 LoginCodeEnum "); + } + } + if(StringUtils.isNotBlank(loginCode.getFontName())){ + captcha.setFont(new Font(loginCode.getFontName(), Font.PLAIN, loginCode.getFontSize())); + } + return captcha; + } + + static class FixedArithmeticCaptcha extends ArithmeticCaptcha { + public FixedArithmeticCaptcha(int width, int height) { + super(width, height); + } + + @Override + protected char[] alphas() { + // 生成随机数字和运算符 + int n1 = num(1, 10), n2 = num(1, 10); + int opt = num(3); + + // 计算结果 + int res = new int[]{n1 + n2, n1 - n2, n1 * n2}[opt]; + // 转换为字符运算符 + char optChar = "+-x".charAt(opt); + + this.setArithmeticString(String.format("%s%c%s=?", n1, optChar, n2)); + this.chars = String.valueOf(res); + + return chars.toCharArray(); + } + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/config/bean/SecurityProperties.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/config/bean/SecurityProperties.java new file mode 100644 index 0000000..16ec3cf --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/config/bean/SecurityProperties.java @@ -0,0 +1,72 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.config.bean; + +import lombok.Data; + +/** + * Jwt参数配置 + * + * @author Zheng Jie + * @date 2019年11月28日 + */ +@Data +public class SecurityProperties { + + /** + * Request Headers : Authorization + */ + private String header; + + /** + * 令牌前缀,最后留个空格 Bearer + */ + private String tokenStartWith; + + /** + * 必须使用最少88位的Base64对该令牌进行编码 + */ + private String base64Secret; + + /** + * 令牌过期时间 此处单位/毫秒 + */ + private Long tokenValidityInSeconds; + + /** + * 在线用户 key,根据 key 查询 redis 中在线用户的数据 + */ + private String onlineKey; + + /** + * 验证码 key + */ + private String codeKey; + + /** + * token 续期检查 + */ + private Long detect; + + /** + * 续期时间 + */ + private Long renew; + + public String getTokenStartWith() { + return tokenStartWith + " "; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/rest/AuthorizationController.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/rest/AuthorizationController.java new file mode 100644 index 0000000..c9180cf --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/rest/AuthorizationController.java @@ -0,0 +1,201 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.rest; + +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.ObjectUtil; +import com.wf.captcha.base.Captcha; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.rest.AnonymousDeleteMapping; +import me.zhengjie.annotation.rest.AnonymousGetMapping; +import me.zhengjie.annotation.rest.AnonymousPostMapping; +import me.zhengjie.annotation.type.LogActionType; +import me.zhengjie.config.RsaProperties; +import me.zhengjie.dto.Dto; +import me.zhengjie.error.ErrorCodeEnum; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.security.config.bean.LoginCodeEnum; +import me.zhengjie.modules.security.config.bean.LoginProperties; +import me.zhengjie.modules.security.config.bean.SecurityProperties; +import me.zhengjie.modules.security.security.TokenProvider; +import me.zhengjie.modules.security.service.OnlineUserService; +import me.zhengjie.modules.security.service.dto.AuthUserDto; +import me.zhengjie.modules.security.service.dto.JwtUserDto; +import me.zhengjie.modules.utils.GoogleAuthenticatorUtil; +import me.zhengjie.service.LoginIpService; +import me.zhengjie.service.SettingSiteService; +import me.zhengjie.utils.*; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import static me.zhengjie.error.ErrorCodeEnum.LOGIN_PWD_ERROR; + +/** + * @author Zheng Jie + * @date 2018-11-23 + * 授权、根据token获取用户详细信息 + */ +@Slf4j +@RestController +@RequestMapping("/api/auth") +@RequiredArgsConstructor +@Api(tags = "系统:系统授权接口") +public class AuthorizationController { + private final SecurityProperties properties; + private final RedisUtils redisUtils; + private final OnlineUserService onlineUserService; + private final TokenProvider tokenProvider; + private final AuthenticationManagerBuilder authenticationManagerBuilder; + private final LoginIpService loginIpService; + + @Resource + private LoginProperties loginProperties; + @Resource + private SettingSiteService settingSiteService; + + @Log(value = "用户登录", type = LogActionType.LOGIN) + @ApiOperation("登录授权") + @AnonymousPostMapping(value = "/login") + public Object login(@Validated @RequestBody AuthUserDto authUser, HttpServletRequest request) throws Exception { + String ip = StringUtils.getIp(request); + if (!loginIpService.whiteListFlag(ip)) { + return Dto.getInstance(ErrorCodeEnum.BLOCKED_LOGIN_IP_ERROR); + } + + String BLOCKED_ACCOUNT = String.format(RedisUtils.BLOCKED_ACCOUNT, authUser.getUsername()); + Object obj = redisUtils.get(BLOCKED_ACCOUNT); + if (ObjectUtil.isNotEmpty(obj)) { + return Dto.getInstance(ErrorCodeEnum.BLOCKED_ACCOUNT_ERROR); + } + + // 如果Google Auth开启使用google Auth 验证 + if (settingSiteService.getGooleAuthSwitch()) { + // 第二个参数是 host -TODO 待确认 request.getRemoteHost() 是否是符合要求的域 + if (!GoogleAuthenticatorUtil.authcode(authUser.getCode(), GoogleAuthenticatorUtil.genSecret(authUser.getUsername(), request.getRemoteHost()))) { +// throw new BadRequestException("验证码错误"); + return Dto.getInstance(ErrorCodeEnum.ERROR_2222); + } + } else { + // 查询验证码 + String code = (String) redisUtils.get(authUser.getUuid()); + // 清除验证码 + redisUtils.del(authUser.getUuid()); + if (StringUtils.isBlank(code)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_2223); + } + if (StringUtils.isBlank(authUser.getCode()) || !authUser.getCode().equalsIgnoreCase(code)) { + return Dto.getInstance(ErrorCodeEnum.ERROR_2222); + } + } + + // 密码解密 + Authentication authentication = null; + try { + + String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, authUser.getPassword()); + + UsernamePasswordAuthenticationToken authenticationToken = + new UsernamePasswordAuthenticationToken(authUser.getUsername(), password); + authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken); + SecurityContextHolder.getContext().setAuthentication(authentication); + } catch (Exception e) { + String key = String.format(RedisUtils.LOGIN_FAIL_COUNT, authUser.getUsername()); + Long count = redisUtils.incrAndExpire(key, 300); + if (count >=3) { + // 冻结账户,24小时内不允许登录 + Map map = MapUtil.of("time", DateUtil.getCurrentTime()); + redisUtils.set(BLOCKED_ACCOUNT, map, 3600 * 24); + redisUtils.del(key); + } + + return Dto.getInstance(LOGIN_PWD_ERROR); + } + + + // 生成令牌与第三方系统获取令牌方式 + // UserDetails userDetails = userDetailsService.loadUserByUsername(userInfo.getUsername()); + // Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); + // SecurityContextHolder.getContext().setAuthentication(authentication); + String token = tokenProvider.createToken(authentication); + final JwtUserDto jwtUserDto = (JwtUserDto) authentication.getPrincipal(); + // 保存在线信息 + onlineUserService.save(jwtUserDto, token, request); + // 返回 token 与 用户信息 + Map authInfo = new HashMap(2) {{ + put("token", properties.getTokenStartWith() + token); + put("user", jwtUserDto); + }}; + if (loginProperties.isSingleLogin()) { + //踢掉之前已经登录的token + onlineUserService.checkLoginOnUser(authUser.getUsername(), token); + } + return ResponseEntity.ok(authInfo); + } + + @ApiOperation("获取用户信息") + @GetMapping(value = "/info") + public ResponseEntity getUserInfo() { + return ResponseEntity.ok(SecurityUtils.getCurrentUser()); + } + + @ApiOperation("获取验证码") + @AnonymousGetMapping(value = "/code") + public ResponseEntity getCode() { + // 获取运算的结果 + Captcha captcha = loginProperties.getCaptcha(); + String uuid = properties.getCodeKey() + IdUtil.simpleUUID(); + //当验证码类型为 arithmetic时且长度 >= 2 时,captcha.text()的结果有几率为浮点型 + String captchaValue = captcha.text(); + if (captcha.getCharType() - 1 == LoginCodeEnum.arithmetic.ordinal() && captchaValue.contains(".")) { + captchaValue = captchaValue.split("\\.")[0]; + } + // 保存 + redisUtils.set(uuid, captchaValue, loginProperties.getLoginCode().getExpiration(), TimeUnit.MINUTES); + // 验证码信息 + Map imgResult = new HashMap(2) {{ + put("img", captcha.toBase64()); + put("uuid", uuid); + }}; + return ResponseEntity.ok(imgResult); + } + + @ApiOperation("退出登录") + @AnonymousDeleteMapping(value = "/logout") + public ResponseEntity logout(HttpServletRequest request) { + onlineUserService.logout(tokenProvider.getToken(request)); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/rest/OnlineController.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/rest/OnlineController.java new file mode 100644 index 0000000..016f06f --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/rest/OnlineController.java @@ -0,0 +1,68 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.modules.security.service.OnlineUserService; +import me.zhengjie.utils.EncryptUtils; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +/** + * @author Zheng Jie + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/online") +@Api(tags = "系统:在线用户管理") +public class OnlineController { + + private final OnlineUserService onlineUserService; + + @ApiOperation("查询在线用户") + @GetMapping + @PreAuthorize("@el.check()") + public ResponseEntity query(String filter, Pageable pageable){ + return new ResponseEntity<>(onlineUserService.getAll(filter, pageable),HttpStatus.OK); + } + + @ApiOperation("导出数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check()") + public void download(HttpServletResponse response, String filter) throws IOException { + onlineUserService.download(onlineUserService.getAll(filter), response); + } + + @ApiOperation("踢出用户") + @DeleteMapping + @PreAuthorize("@el.check()") + public ResponseEntity delete(@RequestBody Set keys) throws Exception { + for (String key : keys) { + // 解密Key + key = EncryptUtils.desDecrypt(key); + onlineUserService.kickOut(key); + } + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/security/JwtAccessDeniedHandler.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/security/JwtAccessDeniedHandler.java new file mode 100644 index 0000000..8b3f8c1 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/security/JwtAccessDeniedHandler.java @@ -0,0 +1,37 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.security; + +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author Zheng Jie + */ +@Component +public class JwtAccessDeniedHandler implements AccessDeniedHandler { + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException { + //当用户在没有授权的情况下访问受保护的REST资源时,将调用此方法发送403 Forbidden响应 + response.sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage()); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/security/JwtAuthenticationEntryPoint.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/security/JwtAuthenticationEntryPoint.java new file mode 100644 index 0000000..f881586 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/security/JwtAuthenticationEntryPoint.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.security; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author Zheng Jie + */ +@Component +public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { + + @Override + public void commence(HttpServletRequest request, + HttpServletResponse response, + AuthenticationException authException) throws IOException { + // 当用户尝试访问安全的REST资源而不提供任何凭据时,将调用此方法发送401 响应 + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException==null?"Unauthorized":authException.getMessage()); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/security/TokenConfigurer.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/security/TokenConfigurer.java new file mode 100644 index 0000000..9e4e533 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/security/TokenConfigurer.java @@ -0,0 +1,45 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.security; + +import lombok.RequiredArgsConstructor; +import me.zhengjie.modules.security.config.bean.SecurityProperties; +import me.zhengjie.modules.security.service.OnlineUserService; +import me.zhengjie.modules.security.service.UserCacheClean; +import me.zhengjie.service.LoginIpService; +import org.springframework.security.config.annotation.SecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.DefaultSecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +/** + * @author / + */ +@RequiredArgsConstructor +public class TokenConfigurer extends SecurityConfigurerAdapter { + + private final TokenProvider tokenProvider; + private final SecurityProperties properties; + private final OnlineUserService onlineUserService; + private final UserCacheClean userCacheClean; + private final LoginIpService loginIpService; + + @Override + public void configure(HttpSecurity http) { + TokenFilter customFilter = new TokenFilter(tokenProvider, properties, onlineUserService, userCacheClean,loginIpService); + http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java new file mode 100644 index 0000000..db96094 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java @@ -0,0 +1,111 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.security; + +import cn.hutool.core.util.StrUtil; +import io.jsonwebtoken.ExpiredJwtException; +import lombok.RequiredArgsConstructor; +import me.zhengjie.modules.security.config.bean.SecurityProperties; +import me.zhengjie.modules.security.service.OnlineUserService; +import me.zhengjie.modules.security.service.UserCacheClean; +import me.zhengjie.modules.security.service.dto.OnlineUserDto; +import me.zhengjie.service.LoginIpService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.GenericFilterBean; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.Objects; + +/** + * @author / + */ +@RequiredArgsConstructor +public class TokenFilter extends GenericFilterBean { + private static final Logger log = LoggerFactory.getLogger(TokenFilter.class); + + + private final TokenProvider tokenProvider; + private final SecurityProperties properties; + private final OnlineUserService onlineUserService; + private final UserCacheClean userCacheClean; + private final LoginIpService loginIpService; + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; + // 验证 +// String ip = me.zhengjie.utils.StringUtils.getIp(httpServletRequest); +// if (!loginIpService.whiteListFlag(ip)) { +// Dto dto = Dto.getInstance(ErrorCodeEnum.BLOCKED_LOGIN_IP_ERROR); +//// throw new BadRequestException(ErrorCodeEnum.BLOCKED_LOGIN_IP_ERROR); +// servletResponse.setContentType("application/json;charset=UTF-8"); +// servletResponse.getWriter().write(JSONUtil.toJsonStr(dto)); +// +// return; +// } + + String token = resolveToken(httpServletRequest); + // 对于 Token 为空的不需要去查 Redis + if (StrUtil.isNotBlank(token)) { + OnlineUserDto onlineUserDto = null; + boolean cleanUserCache = false; + try { + onlineUserDto = onlineUserService.getOne(properties.getOnlineKey() + token); + } catch (ExpiredJwtException e) { + log.error(e.getMessage()); + cleanUserCache = true; + } finally { + if (cleanUserCache || Objects.isNull(onlineUserDto)) { + userCacheClean.cleanUserCache(String.valueOf(tokenProvider.getClaims(token).get(TokenProvider.AUTHORITIES_KEY))); + } + } + if (onlineUserDto != null && StringUtils.hasText(token)) { + Authentication authentication = tokenProvider.getAuthentication(token); + SecurityContextHolder.getContext().setAuthentication(authentication); + // Token 续期 +// tokenProvider.checkRenewal(token); + } + } + filterChain.doFilter(servletRequest, servletResponse); + } + + /** + * 初步检测Token + * + * @param request / + * @return / + */ + private String resolveToken(HttpServletRequest request) { + String bearerToken = request.getHeader(properties.getHeader()); + if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(properties.getTokenStartWith())) { + // 去掉令牌前缀 + return bearerToken.replace(properties.getTokenStartWith(), ""); + } else { + log.debug("非法Token:{}", bearerToken); + } + return null; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java new file mode 100644 index 0000000..db98fba --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java @@ -0,0 +1,123 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.security; + +import cn.hutool.core.date.DateField; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import io.jsonwebtoken.*; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.modules.security.config.bean.SecurityProperties; +import me.zhengjie.utils.RedisUtils; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.User; +import org.springframework.stereotype.Component; +import javax.servlet.http.HttpServletRequest; +import java.security.Key; +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * @author / + */ +@Slf4j +@Component +public class TokenProvider implements InitializingBean { + + private final SecurityProperties properties; + private final RedisUtils redisUtils; + public static final String AUTHORITIES_KEY = "user"; + private JwtParser jwtParser; + private JwtBuilder jwtBuilder; + + public TokenProvider(SecurityProperties properties, RedisUtils redisUtils) { + this.properties = properties; + this.redisUtils = redisUtils; + } + + @Override + public void afterPropertiesSet() { + byte[] keyBytes = Decoders.BASE64.decode(properties.getBase64Secret()); + Key key = Keys.hmacShaKeyFor(keyBytes); + jwtParser = Jwts.parserBuilder() + .setSigningKey(key) + .build(); + jwtBuilder = Jwts.builder() + .signWith(key, SignatureAlgorithm.HS512); + } + + /** + * 创建Token 设置永不过期, + * Token 的时间有效性转到Redis 维护 + * + * @param authentication / + * @return / + */ + public String createToken(Authentication authentication) { + return jwtBuilder + // 加入ID确保生成的 Token 都不一致 + .setId(IdUtil.simpleUUID()) + .claim(AUTHORITIES_KEY, authentication.getName()) + .setSubject(authentication.getName()) + .compact(); + } + + /** + * 依据Token 获取鉴权信息 + * + * @param token / + * @return / + */ + Authentication getAuthentication(String token) { + Claims claims = getClaims(token); + User principal = new User(claims.getSubject(), "******", new ArrayList<>()); + return new UsernamePasswordAuthenticationToken(principal, token, new ArrayList<>()); + } + + public Claims getClaims(String token) { + return jwtParser + .parseClaimsJws(token) + .getBody(); + } + + /** + * @param token 需要检查的token + */ + public void checkRenewal(String token) { + // 判断是否续期token,计算token的过期时间 + long time = redisUtils.getExpire(properties.getOnlineKey() + token) * 1000; + Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time); + // 判断当前时间与过期时间的时间差 + long differ = expireDate.getTime() - System.currentTimeMillis(); + // 如果在续期检查的范围内,则续期 + if (differ <= properties.getDetect()) { + long renew = time + properties.getRenew(); + redisUtils.expire(properties.getOnlineKey() + token, renew, TimeUnit.MILLISECONDS); + } + } + + public String getToken(HttpServletRequest request) { + final String requestHeader = request.getHeader(properties.getHeader()); + if (requestHeader != null && requestHeader.startsWith(properties.getTokenStartWith())) { + return requestHeader.substring(7); + } + return null; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/service/OnlineUserService.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/service/OnlineUserService.java new file mode 100644 index 0000000..96ebec4 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/service/OnlineUserService.java @@ -0,0 +1,191 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.service; + +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.modules.security.config.bean.SecurityProperties; +import me.zhengjie.modules.security.service.dto.JwtUserDto; +import me.zhengjie.modules.security.service.dto.OnlineUserDto; +import me.zhengjie.utils.*; +import org.springframework.data.domain.Pageable; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** + * @author Zheng Jie + * @date 2019年10月26日21:56:27 + */ +@Service +@Slf4j +public class OnlineUserService { + + private final SecurityProperties properties; + private final RedisUtils redisUtils; + + public OnlineUserService(SecurityProperties properties, RedisUtils redisUtils) { + this.properties = properties; + this.redisUtils = redisUtils; + } + + /** + * 保存在线用户信息 + * @param jwtUserDto / + * @param token / + * @param request / + */ + public void save(JwtUserDto jwtUserDto, String token, HttpServletRequest request){ + String dept = /*jwtUserDto.getUser().getDept().getName();*/null; + String ip = StringUtils.getIp(request); + String browser = StringUtils.getBrowser(request); +// String address = StringUtils.getCityInfo(ip); + OnlineUserDto onlineUserDto = null; + try { + onlineUserDto = new OnlineUserDto(jwtUserDto.getUsername(), jwtUserDto.getUser().getNickName(), dept, browser , ip, null, EncryptUtils.desEncrypt(token), new Date()); + } catch (Exception e) { + log.error(e.getMessage(),e); + } + redisUtils.set(properties.getOnlineKey() + token, onlineUserDto, properties.getTokenValidityInSeconds()/1000); + } + + /** + * 查询全部数据 + * @param filter / + * @param pageable / + * @return / + */ + public Map getAll(String filter, Pageable pageable){ + List onlineUserDtos = getAll(filter); + return PageUtil.toPage( + PageUtil.toPage(pageable.getPageNumber(),pageable.getPageSize(), onlineUserDtos), + onlineUserDtos.size() + ); + } + + /** + * 查询全部数据,不分页 + * @param filter / + * @return / + */ + public List getAll(String filter){ + List keys = redisUtils.scan(properties.getOnlineKey() + "*"); + Collections.reverse(keys); + List onlineUserDtos = new ArrayList<>(); + for (String key : keys) { + OnlineUserDto onlineUserDto = (OnlineUserDto) redisUtils.get(key); + if(StringUtils.isNotBlank(filter)){ + if(onlineUserDto.toString().contains(filter)){ + onlineUserDtos.add(onlineUserDto); + } + } else { + onlineUserDtos.add(onlineUserDto); + } + } + onlineUserDtos.sort((o1, o2) -> o2.getLoginTime().compareTo(o1.getLoginTime())); + return onlineUserDtos; + } + + /** + * 踢出用户 + * @param key / + */ + public void kickOut(String key){ + key = properties.getOnlineKey() + key; + redisUtils.del(key); + } + + /** + * 退出登录 + * @param token / + */ + public void logout(String token) { + String key = properties.getOnlineKey() + token; + redisUtils.del(key); + } + + /** + * 导出 + * @param all / + * @param response / + * @throws IOException / + */ + public void download(List all, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (OnlineUserDto user : all) { + Map map = new LinkedHashMap<>(); + map.put("用户名", user.getUserName()); + map.put("部门", user.getDept()); + map.put("登录IP", user.getIp()); + map.put("登录地点", user.getAddress()); + map.put("浏览器", user.getBrowser()); + map.put("登录日期", user.getLoginTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + /** + * 查询用户 + * @param key / + * @return / + */ + public OnlineUserDto getOne(String key) { + return (OnlineUserDto)redisUtils.get(key); + } + + /** + * 检测用户是否在之前已经登录,已经登录踢下线 + * @param userName 用户名 + */ + public void checkLoginOnUser(String userName, String igoreToken){ + List onlineUserDtos = getAll(userName); + if(onlineUserDtos ==null || onlineUserDtos.isEmpty()){ + return; + } + for(OnlineUserDto onlineUserDto : onlineUserDtos){ + if(onlineUserDto.getUserName().equals(userName)){ + try { + String token =EncryptUtils.desDecrypt(onlineUserDto.getKey()); + if(StringUtils.isNotBlank(igoreToken)&&!igoreToken.equals(token)){ + this.kickOut(token); + }else if(StringUtils.isBlank(igoreToken)){ + this.kickOut(token); + } + } catch (Exception e) { + log.error("checkUser is error",e); + } + } + } + } + + /** + * 根据用户名强退用户 + * @param username / + */ + @Async + public void kickOutForUsername(String username) throws Exception { + List onlineUsers = getAll(username); + for (OnlineUserDto onlineUser : onlineUsers) { + if (onlineUser.getUserName().equals(username)) { + String token =EncryptUtils.desDecrypt(onlineUser.getKey()); + kickOut(token); + } + } + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/service/UserCacheClean.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/service/UserCacheClean.java new file mode 100644 index 0000000..3f9fe5b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/service/UserCacheClean.java @@ -0,0 +1,49 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.zhengjie.modules.security.service; + +import me.zhengjie.utils.StringUtils; +import org.springframework.stereotype.Component; + +/** + * @author: liaojinlong + * @date: 2020/6/11 18:01 + * @apiNote: 用于清理 用户登录信息缓存,为防止Spring循环依赖与安全考虑 ,单独构成工具类 + */ +@Component +public class UserCacheClean { + + /** + * 清理特定用户缓存信息
+ * 用户信息变更时 + * + * @param userName / + */ + public void cleanUserCache(String userName) { + if (StringUtils.isNotEmpty(userName)) { + UserDetailsServiceImpl.userDtoCache.remove(userName); + } + } + + /** + * 清理所有用户的缓存信息
+ * ,如发生角色授权信息变化,可以简便的全部失效缓存 + */ + public void cleanAll() { + UserDetailsServiceImpl.userDtoCache.clear(); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/service/UserDetailsServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/service/UserDetailsServiceImpl.java new file mode 100644 index 0000000..c3657d1 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/service/UserDetailsServiceImpl.java @@ -0,0 +1,94 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.service; + +import lombok.RequiredArgsConstructor; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.exception.EntityNotFoundException; +import me.zhengjie.modules.security.config.bean.LoginProperties; +import me.zhengjie.modules.security.service.dto.JwtUserDto; +import me.zhengjie.modules.system.service.DataService; +import me.zhengjie.modules.system.service.RoleService; +import me.zhengjie.modules.system.service.UserService; +import me.zhengjie.modules.system.service.dto.UserDto; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author Zheng Jie + * @date 2018-11-22 + */ +@RequiredArgsConstructor +@Service("userDetailsService") +public class UserDetailsServiceImpl implements UserDetailsService { + private final UserService userService; + private final RoleService roleService; + private final DataService dataService; + private final LoginProperties loginProperties; + + public void setEnableCache(boolean enableCache) { + this.loginProperties.setCacheEnable(enableCache); + } + + /** + * 用户信息缓存 + * + * @see {@link UserCacheClean} + */ + static Map userDtoCache = new ConcurrentHashMap<>(); + + @Override + public JwtUserDto loadUserByUsername(String username) { + boolean searchDb = true; + JwtUserDto jwtUserDto = null; + if (loginProperties.isCacheEnable() && userDtoCache.containsKey(username)) { + jwtUserDto = userDtoCache.get(username); + // 检查dataScope是否修改 + List dataScopes = jwtUserDto.getDataScopes(); + dataScopes.clear(); + dataScopes.addAll(dataService.getDeptIds(jwtUserDto.getUser())); + searchDb = false; + } + if (searchDb) { + UserDto user; + try { + user = userService.findByName(username); + } catch (EntityNotFoundException e) { + // SpringSecurity会自动转换UsernameNotFoundException为BadCredentialsException + throw new UsernameNotFoundException("", e); + } + if (user == null) { + throw new UsernameNotFoundException(""); + } else { + if (!user.getEnabled()) { + throw new BadRequestException("账号未激活!"); + } + jwtUserDto = new JwtUserDto( + user, + dataService.getDeptIds(user), + roleService.mapToGrantedAuthorities(user) + ); + userDtoCache.put(username, jwtUserDto); + } + } + return jwtUserDto; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/service/dto/AuthUserDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/service/dto/AuthUserDto.java new file mode 100644 index 0000000..5219fc5 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/service/dto/AuthUserDto.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.service.dto; + +import lombok.Getter; +import lombok.Setter; +import javax.validation.constraints.NotBlank; + +/** + * @author Zheng Jie + * @date 2018-11-30 + */ +@Getter +@Setter +public class AuthUserDto { + + @NotBlank + private String username; + + @NotBlank + private String password; + + private String code; + + private String uuid = ""; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/service/dto/JwtUserDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/service/dto/JwtUserDto.java new file mode 100644 index 0000000..00f4372 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/service/dto/JwtUserDto.java @@ -0,0 +1,82 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.service.dto; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.AllArgsConstructor; +import lombok.Getter; +import me.zhengjie.modules.system.service.dto.UserDto; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Getter +@AllArgsConstructor +public class JwtUserDto implements UserDetails { + + private final UserDto user; + + private final List dataScopes; + + @JSONField(serialize = false) + private final List authorities; + + public Set getRoles() { + return authorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet()); + } + + @Override + @JSONField(serialize = false) + public String getPassword() { + return user.getPassword(); + } + + @Override + @JSONField(serialize = false) + public String getUsername() { + return user.getUsername(); + } + + @JSONField(serialize = false) + @Override + public boolean isAccountNonExpired() { + return true; + } + + @JSONField(serialize = false) + @Override + public boolean isAccountNonLocked() { + return true; + } + + @JSONField(serialize = false) + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + @JSONField(serialize = false) + public boolean isEnabled() { + return user.getEnabled(); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/security/service/dto/OnlineUserDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/security/service/dto/OnlineUserDto.java new file mode 100644 index 0000000..290ab6d --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/security/service/dto/OnlineUserDto.java @@ -0,0 +1,73 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.service.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.util.Date; + +/** + * 在线用户 + * @author Zheng Jie + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class OnlineUserDto { + + /** + * 用户名 + */ + private String userName; + + /** + * 昵称 + */ + private String nickName; + + /** + * 岗位 + */ + private String dept; + + /** + * 浏览器 + */ + private String browser; + + /** + * IP + */ + private String ip; + + /** + * 地址 + */ + private String address; + + /** + * token + */ + private String key; + + /** + * 登录时间 + */ + private Date loginTime; + + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Dept.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Dept.java new file mode 100644 index 0000000..9f28af2 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Dept.java @@ -0,0 +1,86 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.domain; + +import com.alibaba.fastjson.annotation.JSONField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseEntity; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Objects; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +@Entity +@Getter +@Setter +@Table(name="sys_dept") +public class Dept extends BaseEntity implements Serializable { + + @Id + @Column(name = "dept_id") + @NotNull(groups = Update.class) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @JSONField(serialize = false) + @ManyToMany(mappedBy = "depts") + @ApiModelProperty(value = "角色") + private Set roles; + + @ApiModelProperty(value = "排序") + private Integer deptSort; + + @NotBlank + @ApiModelProperty(value = "部门名称") + private String name; + + @NotNull + @ApiModelProperty(value = "是否启用") + private Boolean enabled; + + @ApiModelProperty(value = "上级部门") + private Long pid; + + @ApiModelProperty(value = "子节点数目", hidden = true) + private Integer subCount = 0; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Dept dept = (Dept) o; + return Objects.equals(id, dept.id) && + Objects.equals(name, dept.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Dict.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Dict.java new file mode 100644 index 0000000..689cf2e --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Dict.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseEntity; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.List; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Entity +@Getter +@Setter +@Table(name="sys_dict") +public class Dict extends BaseEntity implements Serializable { + + @Id + @Column(name = "dict_id") + @NotNull(groups = Update.class) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToMany(mappedBy = "dict",cascade={CascadeType.PERSIST,CascadeType.REMOVE}) + private List dictDetails; + + @NotBlank + @ApiModelProperty(value = "名称") + private String name; + + @ApiModelProperty(value = "描述") + private String description; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/DictDetail.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/DictDetail.java new file mode 100644 index 0000000..554dde6 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/DictDetail.java @@ -0,0 +1,56 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseEntity; +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Entity +@Getter +@Setter +@Table(name="sys_dict_detail") +public class DictDetail extends BaseEntity implements Serializable { + + @Id + @Column(name = "detail_id") + @NotNull(groups = Update.class) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @JoinColumn(name = "dict_id") + @ManyToOne(fetch=FetchType.LAZY) + @ApiModelProperty(value = "字典", hidden = true) + private Dict dict; + + @ApiModelProperty(value = "字典标签") + private String label; + + @ApiModelProperty(value = "字典值") + private String value; + + @ApiModelProperty(value = "排序") + private Integer dictSort = 999; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Job.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Job.java new file mode 100644 index 0000000..f2d358a --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Job.java @@ -0,0 +1,73 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseEntity; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Objects; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +@Entity +@Getter +@Setter +@Table(name="sys_job") +public class Job extends BaseEntity implements Serializable { + + @Id + @Column(name = "job_id") + @NotNull(groups = Update.class) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotBlank + @ApiModelProperty(value = "岗位名称") + private String name; + + @NotNull + @ApiModelProperty(value = "岗位排序") + private Long jobSort; + + @NotNull + @ApiModelProperty(value = "是否启用") + private Boolean enabled; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Job job = (Job) o; + return Objects.equals(id, job.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Menu.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Menu.java new file mode 100644 index 0000000..b2ea225 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Menu.java @@ -0,0 +1,110 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.domain; + +import com.alibaba.fastjson.annotation.JSONField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseEntity; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Objects; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-12-17 + */ +@Entity +@Getter +@Setter +@Table(name = "sys_menu") +public class Menu extends BaseEntity implements Serializable { + + @Id + @Column(name = "menu_id") + @NotNull(groups = {Update.class}) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @JSONField(serialize = false) + @ManyToMany(mappedBy = "menus") + @ApiModelProperty(value = "菜单角色") + private Set roles; + + @ApiModelProperty(value = "菜单标题") + private String title; + + @Column(name = "name") + @ApiModelProperty(value = "菜单组件名称") + private String componentName; + + @ApiModelProperty(value = "排序") + private Integer menuSort = 999; + + @ApiModelProperty(value = "组件路径") + private String component; + + @ApiModelProperty(value = "路由地址") + private String path; + + @ApiModelProperty(value = "菜单类型,目录、菜单、按钮") + private Integer type; + + @ApiModelProperty(value = "权限标识") + private String permission; + + @ApiModelProperty(value = "菜单图标") + private String icon; + + @Column(columnDefinition = "bit(1) default 0") + @ApiModelProperty(value = "缓存") + private Boolean cache; + + @Column(columnDefinition = "bit(1) default 0") + @ApiModelProperty(value = "是否隐藏") + private Boolean hidden; + + @ApiModelProperty(value = "上级菜单") + private Long pid; + + @ApiModelProperty(value = "子节点数目", hidden = true) + private Integer subCount = 0; + + @ApiModelProperty(value = "外链菜单") + private Boolean iFrame; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Menu menu = (Menu) o; + return Objects.equals(id, menu.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Role.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Role.java new file mode 100644 index 0000000..8b3ad19 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/Role.java @@ -0,0 +1,99 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.domain; + +import com.alibaba.fastjson.annotation.JSONField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseEntity; +import me.zhengjie.utils.enums.DataScopeEnum; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Objects; +import java.util.Set; + +/** + * 角色 + * @author Zheng Jie + * @date 2018-11-22 + */ +@Getter +@Setter +@Entity +@Table(name = "sys_role") +public class Role extends BaseEntity implements Serializable { + + @Id + @Column(name = "role_id") + @NotNull(groups = {Update.class}) + @GeneratedValue(strategy = GenerationType.IDENTITY) + @ApiModelProperty(value = "ID", hidden = true) + private Long id; + + @JSONField(serialize = false) + @ManyToMany(mappedBy = "roles") + @ApiModelProperty(value = "用户", hidden = true) + private Set users; + + @ManyToMany + @JoinTable(name = "sys_roles_menus", + joinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "role_id")}, + inverseJoinColumns = {@JoinColumn(name = "menu_id",referencedColumnName = "menu_id")}) + @ApiModelProperty(value = "菜单", hidden = true) + private Set menus; + + @ManyToMany + @JoinTable(name = "sys_roles_depts", + joinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "role_id")}, + inverseJoinColumns = {@JoinColumn(name = "dept_id",referencedColumnName = "dept_id")}) + @ApiModelProperty(value = "部门", hidden = true) + private Set depts; + + @NotBlank + @ApiModelProperty(value = "名称", hidden = true) + private String name; + + @ApiModelProperty(value = "数据权限,全部 、 本级 、 自定义") + private String dataScope = DataScopeEnum.THIS_LEVEL.getValue(); + + @Column(name = "level") + @ApiModelProperty(value = "级别,数值越小,级别越大") + private Integer level = 3; + + @ApiModelProperty(value = "描述") + private String description; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Role role = (Role) o; + return Objects.equals(id, role.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/User.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/User.java new file mode 100644 index 0000000..c496c91 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/User.java @@ -0,0 +1,129 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.annotation.CheckPwd; +import me.zhengjie.base.BaseEntity; +import javax.persistence.*; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; +import java.util.Objects; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-11-22 + */ +@Entity +@Getter +@Setter +@Table(name="sys_user") +public class User extends BaseEntity implements Serializable { + + @Id + @Column(name = "user_id") + @NotNull(groups = Update.class) + @GeneratedValue(strategy = GenerationType.IDENTITY) + @ApiModelProperty(value = "ID", hidden = true) + private Long id; + + @ManyToMany + @ApiModelProperty(value = "用户角色") + @JoinTable(name = "sys_users_roles", + joinColumns = {@JoinColumn(name = "user_id",referencedColumnName = "user_id")}, + inverseJoinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "role_id")}) + private Set roles; + + @ManyToMany + @ApiModelProperty(value = "用户岗位") + @JoinTable(name = "sys_users_jobs", + joinColumns = {@JoinColumn(name = "user_id",referencedColumnName = "user_id")}, + inverseJoinColumns = {@JoinColumn(name = "job_id",referencedColumnName = "job_id")}) + private Set jobs; + + @OneToOne + @JoinColumn(name = "dept_id") + @ApiModelProperty(value = "用户部门") + private Dept dept; + + @NotBlank(groups = Create.class) + @Column(unique = true) + @ApiModelProperty(value = "用户名称") + private String username; + + @NotBlank(groups = Create.class) + @ApiModelProperty(value = "用户昵称") + private String nickName; + + @Email(groups = Create.class) + @NotBlank(groups = Create.class) + @ApiModelProperty(value = "邮箱") + private String email; + + @NotBlank(groups = Create.class) + @ApiModelProperty(value = "电话号码") + private String phone; + + @ApiModelProperty(value = "用户性别") + private String gender; + + @ApiModelProperty(value = "头像真实名称",hidden = true) + private String avatarName; + + @ApiModelProperty(value = "头像存储的路径", hidden = true) + private String avatarPath; + + @NotBlank(groups = Create.class) + @CheckPwd(groups = Create.class) + @ApiModelProperty(value = "密码") + private String password; + + @NotNull(groups = Create.class) + @ApiModelProperty(value = "是否启用") + private Boolean enabled; + + @ApiModelProperty(value = "是否为admin账号", hidden = true) + private Boolean isAdmin = false; + + @Column(name = "pwd_reset_time") + @ApiModelProperty(value = "最后修改密码的时间", hidden = true) + private Date pwdResetTime; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + User user = (User) o; + return Objects.equals(id, user.id) && + Objects.equals(username, user.username); + } + + @Override + public int hashCode() { + return Objects.hash(id, username); + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/vo/MenuMetaVo.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/vo/MenuMetaVo.java new file mode 100644 index 0000000..647baa8 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/vo/MenuMetaVo.java @@ -0,0 +1,35 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.domain.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import java.io.Serializable; + +/** + * @author Zheng Jie + * @date 2018-12-20 + */ +@Data +@AllArgsConstructor +public class MenuMetaVo implements Serializable { + + private String title; + + private String icon; + + private Boolean noCache; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/vo/MenuVo.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/vo/MenuVo.java new file mode 100644 index 0000000..82fc0cc --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/vo/MenuVo.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.domain.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; +import java.io.Serializable; +import java.util.List; + +/** + * 构建前端路由时用到 + * @author Zheng Jie + * @date 2018-12-20 + */ +@Data +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class MenuVo implements Serializable { + + private String name; + + private String path; + + private Boolean hidden; + + private String redirect; + + private String component; + + private Boolean alwaysShow; + + private MenuMetaVo meta; + + private List children; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/vo/UserPassVo.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/vo/UserPassVo.java new file mode 100644 index 0000000..e92d472 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/domain/vo/UserPassVo.java @@ -0,0 +1,37 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.domain.vo; + +import lombok.Data; +import me.zhengjie.annotation.CheckPwd; + +import javax.validation.constraints.NotBlank; + +/** + * 修改密码的 Vo 类 + * @author Zheng Jie + * @date 2019年7月11日13:59:49 + */ +@Data +public class UserPassVo { + + private String oldPass; + + // 注:这里传的是加密后的字符串 + @NotBlank +// @CheckPwd + private String newPass; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/DeptRepository.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/DeptRepository.java new file mode 100644 index 0000000..9858322 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/DeptRepository.java @@ -0,0 +1,69 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.repository; + +import me.zhengjie.modules.system.domain.Dept; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import java.util.List; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +public interface DeptRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据 PID 查询 + * @param id pid + * @return / + */ + List findByPid(Long id); + + /** + * 获取顶级部门 + * @return / + */ + List findByPidIsNull(); + + /** + * 根据角色ID 查询 + * @param roleId 角色ID + * @return / + */ + @Query(value = "select d.* from sys_dept d, sys_roles_depts r where " + + "d.dept_id = r.dept_id and r.role_id = ?1", nativeQuery = true) + Set findByRoleId(Long roleId); + + /** + * 判断是否存在子节点 + * @param pid / + * @return / + */ + int countByPid(Long pid); + + /** + * 根据ID更新sub_count + * @param count / + * @param id / + */ + @Modifying + @Query(value = " update sys_dept set sub_count = ?1 where dept_id = ?2 ",nativeQuery = true) + void updateSubCntById(Integer count, Long id); +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/DictDetailRepository.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/DictDetailRepository.java new file mode 100644 index 0000000..d80b970 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/DictDetailRepository.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.repository; + +import me.zhengjie.modules.system.domain.DictDetail; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import java.util.List; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +public interface DictDetailRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据字典名称查询 + * @param name / + * @return / + */ + List findByDictName(String name); +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/DictRepository.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/DictRepository.java new file mode 100644 index 0000000..f09b6d1 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/DictRepository.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.repository; + +import me.zhengjie.modules.system.domain.Dict; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import java.util.List; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +public interface DictRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 删除 + * @param ids / + */ + void deleteByIdIn(Set ids); + + /** + * 查询 + * @param ids / + * @return / + */ + List findByIdIn(Set ids); +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/JobRepository.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/JobRepository.java new file mode 100644 index 0000000..e39ebf0 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/JobRepository.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.repository; + +import me.zhengjie.modules.system.domain.Job; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +public interface JobRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据名称查询 + * @param name 名称 + * @return / + */ + Job findByName(String name); + + /** + * 根据Id删除 + * @param ids / + */ + void deleteAllByIdIn(Set ids); +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/MenuRepository.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/MenuRepository.java new file mode 100644 index 0000000..0907606 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/MenuRepository.java @@ -0,0 +1,85 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.repository; + +import me.zhengjie.modules.system.domain.Menu; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-12-17 + */ +public interface MenuRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据菜单标题查询 + * @param title 菜单标题 + * @return / + */ + Menu findByTitle(String title); + + /** + * 根据组件名称查询 + * @param name 组件名称 + * @return / + */ + Menu findByComponentName(String name); + + /** + * 根据菜单的 PID 查询 + * @param pid / + * @return / + */ + List findByPid(long pid); + + /** + * 查询顶级菜单 + * @return / + */ + List findByPidIsNull(); + + /** + * 根据角色ID与菜单类型查询菜单 + * @param roleIds roleIDs + * @param type 类型 + * @return / + */ + @Query(value = "SELECT m.* FROM sys_menu m, sys_roles_menus r WHERE " + + "m.menu_id = r.menu_id AND r.role_id IN ?1 AND type != ?2 order by m.menu_sort asc",nativeQuery = true) + LinkedHashSet findByRoleIdsAndTypeNot(Set roleIds, int type); + + /** + * 获取节点数量 + * @param id / + * @return / + */ + int countByPid(Long id); + + /** + * 更新节点数目 + * @param count / + * @param menuId / + */ + @Modifying + @Query(value = " update sys_menu set sub_count = ?1 where menu_id = ?2 ",nativeQuery = true) + void updateSubCntById(int count, Long menuId); +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/RoleRepository.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/RoleRepository.java new file mode 100644 index 0000000..8e76cc5 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/RoleRepository.java @@ -0,0 +1,80 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.repository; + +import me.zhengjie.modules.system.domain.Role; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-12-03 + */ +public interface RoleRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据名称查询 + * @param name / + * @return / + */ + Role findByName(String name); + + /** + * 删除多个角色 + * @param ids / + */ + void deleteAllByIdIn(Set ids); + + /** + * 根据用户ID查询 + * @param id 用户ID + * @return / + */ + @Query(value = "SELECT r.* FROM sys_role r, sys_users_roles u WHERE " + + "r.role_id = u.role_id AND u.user_id = ?1",nativeQuery = true) + Set findByUserId(Long id); + + /** + * 解绑角色菜单 + * @param id 菜单ID + */ + @Modifying + @Query(value = "delete from sys_roles_menus where menu_id = ?1",nativeQuery = true) + void untiedMenu(Long id); + + /** + * 根据部门查询 + * @param deptIds / + * @return / + */ + @Query(value = "select count(1) from sys_role r, sys_roles_depts d where " + + "r.role_id = d.role_id and d.dept_id in ?1",nativeQuery = true) + int countByDepts(Set deptIds); + + /** + * 根据菜单Id查询 + * @param menuIds / + * @return / + */ + @Query(value = "SELECT r.* FROM sys_role r, sys_roles_menus m WHERE " + + "r.role_id = m.role_id AND m.menu_id in ?1",nativeQuery = true) + List findInMenuId(List menuIds); +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/UserRepository.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/UserRepository.java new file mode 100644 index 0000000..c5c88a8 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/repository/UserRepository.java @@ -0,0 +1,130 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.repository; + +import me.zhengjie.modules.system.domain.User; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import java.util.Date; +import java.util.List; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-11-22 + */ +public interface UserRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据用户名查询 + * @param username 用户名 + * @return / + */ + User findByUsername(String username); + + /** + * 根据邮箱查询 + * @param email 邮箱 + * @return / + */ + User findByEmail(String email); + + /** + * 根据手机号查询 + * @param phone 手机号 + * @return / + */ + User findByPhone(String phone); + + /** + * 修改密码 + * @param username 用户名 + * @param pass 密码 + * @param lastPasswordResetTime / + */ + @Modifying + @Query(value = "update sys_user set password = ?2 , pwd_reset_time = ?3 where username = ?1",nativeQuery = true) + void updatePass(String username, String pass, Date lastPasswordResetTime); + + /** + * 修改邮箱 + * @param username 用户名 + * @param email 邮箱 + */ + @Modifying + @Query(value = "update sys_user set email = ?2 where username = ?1",nativeQuery = true) + void updateEmail(String username, String email); + + /** + * 根据角色查询用户 + * @param roleId / + * @return / + */ + @Query(value = "SELECT u.* FROM sys_user u, sys_users_roles r WHERE" + + " u.user_id = r.user_id AND r.role_id = ?1", nativeQuery = true) + List findByRoleId(Long roleId); + + /** + * 根据角色中的部门查询 + * @param deptId / + * @return / + */ + @Query(value = "SELECT u.* FROM sys_user u, sys_users_roles r, sys_roles_depts d WHERE " + + "u.user_id = r.user_id AND r.role_id = d.role_id AND d.dept_id = ?1 group by u.user_id", nativeQuery = true) + List findByRoleDeptId(Long deptId); + + /** + * 根据菜单查询 + * @param id 菜单ID + * @return / + */ + @Query(value = "SELECT u.* FROM sys_user u, sys_users_roles ur, sys_roles_menus rm WHERE\n" + + "u.user_id = ur.user_id AND ur.role_id = rm.role_id AND rm.menu_id = ?1 group by u.user_id", nativeQuery = true) + List findByMenuId(Long id); + + /** + * 根据Id删除 + * @param ids / + */ + void deleteAllByIdIn(Set ids); + + /** + * 根据岗位查询 + * @param ids / + * @return / + */ + @Query(value = "SELECT count(1) FROM sys_user u, sys_users_jobs j WHERE u.user_id = j.user_id AND j.job_id IN ?1", nativeQuery = true) + int countByJobs(Set ids); + + /** + * 根据部门查询 + * @param deptIds / + * @return / + */ + @Query(value = "SELECT count(1) FROM sys_user u WHERE u.dept_id IN ?1", nativeQuery = true) + int countByDepts(Set deptIds); + + /** + * 根据角色查询 + * @param ids / + * @return / + */ + @Query(value = "SELECT count(1) FROM sys_user u, sys_users_roles r WHERE " + + "u.user_id = r.user_id AND r.role_id in ?1", nativeQuery = true) + int countByRoles(Set ids); +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/DeptController.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/DeptController.java new file mode 100644 index 0000000..9b3b0ef --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/DeptController.java @@ -0,0 +1,117 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.rest; + +import cn.hutool.core.collection.CollectionUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.system.domain.Dept; +import me.zhengjie.modules.system.service.DeptService; +import me.zhengjie.modules.system.service.dto.DeptDto; +import me.zhengjie.modules.system.service.dto.DeptQueryCriteria; +import me.zhengjie.utils.PageUtil; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.util.*; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:部门管理") +@RequestMapping("/api/dept") +public class DeptController { + + private final DeptService deptService; + private static final String ENTITY_NAME = "dept"; + + @ApiOperation("导出部门数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('dept:list')") + public void download(HttpServletResponse response, DeptQueryCriteria criteria) throws Exception { + deptService.download(deptService.queryAll(criteria, false), response); + } + + @ApiOperation("查询部门") + @GetMapping + @PreAuthorize("@el.check('user:list','dept:list')") + public ResponseEntity query(DeptQueryCriteria criteria) throws Exception { + List deptDtos = deptService.queryAll(criteria, true); + return new ResponseEntity<>(PageUtil.toPage(deptDtos, deptDtos.size()),HttpStatus.OK); + } + + @ApiOperation("查询部门:根据ID获取同级与上级数据") + @PostMapping("/superior") + @PreAuthorize("@el.check('user:list','dept:list')") + public ResponseEntity getSuperior(@RequestBody List ids) { + Set deptDtos = new LinkedHashSet<>(); + for (Long id : ids) { + DeptDto deptDto = deptService.findById(id); + List depts = deptService.getSuperior(deptDto, new ArrayList<>()); + deptDtos.addAll(depts); + } + return new ResponseEntity<>(deptService.buildTree(new ArrayList<>(deptDtos)),HttpStatus.OK); + } + + @Log("新增部门") + @ApiOperation("新增部门") + @PostMapping + @PreAuthorize("@el.check('dept:add')") + public ResponseEntity create(@Validated @RequestBody Dept resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + deptService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改部门") + @ApiOperation("修改部门") + @PutMapping + @PreAuthorize("@el.check('dept:edit')") + public ResponseEntity update(@Validated(Dept.Update.class) @RequestBody Dept resources){ + deptService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除部门") + @ApiOperation("删除部门") + @DeleteMapping + @PreAuthorize("@el.check('dept:del')") + public ResponseEntity delete(@RequestBody Set ids){ + Set deptDtos = new HashSet<>(); + for (Long id : ids) { + List deptList = deptService.findByPid(id); + deptDtos.add(deptService.findById(id)); + if(CollectionUtil.isNotEmpty(deptList)){ + deptDtos = deptService.getDeleteDepts(deptList, deptDtos); + } + } + // 验证是否被角色或用户关联 + deptService.verification(deptDtos); + deptService.delete(deptDtos); + return new ResponseEntity<>(HttpStatus.OK); + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/DictController.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/DictController.java new file mode 100644 index 0000000..f1e4d58 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/DictController.java @@ -0,0 +1,99 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.system.domain.Dict; +import me.zhengjie.modules.system.service.DictService; +import me.zhengjie.modules.system.service.dto.DictQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:字典管理") +@RequestMapping("/api/dict") +public class DictController { + + private final DictService dictService; + private static final String ENTITY_NAME = "dict"; + + @ApiOperation("导出字典数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('dict:list')") + public void download(HttpServletResponse response, DictQueryCriteria criteria) throws IOException { + dictService.download(dictService.queryAll(criteria), response); + } + + @ApiOperation("查询字典") + @GetMapping(value = "/all") + @PreAuthorize("@el.check('dict:list')") + public ResponseEntity queryAll(){ + return new ResponseEntity<>(dictService.queryAll(new DictQueryCriteria()),HttpStatus.OK); + } + + @ApiOperation("查询字典") + @GetMapping + @PreAuthorize("@el.check('dict:list')") + public ResponseEntity query(DictQueryCriteria resources, Pageable pageable){ + return new ResponseEntity<>(dictService.queryAll(resources,pageable),HttpStatus.OK); + } + + @Log("新增字典") + @ApiOperation("新增字典") + @PostMapping + @PreAuthorize("@el.check('dict:add')") + public ResponseEntity create(@Validated @RequestBody Dict resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + dictService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改字典") + @ApiOperation("修改字典") + @PutMapping + @PreAuthorize("@el.check('dict:edit')") + public ResponseEntity update(@Validated(Dict.Update.class) @RequestBody Dict resources){ + dictService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除字典") + @ApiOperation("删除字典") + @DeleteMapping + @PreAuthorize("@el.check('dict:del')") + public ResponseEntity delete(@RequestBody Set ids){ + dictService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/DictDetailController.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/DictDetailController.java new file mode 100644 index 0000000..92f65fd --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/DictDetailController.java @@ -0,0 +1,99 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.system.domain.DictDetail; +import me.zhengjie.modules.system.service.DictDetailService; +import me.zhengjie.modules.system.service.dto.DictDetailDto; +import me.zhengjie.modules.system.service.dto.DictDetailQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.web.PageableDefault; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:字典详情管理") +@RequestMapping("/api/dictDetail") +public class DictDetailController { + + private final DictDetailService dictDetailService; + private static final String ENTITY_NAME = "dictDetail"; + + @ApiOperation("查询字典详情") + @GetMapping + public ResponseEntity query(DictDetailQueryCriteria criteria, + @PageableDefault(sort = {"dictSort"}, direction = Sort.Direction.ASC) Pageable pageable){ + return new ResponseEntity<>(dictDetailService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @ApiOperation("查询多个字典详情") + @GetMapping(value = "/map") + public ResponseEntity getDictDetailMaps(@RequestParam String dictName){ + String[] names = dictName.split("[,,]"); + Map> dictMap = new HashMap<>(16); + for (String name : names) { + dictMap.put(name, dictDetailService.getDictByName(name)); + } + return new ResponseEntity<>(dictMap, HttpStatus.OK); + } + + @Log("新增字典详情") + @ApiOperation("新增字典详情") + @PostMapping + @PreAuthorize("@el.check('dict:add')") + public ResponseEntity create(@Validated @RequestBody DictDetail resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + dictDetailService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改字典详情") + @ApiOperation("修改字典详情") + @PutMapping + @PreAuthorize("@el.check('dict:edit')") + public ResponseEntity update(@Validated(DictDetail.Update.class) @RequestBody DictDetail resources){ + dictDetailService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除字典详情") + @ApiOperation("删除字典详情") + @DeleteMapping(value = "/{id}") + @PreAuthorize("@el.check('dict:del')") + public ResponseEntity delete(@PathVariable Long id){ + dictDetailService.delete(id); + return new ResponseEntity<>(HttpStatus.OK); + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/JobController.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/JobController.java new file mode 100644 index 0000000..cac14c0 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/JobController.java @@ -0,0 +1,94 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.system.domain.Job; +import me.zhengjie.modules.system.service.JobService; +import me.zhengjie.modules.system.service.dto.JobQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:岗位管理") +@RequestMapping("/api/job") +public class JobController { + + private final JobService jobService; + private static final String ENTITY_NAME = "job"; + + @ApiOperation("导出岗位数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('job:list')") + public void download(HttpServletResponse response, JobQueryCriteria criteria) throws IOException { + jobService.download(jobService.queryAll(criteria), response); + } + + @ApiOperation("查询岗位") + @GetMapping + @PreAuthorize("@el.check('job:list','user:list')") + public ResponseEntity query(JobQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(jobService.queryAll(criteria, pageable),HttpStatus.OK); + } + + @Log("新增岗位") + @ApiOperation("新增岗位") + @PostMapping + @PreAuthorize("@el.check('job:add')") + public ResponseEntity create(@Validated @RequestBody Job resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + jobService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改岗位") + @ApiOperation("修改岗位") + @PutMapping + @PreAuthorize("@el.check('job:edit')") + public ResponseEntity update(@Validated(Job.Update.class) @RequestBody Job resources){ + jobService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除岗位") + @ApiOperation("删除岗位") + @DeleteMapping + @PreAuthorize("@el.check('job:del')") + public ResponseEntity delete(@RequestBody Set ids){ + // 验证是否被用户关联 + jobService.verification(ids); + jobService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/LimitController.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/LimitController.java new file mode 100644 index 0000000..329c5ac --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/LimitController.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import me.zhengjie.annotation.Limit; +import me.zhengjie.annotation.rest.AnonymousGetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author / + * 接口限流测试类 + */ +@RestController +@RequestMapping("/api/limit") +@Api(tags = "系统:限流测试管理") +public class LimitController { + + private static final AtomicInteger ATOMIC_INTEGER = new AtomicInteger(); + + /** + * 测试限流注解,下面配置说明该接口 60秒内最多只能访问 10次,保存到redis的键名为 limit_test, + */ + @AnonymousGetMapping + @ApiOperation("测试") + @Limit(key = "test", period = 60, count = 10, name = "testLimit", prefix = "limit") + public int test() { + return ATOMIC_INTEGER.incrementAndGet(); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/MenuController.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/MenuController.java new file mode 100644 index 0000000..d5461a2 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/MenuController.java @@ -0,0 +1,147 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.rest; + +import cn.hutool.core.collection.CollectionUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.modules.system.domain.Menu; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.system.service.MenuService; +import me.zhengjie.modules.system.service.dto.MenuDto; +import me.zhengjie.modules.system.service.dto.MenuQueryCriteria; +import me.zhengjie.modules.system.service.mapstruct.MenuMapper; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.SecurityUtils; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + * @date 2018-12-03 + */ + +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:菜单管理") +@RequestMapping("/api/menus") +public class MenuController { + + private final MenuService menuService; + private final MenuMapper menuMapper; + private static final String ENTITY_NAME = "menu"; + + @ApiOperation("导出菜单数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('menu:list')") + public void download(HttpServletResponse response, MenuQueryCriteria criteria) throws Exception { + menuService.download(menuService.queryAll(criteria, false), response); + } + + @GetMapping(value = "/build") + @ApiOperation("获取前端所需菜单") + public ResponseEntity buildMenus(){ + List menuDtoList = menuService.findByUser(SecurityUtils.getCurrentUserId()); + List menuDtos = menuService.buildTree(menuDtoList); + return new ResponseEntity<>(menuService.buildMenus(menuDtos),HttpStatus.OK); + } + + @ApiOperation("返回全部的菜单") + @GetMapping(value = "/lazy") + @PreAuthorize("@el.check('menu:list','roles:list')") + public ResponseEntity query(@RequestParam Long pid){ + return new ResponseEntity<>(menuService.getMenus(pid),HttpStatus.OK); + } + + @ApiOperation("根据菜单ID返回所有子节点ID,包含自身ID") + @GetMapping(value = "/child") + @PreAuthorize("@el.check('menu:list','roles:list')") + public ResponseEntity child(@RequestParam Long id){ + Set menuSet = new HashSet<>(); + List menuList = menuService.getMenus(id); + menuSet.add(menuService.findOne(id)); + menuSet = menuService.getChildMenus(menuMapper.toEntity(menuList), menuSet); + Set ids = menuSet.stream().map(Menu::getId).collect(Collectors.toSet()); + return new ResponseEntity<>(ids,HttpStatus.OK); + } + + @GetMapping + @ApiOperation("查询菜单") + @PreAuthorize("@el.check('menu:list')") + public ResponseEntity query(MenuQueryCriteria criteria) throws Exception { + List menuDtoList = menuService.queryAll(criteria, true); + return new ResponseEntity<>(PageUtil.toPage(menuDtoList, menuDtoList.size()),HttpStatus.OK); + } + + @ApiOperation("查询菜单:根据ID获取同级与上级数据") + @PostMapping("/superior") + @PreAuthorize("@el.check('menu:list')") + public ResponseEntity getSuperior(@RequestBody List ids) { + Set menuDtos = new LinkedHashSet<>(); + if(CollectionUtil.isNotEmpty(ids)){ + for (Long id : ids) { + MenuDto menuDto = menuService.findById(id); + menuDtos.addAll(menuService.getSuperior(menuDto, new ArrayList<>())); + } + return new ResponseEntity<>(menuService.buildTree(new ArrayList<>(menuDtos)),HttpStatus.OK); + } + return new ResponseEntity<>(menuService.getMenus(null),HttpStatus.OK); + } + + @Log("新增菜单") + @ApiOperation("新增菜单") + @PostMapping + @PreAuthorize("@el.check('menu:add')") + public ResponseEntity create(@Validated @RequestBody Menu resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + menuService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改菜单") + @ApiOperation("修改菜单") + @PutMapping + @PreAuthorize("@el.check('menu:edit')") + public ResponseEntity update(@Validated(Menu.Update.class) @RequestBody Menu resources){ + menuService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除菜单") + @ApiOperation("删除菜单") + @DeleteMapping + @PreAuthorize("@el.check('menu:del')") + public ResponseEntity delete(@RequestBody Set ids){ + Set menuSet = new HashSet<>(); + for (Long id : ids) { + List menuList = menuService.getMenus(id); + menuSet.add(menuService.findOne(id)); + menuSet = menuService.getChildMenus(menuMapper.toEntity(menuList), menuSet); + } + menuService.delete(menuSet); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/MonitorController.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/MonitorController.java new file mode 100644 index 0000000..35ac0c5 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/MonitorController.java @@ -0,0 +1,45 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.modules.system.service.MonitorService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +/** + * @author Zheng Jie + * @date 2020-05-02 + */ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统-服务监控管理") +@RequestMapping("/api/monitor") +public class MonitorController { + + private final MonitorService serverService; + + @GetMapping + @ApiOperation("查询服务监控") + @PreAuthorize("@el.check('monitor:list')") + public ResponseEntity query(){ + return new ResponseEntity<>(serverService.getServers(),HttpStatus.OK); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/RoleController.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/RoleController.java new file mode 100644 index 0000000..a1edc93 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/RoleController.java @@ -0,0 +1,154 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.rest; + +import cn.hutool.core.lang.Dict; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.modules.system.domain.Role; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.system.service.RoleService; +import me.zhengjie.modules.system.service.dto.RoleDto; +import me.zhengjie.modules.system.service.dto.RoleQueryCriteria; +import me.zhengjie.modules.system.service.dto.RoleSmallDto; +import me.zhengjie.utils.SecurityUtils; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + * @date 2018-12-03 + */ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:角色管理") +@RequestMapping("/api/roles") +public class RoleController { + + private final RoleService roleService; + + private static final String ENTITY_NAME = "role"; + + @ApiOperation("获取单个role") + @GetMapping(value = "/{id}") + @PreAuthorize("@el.check('roles:list')") + public ResponseEntity query(@PathVariable Long id){ + return new ResponseEntity<>(roleService.findById(id), HttpStatus.OK); + } + + @ApiOperation("导出角色数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('role:list')") + public void download(HttpServletResponse response, RoleQueryCriteria criteria) throws IOException { + roleService.download(roleService.queryAll(criteria), response); + } + + @ApiOperation("返回全部的角色") + @GetMapping(value = "/all") + @PreAuthorize("@el.check('roles:list','user:add','user:edit')") + public ResponseEntity query(){ + return new ResponseEntity<>(roleService.queryAll(),HttpStatus.OK); + } + + @ApiOperation("查询角色") + @GetMapping + @PreAuthorize("@el.check('roles:list')") + public ResponseEntity query(RoleQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(roleService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @ApiOperation("获取用户级别") + @GetMapping(value = "/level") + public ResponseEntity getLevel(){ + return new ResponseEntity<>(Dict.create().set("level", getLevels(null)),HttpStatus.OK); + } + + @Log("新增角色") + @ApiOperation("新增角色") + @PostMapping + @PreAuthorize("@el.check('roles:add')") + public ResponseEntity create(@Validated @RequestBody Role resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + getLevels(resources.getLevel()); + roleService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改角色") + @ApiOperation("修改角色") + @PutMapping + @PreAuthorize("@el.check('roles:edit')") + public ResponseEntity update(@Validated(Role.Update.class) @RequestBody Role resources){ + getLevels(resources.getLevel()); + roleService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("修改角色菜单") + @ApiOperation("修改角色菜单") + @PutMapping(value = "/menu") + @PreAuthorize("@el.check('roles:edit')") + public ResponseEntity updateMenu(@RequestBody Role resources){ + RoleDto role = roleService.findById(resources.getId()); + getLevels(role.getLevel()); + roleService.updateMenu(resources,role); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除角色") + @ApiOperation("删除角色") + @DeleteMapping + @PreAuthorize("@el.check('roles:del')") + public ResponseEntity delete(@RequestBody Set ids){ + for (Long id : ids) { + RoleDto role = roleService.findById(id); + getLevels(role.getLevel()); + } + // 验证是否被用户关联 + roleService.verification(ids); + roleService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + /** + * 获取用户的角色级别 + * @return / + */ + private int getLevels(Integer level){ + List levels = roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()); + int min = Collections.min(levels); + if(level != null){ + if(level < min){ + throw new BadRequestException("权限不足,你的角色级别:" + min + ",低于操作的角色级别:" + level); + } + } + return min; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/UserController.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/UserController.java new file mode 100644 index 0000000..a5e6dca --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/UserController.java @@ -0,0 +1,230 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.rest; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.base.BaseEntity; +import me.zhengjie.config.RsaProperties; +import me.zhengjie.dto.Dto; +import me.zhengjie.modules.system.domain.Dept; +import me.zhengjie.modules.system.service.DataService; +import me.zhengjie.modules.system.domain.User; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.system.domain.vo.UserPassVo; +import me.zhengjie.modules.system.service.DeptService; +import me.zhengjie.modules.system.service.RoleService; +import me.zhengjie.modules.system.service.dto.RoleSmallDto; +import me.zhengjie.modules.system.service.dto.UserDto; +import me.zhengjie.modules.system.service.dto.UserQueryCriteria; +import me.zhengjie.modules.system.service.VerifyService; +import me.zhengjie.utils.*; +import me.zhengjie.modules.system.service.UserService; +import me.zhengjie.utils.enums.CodeEnum; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Api(tags = "系统:用户管理") +@RestController +@RequestMapping("/api/users") +@RequiredArgsConstructor +public class UserController { + + private final PasswordEncoder passwordEncoder; + private final UserService userService; + private final DataService dataService; + private final DeptService deptService; + private final RoleService roleService; + private final VerifyService verificationCodeService; + private final RedisUtils redisUtils; + + @ApiOperation("导出用户数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('user:list')") + public void download(HttpServletResponse response, UserQueryCriteria criteria) throws IOException { + userService.download(userService.queryAll(criteria), response); + } + + @ApiOperation("查询用户") + @GetMapping + @PreAuthorize("@el.check('user:list')") + public ResponseEntity query(UserQueryCriteria criteria, Pageable pageable){ + if (!ObjectUtils.isEmpty(criteria.getDeptId())) { + criteria.getDeptIds().add(criteria.getDeptId()); + // 先查找是否存在子节点 + List data = deptService.findByPid(criteria.getDeptId()); + // 然后把子节点的ID都加入到集合中 + criteria.getDeptIds().addAll(deptService.getDeptChildren(data)); + } + // 数据权限 + List dataScopes = dataService.getDeptIds(userService.findByName(SecurityUtils.getCurrentUsername())); + // criteria.getDeptIds() 不为空并且数据权限不为空则取交集 + if (!CollectionUtils.isEmpty(criteria.getDeptIds()) && !CollectionUtils.isEmpty(dataScopes)){ + // 取交集 + criteria.getDeptIds().retainAll(dataScopes); + if(!CollectionUtil.isEmpty(criteria.getDeptIds())){ + return new ResponseEntity<>(userService.queryAll(criteria,pageable),HttpStatus.OK); + } + } else { + // 否则取并集 + criteria.getDeptIds().addAll(dataScopes); + return new ResponseEntity<>(userService.queryAll(criteria,pageable),HttpStatus.OK); + } + return new ResponseEntity<>(PageUtil.toPage(null,0),HttpStatus.OK); + } + + /** + * 解冻账号 + * @author: zeng + */ + @GetMapping("/unfreeze") + @PreAuthorize("@el.check('user:list')") + public Dto unfreeze(String username) { + if (ObjectUtil.isEmpty(username)) { + return Dto.returnResult(null); + } + String key = String.format(RedisUtils.BLOCKED_ACCOUNT, username); + redisUtils.del(key); + return Dto.returnResult(true); + } + + @Log("新增用户") + @ApiOperation("新增用户") + @PostMapping + @PreAuthorize("@el.check('user:add')") + public ResponseEntity create(@Validated(BaseEntity.Create.class) @RequestBody User resources){ + checkLevel(resources); + // 默认密码 123456 + resources.setPassword(passwordEncoder.encode(resources.getPassword())); + userService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改用户") + @ApiOperation("修改用户") + @PutMapping + @PreAuthorize("@el.check('user:edit')") + public ResponseEntity update(@Validated(User.Update.class) @RequestBody User resources) throws Exception { + checkLevel(resources); + userService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("修改用户:个人中心") + @ApiOperation("修改用户:个人中心") + @PutMapping(value = "center") + public ResponseEntity center(@Validated(User.Update.class) @RequestBody User resources){ + if(!resources.getId().equals(SecurityUtils.getCurrentUserId())){ + throw new BadRequestException("不能修改他人资料"); + } + userService.updateCenter(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除用户") + @ApiOperation("删除用户") + @DeleteMapping + @PreAuthorize("@el.check('user:del')") + public ResponseEntity delete(@RequestBody Set ids){ + for (Long id : ids) { + Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); + Integer optLevel = Collections.min(roleService.findByUsersId(id).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); + if (currentLevel > optLevel) { + throw new BadRequestException("角色权限不足,不能删除:" + userService.findById(id).getUsername()); + } + } + userService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + /** + * 修改密码 + * @param passVo 修改密码DTO + * @return + * @throws Exception + */ + @ApiOperation("修改密码") + @PostMapping(value = "/updatePass") + public ResponseEntity updatePass(@RequestBody @Validated UserPassVo passVo) throws Exception { + String oldPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,passVo.getOldPass()); + String newPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,passVo.getNewPass()); + UserDto user = userService.findByName(SecurityUtils.getCurrentUsername()); + if(!passwordEncoder.matches(oldPass, user.getPassword())){ + throw new BadRequestException("修改失败,旧密码错误"); + } + if(passwordEncoder.matches(newPass, user.getPassword())){ + throw new BadRequestException("新密码不能与旧密码相同"); + } + if (!Pattern.matches(CheckPwdValidator.p, newPass)) { + throw new BadRequestException("密码格式错误,必须包含大小写字母、数子、英文特殊符号,且长度在16~64之间!"); + } + userService.updatePass(user.getUsername(),passwordEncoder.encode(newPass)); + return new ResponseEntity<>(HttpStatus.OK); + } + + @ApiOperation("修改头像") + @PostMapping(value = "/updateAvatar") + public ResponseEntity updateAvatar(@RequestParam MultipartFile avatar){ + return new ResponseEntity<>(userService.updateAvatar(avatar), HttpStatus.OK); + } + + @Log("修改邮箱") + @ApiOperation("修改邮箱") + @PostMapping(value = "/updateEmail/{code}") + public ResponseEntity updateEmail(@PathVariable String code,@RequestBody User user) throws Exception { + String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,user.getPassword()); + UserDto userDto = userService.findByName(SecurityUtils.getCurrentUsername()); + if(!passwordEncoder.matches(password, userDto.getPassword())){ + throw new BadRequestException("密码错误"); + } + verificationCodeService.validated(CodeEnum.EMAIL_RESET_EMAIL_CODE.getKey() + user.getEmail(), code); + userService.updateEmail(userDto.getUsername(),user.getEmail()); + return new ResponseEntity<>(HttpStatus.OK); + } + + /** + * 如果当前用户的角色级别低于创建用户的角色级别,则抛出权限不足的错误 + * @param resources / + */ + private void checkLevel(User resources) { + Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); + Integer optLevel = roleService.findByRoles(resources.getRoles()); + if (currentLevel > optLevel) { + throw new BadRequestException("角色权限不足"); + } + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/VerifyController.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/VerifyController.java new file mode 100644 index 0000000..09ba44b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/rest/VerifyController.java @@ -0,0 +1,76 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.domain.vo.EmailVo; +import me.zhengjie.service.EmailService; +import me.zhengjie.modules.system.service.VerifyService; +import me.zhengjie.utils.enums.CodeBiEnum; +import me.zhengjie.utils.enums.CodeEnum; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import java.util.Objects; + +/** + * @author Zheng Jie + * @date 2018-12-26 + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/code") +@Api(tags = "系统:验证码管理") +public class VerifyController { + + private final VerifyService verificationCodeService; + private final EmailService emailService; + + @PostMapping(value = "/resetEmail") + @ApiOperation("重置邮箱,发送验证码") + public ResponseEntity resetEmail(@RequestParam String email){ + EmailVo emailVo = verificationCodeService.sendEmail(email, CodeEnum.EMAIL_RESET_EMAIL_CODE.getKey()); + emailService.send(emailVo,emailService.find()); + return new ResponseEntity<>(HttpStatus.OK); + } + + @PostMapping(value = "/email/resetPass") + @ApiOperation("重置密码,发送验证码") + public ResponseEntity resetPass(@RequestParam String email){ + EmailVo emailVo = verificationCodeService.sendEmail(email, CodeEnum.EMAIL_RESET_PWD_CODE.getKey()); + emailService.send(emailVo,emailService.find()); + return new ResponseEntity<>(HttpStatus.OK); + } + + @GetMapping(value = "/validated") + @ApiOperation("验证码验证") + public ResponseEntity validated(@RequestParam String email, @RequestParam String code, @RequestParam Integer codeBi){ + CodeBiEnum biEnum = CodeBiEnum.find(codeBi); + switch (Objects.requireNonNull(biEnum)){ + case ONE: + verificationCodeService.validated(CodeEnum.EMAIL_RESET_EMAIL_CODE.getKey() + email ,code); + break; + case TWO: + verificationCodeService.validated(CodeEnum.EMAIL_RESET_PWD_CODE.getKey() + email ,code); + break; + default: + break; + } + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/DataService.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/DataService.java new file mode 100644 index 0000000..10258d9 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/DataService.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service; + +import me.zhengjie.modules.system.service.dto.UserDto; +import java.util.List; + +/** + * 数据权限服务类 + * @author Zheng Jie + * @date 2020-05-07 + */ +public interface DataService { + + /** + * 获取数据权限 + * @param user / + * @return / + */ + List getDeptIds(UserDto user); +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/DeptService.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/DeptService.java new file mode 100644 index 0000000..d589bf8 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/DeptService.java @@ -0,0 +1,124 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service; + +import me.zhengjie.modules.system.domain.Dept; +import me.zhengjie.modules.system.service.dto.DeptDto; +import me.zhengjie.modules.system.service.dto.DeptQueryCriteria; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +public interface DeptService { + + /** + * 查询所有数据 + * @param criteria 条件 + * @param isQuery / + * @throws Exception / + * @return / + */ + List queryAll(DeptQueryCriteria criteria, Boolean isQuery) throws Exception; + + /** + * 根据ID查询 + * @param id / + * @return / + */ + DeptDto findById(Long id); + + /** + * 创建 + * @param resources / + */ + void create(Dept resources); + + /** + * 编辑 + * @param resources / + */ + void update(Dept resources); + + /** + * 删除 + * @param deptDtos / + * + */ + void delete(Set deptDtos); + + /** + * 根据PID查询 + * @param pid / + * @return / + */ + List findByPid(long pid); + + /** + * 根据角色ID查询 + * @param id / + * @return / + */ + Set findByRoleId(Long id); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 获取待删除的部门 + * @param deptList / + * @param deptDtos / + * @return / + */ + Set getDeleteDepts(List deptList, Set deptDtos); + + /** + * 根据ID获取同级与上级数据 + * @param deptDto / + * @param depts / + * @return / + */ + List getSuperior(DeptDto deptDto, List depts); + + /** + * 构建树形数据 + * @param deptDtos / + * @return / + */ + Object buildTree(List deptDtos); + + /** + * 获取 + * @param deptList + * @return + */ + List getDeptChildren(List deptList); + + /** + * 验证是否被角色或用户关联 + * @param deptDtos / + */ + void verification(Set deptDtos); +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/DictDetailService.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/DictDetailService.java new file mode 100644 index 0000000..3912a47 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/DictDetailService.java @@ -0,0 +1,63 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service; + +import me.zhengjie.modules.system.domain.DictDetail; +import me.zhengjie.modules.system.service.dto.DictDetailDto; +import me.zhengjie.modules.system.service.dto.DictDetailQueryCriteria; +import org.springframework.data.domain.Pageable; +import java.util.List; +import java.util.Map; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +public interface DictDetailService { + + /** + * 创建 + * @param resources / + */ + void create(DictDetail resources); + + /** + * 编辑 + * @param resources / + */ + void update(DictDetail resources); + + /** + * 删除 + * @param id / + */ + void delete(Long id); + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Map queryAll(DictDetailQueryCriteria criteria, Pageable pageable); + + /** + * 根据字典名称获取字典详情 + * @param name 字典名称 + * @return / + */ + List getDictByName(String name); +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/DictService.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/DictService.java new file mode 100644 index 0000000..9a89e4c --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/DictService.java @@ -0,0 +1,75 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service; + +import me.zhengjie.modules.system.domain.Dict; +import me.zhengjie.modules.system.service.dto.DictDto; +import me.zhengjie.modules.system.service.dto.DictQueryCriteria; +import org.springframework.data.domain.Pageable; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +public interface DictService { + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Map queryAll(DictQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部数据 + * @param dict / + * @return / + */ + List queryAll(DictQueryCriteria dict); + + /** + * 创建 + * @param resources / + * @return / + */ + void create(Dict resources); + + /** + * 编辑 + * @param resources / + */ + void update(Dict resources); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/JobService.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/JobService.java new file mode 100644 index 0000000..21c1c98 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/JobService.java @@ -0,0 +1,93 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service; + +import me.zhengjie.modules.system.domain.Job; +import me.zhengjie.modules.system.service.dto.JobDto; +import me.zhengjie.modules.system.service.dto.JobQueryCriteria; +import org.springframework.data.domain.Pageable; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +public interface JobService { + + /** + * 根据ID查询 + * @param id / + * @return / + */ + JobDto findById(Long id); + + /** + * 创建 + * @param resources / + * @return / + */ + void create(Job resources); + + /** + * 编辑 + * @param resources / + */ + void update(Job resources); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 删除 + */ + void delete(); + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Map queryAll(JobQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部数据 + * @param criteria / + * @return / + */ + List queryAll(JobQueryCriteria criteria); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 验证是否被用户关联 + * @param ids / + */ + void verification(Set ids); +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/MenuService.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/MenuService.java new file mode 100644 index 0000000..f7b8ece --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/MenuService.java @@ -0,0 +1,125 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service; + +import me.zhengjie.modules.system.domain.Menu; +import me.zhengjie.modules.system.service.dto.MenuDto; +import me.zhengjie.modules.system.service.dto.MenuQueryCriteria; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-12-17 + */ +public interface MenuService { + + /** + * 查询全部数据 + * @param criteria 条件 + * @param isQuery / + * @throws Exception / + * @return / + */ + List queryAll(MenuQueryCriteria criteria, Boolean isQuery) throws Exception; + + /** + * 根据ID查询 + * @param id / + * @return / + */ + MenuDto findById(long id); + + /** + * 创建 + * @param resources / + */ + void create(Menu resources); + + /** + * 编辑 + * @param resources / + */ + void update(Menu resources); + + /** + * 获取所有子节点,包含自身ID + * @param menuList / + * @param menuSet / + * @return / + */ + Set getChildMenus(List menuList, Set menuSet); + + /** + * 构建菜单树 + * @param menuDtos 原始数据 + * @return / + */ + List buildTree(List menuDtos); + + /** + * 构建菜单树 + * @param menuDtos / + * @return / + */ + Object buildMenus(List menuDtos); + + /** + * 根据ID查询 + * @param id / + * @return / + */ + Menu findOne(Long id); + + /** + * 删除 + * @param menuSet / + */ + void delete(Set menuSet); + + /** + * 导出 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 懒加载菜单数据 + * @param pid / + * @return / + */ + List getMenus(Long pid); + + /** + * 根据ID获取同级与上级数据 + * @param menuDto / + * @param objects / + * @return / + */ + List getSuperior(MenuDto menuDto, List objects); + + /** + * 根据当前用户获取菜单 + * @param currentUserId / + * @return / + */ + List findByUser(Long currentUserId); +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/MonitorService.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/MonitorService.java new file mode 100644 index 0000000..478225a --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/MonitorService.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service; + +import java.util.Map; + +/** + * @author Zheng Jie + * @date 2020-05-02 + */ +public interface MonitorService { + + /** + * 查询数据分页 + * @return Map + */ + Map getServers(); +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/RoleService.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/RoleService.java new file mode 100644 index 0000000..65e4f58 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/RoleService.java @@ -0,0 +1,136 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service; + +import me.zhengjie.modules.system.domain.Role; +import me.zhengjie.modules.system.service.dto.RoleDto; +import me.zhengjie.modules.system.service.dto.RoleQueryCriteria; +import me.zhengjie.modules.system.service.dto.RoleSmallDto; +import me.zhengjie.modules.system.service.dto.UserDto; +import org.springframework.data.domain.Pageable; +import org.springframework.security.core.GrantedAuthority; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-12-03 + */ +public interface RoleService { + + /** + * 查询全部数据 + * @return / + */ + List queryAll(); + + /** + * 根据ID查询 + * @param id / + * @return / + */ + RoleDto findById(long id); + + /** + * 创建 + * @param resources / + */ + void create(Role resources); + + /** + * 编辑 + * @param resources / + */ + void update(Role resources); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 根据用户ID查询 + * @param id 用户ID + * @return / + */ + List findByUsersId(Long id); + + /** + * 根据角色查询角色级别 + * @param roles / + * @return / + */ + Integer findByRoles(Set roles); + + /** + * 修改绑定的菜单 + * @param resources / + * @param roleDTO / + */ + void updateMenu(Role resources, RoleDto roleDTO); + + /** + * 解绑菜单 + * @param id / + */ + void untiedMenu(Long id); + + /** + * 待条件分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(RoleQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部 + * @param criteria 条件 + * @return / + */ + List queryAll(RoleQueryCriteria criteria); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 获取用户权限信息 + * @param user 用户信息 + * @return 权限信息 + */ + List mapToGrantedAuthorities(UserDto user); + + /** + * 验证是否被用户关联 + * @param ids / + */ + void verification(Set ids); + + /** + * 根据菜单Id查询 + * @param menuIds / + * @return / + */ + List findInMenuId(List menuIds); +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/UserService.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/UserService.java new file mode 100644 index 0000000..814af92 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/UserService.java @@ -0,0 +1,116 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service; + +import me.zhengjie.modules.system.domain.User; +import me.zhengjie.modules.system.service.dto.UserDto; +import me.zhengjie.modules.system.service.dto.UserQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +public interface UserService { + + /** + * 根据ID查询 + * @param id ID + * @return / + */ + UserDto findById(long id); + + /** + * 新增用户 + * @param resources / + */ + void create(User resources); + + /** + * 编辑用户 + * @param resources / + */ + void update(User resources) throws Exception; + + /** + * 删除用户 + * @param ids / + */ + void delete(Set ids); + + /** + * 根据用户名查询 + * @param userName / + * @return / + */ + UserDto findByName(String userName); + + /** + * 修改密码 + * @param username 用户名 + * @param encryptPassword 密码 + */ + void updatePass(String username, String encryptPassword); + + /** + * 修改头像 + * @param file 文件 + * @return / + */ + Map updateAvatar(MultipartFile file); + + /** + * 修改邮箱 + * @param username 用户名 + * @param email 邮箱 + */ + void updateEmail(String username, String email); + + /** + * 查询全部 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(UserQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部不分页 + * @param criteria 条件 + * @return / + */ + List queryAll(UserQueryCriteria criteria); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 用户自助修改资料 + * @param resources / + */ + void updateCenter(User resources); +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/VerifyService.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/VerifyService.java new file mode 100644 index 0000000..4ca39b9 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/VerifyService.java @@ -0,0 +1,41 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service; + +import me.zhengjie.domain.vo.EmailVo; + +/** + * @author Zheng Jie + * @date 2018-12-26 + */ +public interface VerifyService { + + /** + * 发送验证码 + * @param email / + * @param key / + * @return / + */ + EmailVo sendEmail(String email, String key); + + + /** + * 验证 + * @param code / + * @param key / + */ + void validated(String key, String code); +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DeptDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DeptDto.java new file mode 100644 index 0000000..4c3b12a --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DeptDto.java @@ -0,0 +1,78 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseDTO; +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +@Getter +@Setter +public class DeptDto extends BaseDTO implements Serializable { + + private Long id; + + private String name; + + private Boolean enabled; + + private Integer deptSort; + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; + + private Long pid; + + private Integer subCount; + + public Boolean getHasChildren() { + return subCount > 0; + } + + public Boolean getLeaf() { + return subCount <= 0; + } + + public String getLabel() { + return name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DeptDto deptDto = (DeptDto) o; + return Objects.equals(id, deptDto.id) && + Objects.equals(name, deptDto.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DeptQueryCriteria.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DeptQueryCriteria.java new file mode 100644 index 0000000..4d8cdf2 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DeptQueryCriteria.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.DataPermission; +import me.zhengjie.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +@Data +@DataPermission(fieldName = "id") +public class DeptQueryCriteria{ + + @Query(type = Query.Type.INNER_LIKE) + private String name; + + @Query + private Boolean enabled; + + @Query + private Long pid; + + @Query(type = Query.Type.IS_NULL, propName = "pid") + private Boolean pidIsNull; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DeptSmallDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DeptSmallDto.java new file mode 100644 index 0000000..4dc64e5 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DeptSmallDto.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Data; +import java.io.Serializable; + +/** +* @author Zheng Jie +* @date 2019-6-10 16:32:18 +*/ +@Data +public class DeptSmallDto implements Serializable { + + private Long id; + + private String name; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictDetailDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictDetailDto.java new file mode 100644 index 0000000..a4b931b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictDetailDto.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseDTO; +import java.io.Serializable; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Getter +@Setter +public class DictDetailDto extends BaseDTO implements Serializable { + + private Long id; + + private DictSmallDto dict; + + private String label; + + private String value; + + private Integer dictSort; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictDetailQueryCriteria.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictDetailQueryCriteria.java new file mode 100644 index 0000000..91a01b1 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictDetailQueryCriteria.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Data +public class DictDetailQueryCriteria { + + @Query(type = Query.Type.INNER_LIKE) + private String label; + + @Query(propName = "name",joinName = "dict") + private String dictName; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictDto.java new file mode 100644 index 0000000..048b4a1 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictDto.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseDTO; +import java.io.Serializable; +import java.util.List; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Getter +@Setter +public class DictDto extends BaseDTO implements Serializable { + + private Long id; + + private List dictDetails; + + private String name; + + private String description; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictQueryCriteria.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictQueryCriteria.java new file mode 100644 index 0000000..7207c61 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictQueryCriteria.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; + +/** + * @author Zheng Jie + * 公共查询类 + */ +@Data +public class DictQueryCriteria { + + @Query(blurry = "name,description") + private String blurry; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictSmallDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictSmallDto.java new file mode 100644 index 0000000..98fc6ee --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/DictSmallDto.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; +import java.io.Serializable; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Getter +@Setter +public class DictSmallDto implements Serializable { + + private Long id; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/GoogleAuthCodeDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/GoogleAuthCodeDTO.java new file mode 100644 index 0000000..da99a81 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/GoogleAuthCodeDTO.java @@ -0,0 +1,27 @@ +package me.zhengjie.modules.system.service.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; + +/** + * 验证身份验证码是否正确 DTO + * + * @author rch + * @since 2020-08-25 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class GoogleAuthCodeDTO { + + /** 输入的身份验证码 */ + @NotBlank(message = "身份验证码不能为空") + private String codes; + + /** 密钥 */ + @NotBlank(message = "密钥不能为空") + private String savedSecret; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/GoogleAuthGenSecretDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/GoogleAuthGenSecretDTO.java new file mode 100644 index 0000000..dd506f4 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/GoogleAuthGenSecretDTO.java @@ -0,0 +1,23 @@ +package me.zhengjie.modules.system.service.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; + +/** + * 获取密钥 DTO + * + * @author rch + * @since 2020-08-25 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class GoogleAuthGenSecretDTO { + + /** 用户 */ + @NotBlank(message = "用户名不能为空") + private String userName; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/GoogleAuthQrBarCodeUrlDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/GoogleAuthQrBarCodeUrlDTO.java new file mode 100644 index 0000000..049f341 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/GoogleAuthQrBarCodeUrlDTO.java @@ -0,0 +1,23 @@ +package me.zhengjie.modules.system.service.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; + +/** + * 获取密钥 DTO + * + * @author rch + * @since 2020-08-25 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class GoogleAuthQrBarCodeUrlDTO { + + /** 用户 */ + @NotBlank(message = "用户名不能为空") + private String userName; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/JobDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/JobDto.java new file mode 100644 index 0000000..8836d55 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/JobDto.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import me.zhengjie.base.BaseDTO; + +import java.io.Serializable; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +@Getter +@Setter +@NoArgsConstructor +public class JobDto extends BaseDTO implements Serializable { + + private Long id; + + private Integer jobSort; + + private String name; + + private Boolean enabled; + + public JobDto(String name, Boolean enabled) { + this.name = name; + this.enabled = enabled; + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/JobQueryCriteria.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/JobQueryCriteria.java new file mode 100644 index 0000000..ee851dc --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/JobQueryCriteria.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; +import me.zhengjie.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** +* @author Zheng Jie +* @date 2019-6-4 14:49:34 +*/ +@Data +@NoArgsConstructor +public class JobQueryCriteria { + + @Query(type = Query.Type.INNER_LIKE) + private String name; + + @Query + private Boolean enabled; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/JobSmallDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/JobSmallDto.java new file mode 100644 index 0000000..09cfa62 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/JobSmallDto.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; +import java.io.Serializable; + +/** +* @author Zheng Jie +* @date 2019-6-10 16:32:18 +*/ +@Data +@NoArgsConstructor +public class JobSmallDto implements Serializable { + + private Long id; + + private String name; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/MenuDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/MenuDto.java new file mode 100644 index 0000000..d60dd29 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/MenuDto.java @@ -0,0 +1,91 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseDTO; +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +/** + * @author Zheng Jie + * @date 2018-12-17 + */ +@Getter +@Setter +public class MenuDto extends BaseDTO implements Serializable { + + private Long id; + + private List children; + + private Integer type; + + private String permission; + + private String title; + + private Integer menuSort; + + private String path; + + private String component; + + private Long pid; + + private Integer subCount; + + private Boolean iFrame; + + private Boolean cache; + + private Boolean hidden; + + private String componentName; + + private String icon; + + public Boolean getHasChildren() { + return subCount > 0; + } + + public Boolean getLeaf() { + return subCount <= 0; + } + + public String getLabel() { + return title; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MenuDto menuDto = (MenuDto) o; + return Objects.equals(id, menuDto.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/MenuQueryCriteria.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/MenuQueryCriteria.java new file mode 100644 index 0000000..bd43e8d --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/MenuQueryCriteria.java @@ -0,0 +1,41 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** + * @author Zheng Jie + * 公共查询类 + */ +@Data +public class MenuQueryCriteria { + + @Query(blurry = "title,component,permission") + private String blurry; + + @Query(type = Query.Type.BETWEEN) + private List createTime; + + @Query(type = Query.Type.IS_NULL, propName = "pid") + private Boolean pidIsNull; + + @Query + private Long pid; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/RoleDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/RoleDto.java new file mode 100644 index 0000000..fc74d84 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/RoleDto.java @@ -0,0 +1,63 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseDTO; +import java.io.Serializable; +import java.util.Objects; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Getter +@Setter +public class RoleDto extends BaseDTO implements Serializable { + + private Long id; + + private Set menus; + + private Set depts; + + private String name; + + private String dataScope; + + private Integer level; + + private String description; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RoleDto roleDto = (RoleDto) o; + return Objects.equals(id, roleDto.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/RoleQueryCriteria.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/RoleQueryCriteria.java new file mode 100644 index 0000000..5454fc4 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/RoleQueryCriteria.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; + +import java.sql.Timestamp; +import java.util.List; + +/** + * @author Zheng Jie + * 公共查询类 + */ +@Data +public class RoleQueryCriteria { + + @Query(blurry = "name,description") + private String blurry; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/RoleSmallDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/RoleSmallDto.java new file mode 100644 index 0000000..99215e6 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/RoleSmallDto.java @@ -0,0 +1,35 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Data; +import java.io.Serializable; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Data +public class RoleSmallDto implements Serializable { + + private Long id; + + private String name; + + private Integer level; + + private String dataScope; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/UpdateGoogleAuthDTO.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/UpdateGoogleAuthDTO.java new file mode 100644 index 0000000..befe410 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/UpdateGoogleAuthDTO.java @@ -0,0 +1,27 @@ +package me.zhengjie.modules.system.service.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * 修改Google认证器开关 DTO + * + * @author rch + * @since 2020-08-25 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UpdateGoogleAuthDTO { + + /** 用户 */ + @NotNull + @Min(value=0) + @Max(value=1) + private Integer isOpen; +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/UserDto.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/UserDto.java new file mode 100644 index 0000000..923e2d4 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/UserDto.java @@ -0,0 +1,67 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseDTO; +import java.io.Serializable; +import java.util.Date; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Getter +@Setter +public class UserDto extends BaseDTO implements Serializable { + + private Long id; + + private Set roles; + + private Set jobs; + + private DeptSmallDto dept; + + private Long deptId; + + private String username; + + private String nickName; + + private String email; + + private String phone; + + private String gender; + + private String avatarName; + + private String avatarPath; + + @JSONField(serialize = false) + private String password; + + private Boolean enabled; + + @JSONField(serialize = false) + private Boolean isAdmin = false; + + private Date pwdResetTime; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/UserQueryCriteria.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/UserQueryCriteria.java new file mode 100644 index 0000000..ad8e775 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/dto/UserQueryCriteria.java @@ -0,0 +1,49 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Data +public class UserQueryCriteria implements Serializable { + + @Query + private Long id; + + @Query(propName = "id", type = Query.Type.IN, joinName = "dept") + private Set deptIds = new HashSet<>(); + + @Query(blurry = "email,username,nickName") + private String blurry; + + @Query + private Boolean enabled; + + private Long deptId; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/DataServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/DataServiceImpl.java new file mode 100644 index 0000000..33a8148 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/DataServiceImpl.java @@ -0,0 +1,91 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.impl; + +import lombok.RequiredArgsConstructor; +import me.zhengjie.modules.system.domain.Dept; +import me.zhengjie.modules.system.service.DataService; +import me.zhengjie.modules.system.service.DeptService; +import me.zhengjie.modules.system.service.RoleService; +import me.zhengjie.modules.system.service.dto.RoleSmallDto; +import me.zhengjie.modules.system.service.dto.UserDto; +import me.zhengjie.utils.enums.DataScopeEnum; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import java.util.*; + +/** + * @author Zheng Jie + * @website https://el-admin.vip + * @description 数据权限服务实现 + * @date 2020-05-07 + **/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "data") +public class DataServiceImpl implements DataService { + + private final RoleService roleService; + private final DeptService deptService; + + /** + * 用户角色改变时需清理缓存 + * @param user / + * @return / + */ + @Override + @Cacheable(key = "'user:' + #p0.id") + public List getDeptIds(UserDto user) { + // 用于存储部门id + Set deptIds = new HashSet<>(); + // 查询用户角色 + List roleSet = roleService.findByUsersId(user.getId()); + // 获取对应的部门ID + for (RoleSmallDto role : roleSet) { + DataScopeEnum dataScopeEnum = DataScopeEnum.find(role.getDataScope()); + switch (Objects.requireNonNull(dataScopeEnum)) { + case THIS_LEVEL: + deptIds.add(user.getDept().getId()); + break; + case CUSTOMIZE: + deptIds.addAll(getCustomize(deptIds, role)); + break; + default: + return new ArrayList<>(deptIds); + } + } + return new ArrayList<>(deptIds); + } + + /** + * 获取自定义的数据权限 + * @param deptIds 部门ID + * @param role 角色 + * @return 数据权限ID + */ + public Set getCustomize(Set deptIds, RoleSmallDto role){ + Set depts = deptService.findByRoleId(role.getId()); + for (Dept dept : depts) { + deptIds.add(dept.getId()); + List deptChildren = deptService.findByPid(dept.getId()); + if (deptChildren != null && deptChildren.size() != 0) { + deptIds.addAll(deptService.getDeptChildren(deptChildren)); + } + } + return deptIds; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/DeptServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/DeptServiceImpl.java new file mode 100644 index 0000000..a02bd69 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/DeptServiceImpl.java @@ -0,0 +1,283 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import lombok.RequiredArgsConstructor; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.system.domain.Dept; +import me.zhengjie.modules.system.domain.User; +import me.zhengjie.modules.system.repository.RoleRepository; +import me.zhengjie.modules.system.repository.UserRepository; +import me.zhengjie.modules.system.service.dto.DeptDto; +import me.zhengjie.modules.system.service.dto.DeptQueryCriteria; +import me.zhengjie.utils.*; +import me.zhengjie.modules.system.repository.DeptRepository; +import me.zhengjie.modules.system.service.DeptService; +import me.zhengjie.modules.system.service.mapstruct.DeptMapper; +import me.zhengjie.utils.enums.DataScopeEnum; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.*; +import java.util.stream.Collectors; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "dept") +public class DeptServiceImpl implements DeptService { + + private final DeptRepository deptRepository; + private final DeptMapper deptMapper; + private final UserRepository userRepository; + private final RedisUtils redisUtils; + private final RoleRepository roleRepository; + + @Override + public List queryAll(DeptQueryCriteria criteria, Boolean isQuery) throws Exception { + Sort sort = Sort.by(Sort.Direction.ASC, "deptSort"); + String dataScopeType = SecurityUtils.getDataScopeType(); + if (isQuery) { + if(dataScopeType.equals(DataScopeEnum.ALL.getValue())){ + criteria.setPidIsNull(true); + } + List fields = QueryHelp.getAllFields(criteria.getClass(), new ArrayList<>()); + List fieldNames = new ArrayList(){{ add("pidIsNull");add("enabled");}}; + for (Field field : fields) { + //设置对象的访问权限,保证对private的属性的访问 + field.setAccessible(true); + Object val = field.get(criteria); + if(fieldNames.contains(field.getName())){ + continue; + } + if (ObjectUtil.isNotNull(val)) { + criteria.setPidIsNull(null); + break; + } + } + } + List list = deptMapper.toDto(deptRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),sort)); + // 如果为空,就代表为自定义权限或者本级权限,就需要去重,不理解可以注释掉,看查询结果 + if(StringUtils.isBlank(dataScopeType)){ + return deduplication(list); + } + return list; + } + + @Override + @Cacheable(key = "'id:' + #p0") + public DeptDto findById(Long id) { + Dept dept = deptRepository.findById(id).orElseGet(Dept::new); + ValidationUtil.isNull(dept.getId(),"Dept","id",id); + return deptMapper.toDto(dept); + } + + @Override + public List findByPid(long pid) { + return deptRepository.findByPid(pid); + } + + @Override + public Set findByRoleId(Long id) { + return deptRepository.findByRoleId(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Dept resources) { + deptRepository.save(resources); + // 计算子节点数目 + resources.setSubCount(0); + // 清理缓存 + updateSubCnt(resources.getPid()); + // 清理自定义角色权限的datascope缓存 + delCaches(resources.getPid()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Dept resources) { + // 旧的部门 + Long oldPid = findById(resources.getId()).getPid(); + Long newPid = resources.getPid(); + if(resources.getPid() != null && resources.getId().equals(resources.getPid())) { + throw new BadRequestException("上级不能为自己"); + } + Dept dept = deptRepository.findById(resources.getId()).orElseGet(Dept::new); + ValidationUtil.isNull( dept.getId(),"Dept","id",resources.getId()); + resources.setId(dept.getId()); + deptRepository.save(resources); + // 更新父节点中子节点数目 + updateSubCnt(oldPid); + updateSubCnt(newPid); + // 清理缓存 + delCaches(resources.getId()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set deptDtos) { + for (DeptDto deptDto : deptDtos) { + // 清理缓存 + delCaches(deptDto.getId()); + deptRepository.deleteById(deptDto.getId()); + updateSubCnt(deptDto.getPid()); + } + } + + @Override + public void download(List deptDtos, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (DeptDto deptDTO : deptDtos) { + Map map = new LinkedHashMap<>(); + map.put("部门名称", deptDTO.getName()); + map.put("部门状态", deptDTO.getEnabled() ? "启用" : "停用"); + map.put("创建日期", deptDTO.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + @Override + public Set getDeleteDepts(List menuList, Set deptDtos) { + for (Dept dept : menuList) { + deptDtos.add(deptMapper.toDto(dept)); + List depts = deptRepository.findByPid(dept.getId()); + if(depts!=null && depts.size()!=0){ + getDeleteDepts(depts, deptDtos); + } + } + return deptDtos; + } + + @Override + public List getDeptChildren(List deptList) { + List list = new ArrayList<>(); + deptList.forEach(dept -> { + if (dept!=null && dept.getEnabled()) { + List depts = deptRepository.findByPid(dept.getId()); + if (depts.size() != 0) { + list.addAll(getDeptChildren(depts)); + } + list.add(dept.getId()); + } + } + ); + return list; + } + + @Override + public List getSuperior(DeptDto deptDto, List depts) { + if(deptDto.getPid() == null){ + depts.addAll(deptRepository.findByPidIsNull()); + return deptMapper.toDto(depts); + } + depts.addAll(deptRepository.findByPid(deptDto.getPid())); + return getSuperior(findById(deptDto.getPid()), depts); + } + + @Override + public Object buildTree(List deptDtos) { + Set trees = new LinkedHashSet<>(); + Set depts= new LinkedHashSet<>(); + List deptNames = deptDtos.stream().map(DeptDto::getName).collect(Collectors.toList()); + boolean isChild; + for (DeptDto deptDTO : deptDtos) { + isChild = false; + if (deptDTO.getPid() == null) { + trees.add(deptDTO); + } + for (DeptDto it : deptDtos) { + if (it.getPid() != null && deptDTO.getId().equals(it.getPid())) { + isChild = true; + if (deptDTO.getChildren() == null) { + deptDTO.setChildren(new ArrayList<>()); + } + deptDTO.getChildren().add(it); + } + } + if(isChild) { + depts.add(deptDTO); + } else if(deptDTO.getPid() != null && !deptNames.contains(findById(deptDTO.getPid()).getName())) { + depts.add(deptDTO); + } + } + + if (CollectionUtil.isEmpty(trees)) { + trees = depts; + } + Map map = new HashMap<>(2); + map.put("totalElements",deptDtos.size()); + map.put("content",CollectionUtil.isEmpty(trees)? deptDtos :trees); + return map; + } + + @Override + public void verification(Set deptDtos) { + Set deptIds = deptDtos.stream().map(DeptDto::getId).collect(Collectors.toSet()); + if(userRepository.countByDepts(deptIds) > 0){ + throw new BadRequestException("所选部门存在用户关联,请解除后再试!"); + } + if(roleRepository.countByDepts(deptIds) > 0){ + throw new BadRequestException("所选部门存在角色关联,请解除后再试!"); + } + } + + private void updateSubCnt(Long deptId){ + if(deptId != null){ + int count = deptRepository.countByPid(deptId); + deptRepository.updateSubCntById(count, deptId); + } + } + + private List deduplication(List list) { + List deptDtos = new ArrayList<>(); + for (DeptDto deptDto : list) { + boolean flag = true; + for (DeptDto dto : list) { + if (dto.getId().equals(deptDto.getPid())) { + flag = false; + break; + } + } + if (flag){ + deptDtos.add(deptDto); + } + } + return deptDtos; + } + + /** + * 清理缓存 + * @param id / + */ + public void delCaches(Long id){ + List users = userRepository.findByRoleDeptId(id); + // 删除数据权限 + redisUtils.delByKeys(CacheKey.DATA_USER, users.stream().map(User::getId).collect(Collectors.toSet())); + redisUtils.del(CacheKey.DEPT_ID + id); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/DictDetailServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/DictDetailServiceImpl.java new file mode 100644 index 0000000..3f5fc74 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/DictDetailServiceImpl.java @@ -0,0 +1,95 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.impl; + +import lombok.RequiredArgsConstructor; +import me.zhengjie.modules.system.domain.Dict; +import me.zhengjie.modules.system.domain.DictDetail; +import me.zhengjie.modules.system.repository.DictRepository; +import me.zhengjie.modules.system.service.dto.DictDetailQueryCriteria; +import me.zhengjie.utils.*; +import me.zhengjie.modules.system.repository.DictDetailRepository; +import me.zhengjie.modules.system.service.DictDetailService; +import me.zhengjie.modules.system.service.dto.DictDetailDto; +import me.zhengjie.modules.system.service.mapstruct.DictDetailMapper; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.List; +import java.util.Map; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "dict") +public class DictDetailServiceImpl implements DictDetailService { + + private final DictRepository dictRepository; + private final DictDetailRepository dictDetailRepository; + private final DictDetailMapper dictDetailMapper; + private final RedisUtils redisUtils; + + @Override + public Map queryAll(DictDetailQueryCriteria criteria, Pageable pageable) { + Page page = dictDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(dictDetailMapper::toDto)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(DictDetail resources) { + dictDetailRepository.save(resources); + // 清理缓存 + delCaches(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(DictDetail resources) { + DictDetail dictDetail = dictDetailRepository.findById(resources.getId()).orElseGet(DictDetail::new); + ValidationUtil.isNull( dictDetail.getId(),"DictDetail","id",resources.getId()); + resources.setId(dictDetail.getId()); + dictDetailRepository.save(resources); + // 清理缓存 + delCaches(resources); + } + + @Override + @Cacheable(key = "'name:' + #p0") + public List getDictByName(String name) { + return dictDetailMapper.toDto(dictDetailRepository.findByDictName(name)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long id) { + DictDetail dictDetail = dictDetailRepository.findById(id).orElseGet(DictDetail::new); + // 清理缓存 + delCaches(dictDetail); + dictDetailRepository.deleteById(id); + } + + public void delCaches(DictDetail dictDetail){ + Dict dict = dictRepository.findById(dictDetail.getDict().getId()).orElseGet(Dict::new); + redisUtils.del(CacheKey.DICT_NAME + dict.getName()); + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/DictServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/DictServiceImpl.java new file mode 100644 index 0000000..3a2bcd9 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/DictServiceImpl.java @@ -0,0 +1,121 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import lombok.RequiredArgsConstructor; +import me.zhengjie.modules.system.domain.Dict; +import me.zhengjie.modules.system.service.dto.DictDetailDto; +import me.zhengjie.modules.system.service.dto.DictQueryCriteria; +import me.zhengjie.utils.*; +import me.zhengjie.modules.system.repository.DictRepository; +import me.zhengjie.modules.system.service.DictService; +import me.zhengjie.modules.system.service.dto.DictDto; +import me.zhengjie.modules.system.service.mapstruct.DictMapper; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "dict") +public class DictServiceImpl implements DictService { + + private final DictRepository dictRepository; + private final DictMapper dictMapper; + private final RedisUtils redisUtils; + + @Override + public Map queryAll(DictQueryCriteria dict, Pageable pageable){ + Page page = dictRepository.findAll((root, query, cb) -> QueryHelp.getPredicate(root, dict, cb), pageable); + return PageUtil.toPage(page.map(dictMapper::toDto)); + } + + @Override + public List queryAll(DictQueryCriteria dict) { + List list = dictRepository.findAll((root, query, cb) -> QueryHelp.getPredicate(root, dict, cb)); + return dictMapper.toDto(list); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Dict resources) { + dictRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Dict resources) { + // 清理缓存 + delCaches(resources); + Dict dict = dictRepository.findById(resources.getId()).orElseGet(Dict::new); + ValidationUtil.isNull( dict.getId(),"Dict","id",resources.getId()); + dict.setName(resources.getName()); + dict.setDescription(resources.getDescription()); + dictRepository.save(dict); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + // 清理缓存 + List dicts = dictRepository.findByIdIn(ids); + for (Dict dict : dicts) { + delCaches(dict); + } + dictRepository.deleteByIdIn(ids); + } + + @Override + public void download(List dictDtos, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (DictDto dictDTO : dictDtos) { + if(CollectionUtil.isNotEmpty(dictDTO.getDictDetails())){ + for (DictDetailDto dictDetail : dictDTO.getDictDetails()) { + Map map = new LinkedHashMap<>(); + map.put("字典名称", dictDTO.getName()); + map.put("字典描述", dictDTO.getDescription()); + map.put("字典标签", dictDetail.getLabel()); + map.put("字典值", dictDetail.getValue()); + map.put("创建日期", dictDetail.getCreateTime()); + list.add(map); + } + } else { + Map map = new LinkedHashMap<>(); + map.put("字典名称", dictDTO.getName()); + map.put("字典描述", dictDTO.getDescription()); + map.put("字典标签", null); + map.put("字典值", null); + map.put("创建日期", dictDTO.getCreateTime()); + list.add(map); + } + } + FileUtil.downloadExcel(list, response); + } + + public void delCaches(Dict dict){ + redisUtils.del(CacheKey.DICT_NAME + dict.getName()); + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/JobServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/JobServiceImpl.java new file mode 100644 index 0000000..5c76dfc --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/JobServiceImpl.java @@ -0,0 +1,132 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.impl; + +import lombok.RequiredArgsConstructor; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.exception.EntityExistException; +import me.zhengjie.modules.system.domain.Job; +import me.zhengjie.modules.system.repository.UserRepository; +import me.zhengjie.modules.system.service.dto.JobQueryCriteria; +import me.zhengjie.utils.*; +import me.zhengjie.modules.system.repository.JobRepository; +import me.zhengjie.modules.system.service.JobService; +import me.zhengjie.modules.system.service.dto.JobDto; +import me.zhengjie.modules.system.service.mapstruct.JobMapper; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "job") +public class JobServiceImpl implements JobService { + + private final JobRepository jobRepository; + private final JobMapper jobMapper; + private final RedisUtils redisUtils; + private final UserRepository userRepository; + + @Override + public Map queryAll(JobQueryCriteria criteria, Pageable pageable) { + Page page = jobRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(jobMapper::toDto).getContent(),page.getTotalElements()); + } + + @Override + public List queryAll(JobQueryCriteria criteria) { + List list = jobRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)); + return jobMapper.toDto(list); + } + + @Override + @Cacheable(key = "'id:' + #p0") + public JobDto findById(Long id) { + Job job = jobRepository.findById(id).orElseGet(Job::new); + ValidationUtil.isNull(job.getId(),"Job","id",id); + return jobMapper.toDto(job); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Job resources) { + Job job = jobRepository.findByName(resources.getName()); + if(job != null){ + throw new EntityExistException(Job.class,"name",resources.getName()); + } + jobRepository.save(resources); + } + + @Override + @CacheEvict(key = "'id:' + #p0.id") + @Transactional(rollbackFor = Exception.class) + public void update(Job resources) { + Job job = jobRepository.findById(resources.getId()).orElseGet(Job::new); + Job old = jobRepository.findByName(resources.getName()); + if(old != null && !old.getId().equals(resources.getId())){ + throw new EntityExistException(Job.class,"name",resources.getName()); + } + ValidationUtil.isNull( job.getId(),"Job","id",resources.getId()); + resources.setId(job.getId()); + jobRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + jobRepository.deleteAllByIdIn(ids); + jobRepository.deleteAll(); + // 删除缓存 + redisUtils.delByKeys(CacheKey.JOB_ID, ids); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete() { + jobRepository.deleteAll(); + } + + @Override + public void download(List jobDtos, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (JobDto jobDTO : jobDtos) { + Map map = new LinkedHashMap<>(); + map.put("岗位名称", jobDTO.getName()); + map.put("岗位状态", jobDTO.getEnabled() ? "启用" : "停用"); + map.put("创建日期", jobDTO.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + @Override + public void verification(Set ids) { + if(userRepository.countByJobs(ids) > 0){ + throw new BadRequestException("所选的岗位中存在用户关联,请解除关联再试!"); + } + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/MenuServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/MenuServiceImpl.java new file mode 100644 index 0000000..0e54fc9 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/MenuServiceImpl.java @@ -0,0 +1,355 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import lombok.RequiredArgsConstructor; +import me.zhengjie.modules.system.domain.Menu; +import me.zhengjie.modules.system.domain.Role; +import me.zhengjie.modules.system.domain.User; +import me.zhengjie.modules.system.domain.vo.MenuMetaVo; +import me.zhengjie.modules.system.domain.vo.MenuVo; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.exception.EntityExistException; +import me.zhengjie.modules.system.repository.MenuRepository; +import me.zhengjie.modules.system.repository.UserRepository; +import me.zhengjie.modules.system.service.MenuService; +import me.zhengjie.modules.system.service.RoleService; +import me.zhengjie.modules.system.service.dto.MenuDto; +import me.zhengjie.modules.system.service.dto.MenuQueryCriteria; +import me.zhengjie.modules.system.service.dto.RoleSmallDto; +import me.zhengjie.modules.system.service.mapstruct.MenuMapper; +import me.zhengjie.utils.*; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + */ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "menu") +public class MenuServiceImpl implements MenuService { + + private final MenuRepository menuRepository; + private final UserRepository userRepository; + private final MenuMapper menuMapper; + private final RoleService roleService; + private final RedisUtils redisUtils; + + @Override + public List queryAll(MenuQueryCriteria criteria, Boolean isQuery) throws Exception { + Sort sort = Sort.by(Sort.Direction.ASC, "menuSort"); + if(isQuery){ + criteria.setPidIsNull(true); + List fields = QueryHelp.getAllFields(criteria.getClass(), new ArrayList<>()); + for (Field field : fields) { + //设置对象的访问权限,保证对private的属性的访问 + field.setAccessible(true); + Object val = field.get(criteria); + if("pidIsNull".equals(field.getName())){ + continue; + } + if (ObjectUtil.isNotNull(val)) { + criteria.setPidIsNull(null); + break; + } + } + } + return menuMapper.toDto(menuRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),sort)); + } + + @Override + @Cacheable(key = "'id:' + #p0") + public MenuDto findById(long id) { + Menu menu = menuRepository.findById(id).orElseGet(Menu::new); + ValidationUtil.isNull(menu.getId(),"Menu","id",id); + return menuMapper.toDto(menu); + } + + /** + * 用户角色改变时需清理缓存 + * @param currentUserId / + * @return / + */ + @Override + @Cacheable(key = "'user:' + #p0") + public List findByUser(Long currentUserId) { + List roles = roleService.findByUsersId(currentUserId); + Set roleIds = roles.stream().map(RoleSmallDto::getId).collect(Collectors.toSet()); + LinkedHashSet menus = menuRepository.findByRoleIdsAndTypeNot(roleIds, 2); + return menus.stream().map(menuMapper::toDto).collect(Collectors.toList()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Menu resources) { + if(menuRepository.findByTitle(resources.getTitle()) != null){ + throw new EntityExistException(Menu.class,"title",resources.getTitle()); + } + if(StringUtils.isNotBlank(resources.getComponentName())){ + if(menuRepository.findByComponentName(resources.getComponentName()) != null){ + throw new EntityExistException(Menu.class,"componentName",resources.getComponentName()); + } + } + if(resources.getPid().equals(0L)){ + resources.setPid(null); + } + if(resources.getIFrame()){ + String http = "http://", https = "https://"; + if (!(resources.getPath().toLowerCase().startsWith(http)||resources.getPath().toLowerCase().startsWith(https))) { + throw new BadRequestException("外链必须以http://或者https://开头"); + } + } + menuRepository.save(resources); + // 计算子节点数目 + resources.setSubCount(0); + // 更新父节点菜单数目 + updateSubCnt(resources.getPid()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Menu resources) { + if(resources.getId().equals(resources.getPid())) { + throw new BadRequestException("上级不能为自己"); + } + Menu menu = menuRepository.findById(resources.getId()).orElseGet(Menu::new); + ValidationUtil.isNull(menu.getId(),"Permission","id",resources.getId()); + + if(resources.getIFrame()){ + String http = "http://", https = "https://"; + if (!(resources.getPath().toLowerCase().startsWith(http)||resources.getPath().toLowerCase().startsWith(https))) { + throw new BadRequestException("外链必须以http://或者https://开头"); + } + } + Menu menu1 = menuRepository.findByTitle(resources.getTitle()); + + if(menu1 != null && !menu1.getId().equals(menu.getId())){ + throw new EntityExistException(Menu.class,"title",resources.getTitle()); + } + + if(resources.getPid().equals(0L)){ + resources.setPid(null); + } + + // 记录的父节点ID + Long oldPid = menu.getPid(); + Long newPid = resources.getPid(); + + if(StringUtils.isNotBlank(resources.getComponentName())){ + menu1 = menuRepository.findByComponentName(resources.getComponentName()); + if(menu1 != null && !menu1.getId().equals(menu.getId())){ + throw new EntityExistException(Menu.class,"componentName",resources.getComponentName()); + } + } + menu.setTitle(resources.getTitle()); + menu.setComponent(resources.getComponent()); + menu.setPath(resources.getPath()); + menu.setIcon(resources.getIcon()); + menu.setIFrame(resources.getIFrame()); + menu.setPid(resources.getPid()); + menu.setMenuSort(resources.getMenuSort()); + menu.setCache(resources.getCache()); + menu.setHidden(resources.getHidden()); + menu.setComponentName(resources.getComponentName()); + menu.setPermission(resources.getPermission()); + menu.setType(resources.getType()); + menuRepository.save(menu); + // 计算父级菜单节点数目 + updateSubCnt(oldPid); + updateSubCnt(newPid); + // 清理缓存 + delCaches(resources.getId()); + } + + @Override + public Set getChildMenus(List menuList, Set menuSet) { + for (Menu menu : menuList) { + menuSet.add(menu); + List menus = menuRepository.findByPid(menu.getId()); + if(menus!=null && menus.size()!=0){ + getChildMenus(menus, menuSet); + } + } + return menuSet; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set menuSet) { + for (Menu menu : menuSet) { + // 清理缓存 + delCaches(menu.getId()); + roleService.untiedMenu(menu.getId()); + menuRepository.deleteById(menu.getId()); + updateSubCnt(menu.getPid()); + } + } + + @Override + public List getMenus(Long pid) { + List menus; + if(pid != null && !pid.equals(0L)){ + menus = menuRepository.findByPid(pid); + } else { + menus = menuRepository.findByPidIsNull(); + } + return menuMapper.toDto(menus); + } + + @Override + public List getSuperior(MenuDto menuDto, List menus) { + if(menuDto.getPid() == null){ + menus.addAll(menuRepository.findByPidIsNull()); + return menuMapper.toDto(menus); + } + menus.addAll(menuRepository.findByPid(menuDto.getPid())); + return getSuperior(findById(menuDto.getPid()), menus); + } + + @Override + public List buildTree(List menuDtos) { + List trees = new ArrayList<>(); + Set ids = new HashSet<>(); + for (MenuDto menuDTO : menuDtos) { + if (menuDTO.getPid() == null) { + trees.add(menuDTO); + } + for (MenuDto it : menuDtos) { + if (menuDTO.getId().equals(it.getPid())) { + if (menuDTO.getChildren() == null) { + menuDTO.setChildren(new ArrayList<>()); + } + menuDTO.getChildren().add(it); + ids.add(it.getId()); + } + } + } + if(trees.size() == 0){ + trees = menuDtos.stream().filter(s -> !ids.contains(s.getId())).collect(Collectors.toList()); + } + return trees; + } + + @Override + public List buildMenus(List menuDtos) { + List list = new LinkedList<>(); + menuDtos.forEach(menuDTO -> { + if (menuDTO!=null){ + List menuDtoList = menuDTO.getChildren(); + MenuVo menuVo = new MenuVo(); + menuVo.setName(ObjectUtil.isNotEmpty(menuDTO.getComponentName()) ? menuDTO.getComponentName() : menuDTO.getTitle()); + // 一级目录需要加斜杠,不然会报警告 + menuVo.setPath(menuDTO.getPid() == null ? "/" + menuDTO.getPath() :menuDTO.getPath()); + menuVo.setHidden(menuDTO.getHidden()); + // 如果不是外链 + if(!menuDTO.getIFrame()){ + if(menuDTO.getPid() == null){ + menuVo.setComponent(StringUtils.isEmpty(menuDTO.getComponent())?"Layout":menuDTO.getComponent()); + // 如果不是一级菜单,并且菜单类型为目录,则代表是多级菜单 + }else if(menuDTO.getType() == 0){ + menuVo.setComponent(StringUtils.isEmpty(menuDTO.getComponent())?"ParentView":menuDTO.getComponent()); + }else if(StringUtils.isNoneBlank(menuDTO.getComponent())){ + menuVo.setComponent(menuDTO.getComponent()); + } + } + menuVo.setMeta(new MenuMetaVo(menuDTO.getTitle(),menuDTO.getIcon(),!menuDTO.getCache())); + if(CollectionUtil.isNotEmpty(menuDtoList)){ + menuVo.setAlwaysShow(true); + menuVo.setRedirect("noredirect"); + menuVo.setChildren(buildMenus(menuDtoList)); + // 处理是一级菜单并且没有子菜单的情况 + } else if(menuDTO.getPid() == null){ + MenuVo menuVo1 = new MenuVo(); + menuVo1.setMeta(menuVo.getMeta()); + // 非外链 + if(!menuDTO.getIFrame()){ + menuVo1.setPath("index"); + menuVo1.setName(menuVo.getName()); + menuVo1.setComponent(menuVo.getComponent()); + } else { + menuVo1.setPath(menuDTO.getPath()); + } + menuVo.setName(null); + menuVo.setMeta(null); + menuVo.setComponent("Layout"); + List list1 = new ArrayList<>(); + list1.add(menuVo1); + menuVo.setChildren(list1); + } + list.add(menuVo); + } + } + ); + return list; + } + + @Override + public Menu findOne(Long id) { + Menu menu = menuRepository.findById(id).orElseGet(Menu::new); + ValidationUtil.isNull(menu.getId(),"Menu","id",id); + return menu; + } + + @Override + public void download(List menuDtos, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (MenuDto menuDTO : menuDtos) { + Map map = new LinkedHashMap<>(); + map.put("菜单标题", menuDTO.getTitle()); + map.put("菜单类型", menuDTO.getType() == null ? "目录" : menuDTO.getType() == 1 ? "菜单" : "按钮"); + map.put("权限标识", menuDTO.getPermission()); + map.put("外链菜单", menuDTO.getIFrame() ? "是" : "否"); + map.put("菜单可见", menuDTO.getHidden() ? "否" : "是"); + map.put("是否缓存", menuDTO.getCache() ? "是" : "否"); + map.put("创建日期", menuDTO.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + private void updateSubCnt(Long menuId){ + if(menuId != null){ + int count = menuRepository.countByPid(menuId); + menuRepository.updateSubCntById(count, menuId); + } + } + + /** + * 清理缓存 + * @param id 菜单ID + */ + public void delCaches(Long id){ + List users = userRepository.findByMenuId(id); + redisUtils.del(CacheKey.MENU_ID + id); + redisUtils.delByKeys(CacheKey.MENU_USER, users.stream().map(User::getId).collect(Collectors.toSet())); + // 清除 Role 缓存 + List roles = roleService.findInMenuId(new ArrayList(){{ + add(id); + }}); + redisUtils.delByKeys(CacheKey.ROLE_ID, roles.stream().map(Role::getId).collect(Collectors.toSet())); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/MonitorServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/MonitorServiceImpl.java new file mode 100644 index 0000000..7ff2e91 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/MonitorServiceImpl.java @@ -0,0 +1,187 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.impl; + +import cn.hutool.core.date.BetweenFormater; +import cn.hutool.core.date.DateUtil; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.system.service.MonitorService; +import me.zhengjie.utils.ElAdminConstant; +import me.zhengjie.utils.FileUtil; +import me.zhengjie.utils.StringUtils; +import org.springframework.stereotype.Service; +import oshi.SystemInfo; +import oshi.hardware.*; +import oshi.software.os.FileSystem; +import oshi.software.os.OSFileStore; +import oshi.software.os.OperatingSystem; +import oshi.util.FormatUtil; +import oshi.util.Util; +import java.lang.management.ManagementFactory; +import java.text.DecimalFormat; +import java.util.*; + +/** +* @author Zheng Jie +* @date 2020-05-02 +*/ +@Service +public class MonitorServiceImpl implements MonitorService { + + private final DecimalFormat df = new DecimalFormat("0.00"); + + @Override + public Map getServers(){ + Map resultMap = new LinkedHashMap<>(8); + try { + SystemInfo si = new SystemInfo(); + OperatingSystem os = si.getOperatingSystem(); + HardwareAbstractionLayer hal = si.getHardware(); + // 系统信息 + resultMap.put("sys", getSystemInfo(os)); + // cpu 信息 + resultMap.put("cpu", getCpuInfo(hal.getProcessor())); + // 内存信息 + resultMap.put("memory", getMemoryInfo(hal.getMemory())); + // 交换区信息 + resultMap.put("swap", getSwapInfo(hal.getMemory())); + // 磁盘 + resultMap.put("disk", getDiskInfo(os)); + resultMap.put("time", DateUtil.format(new Date(), "HH:mm:ss")); + } catch (Exception e) { + e.printStackTrace(); + } + return resultMap; + } + + /** + * 获取磁盘信息 + * @return / + */ + private Map getDiskInfo(OperatingSystem os) { + Map diskInfo = new LinkedHashMap<>(); + FileSystem fileSystem = os.getFileSystem(); + List fsArray = fileSystem.getFileStores(); + String osName = System.getProperty("os.name"); + long available = 0, total = 0; + for (OSFileStore fs : fsArray){ + // windows 需要将所有磁盘分区累加,linux 和 mac 直接累加会出现磁盘重复的问题,待修复 + if(osName.toLowerCase().startsWith(ElAdminConstant.WIN)) { + available += fs.getUsableSpace(); + total += fs.getTotalSpace(); + } else { + available = fs.getUsableSpace(); + total = fs.getTotalSpace(); + break; + } + } + long used = total - available; + diskInfo.put("total", total > 0 ? FileUtil.getSize(total) : "?"); + diskInfo.put("available", FileUtil.getSize(available)); + diskInfo.put("used", FileUtil.getSize(used)); + if(total != 0){ + diskInfo.put("usageRate", df.format(used/(double)total * 100)); + } else { + diskInfo.put("usageRate", 0); + } + return diskInfo; + } + + /** + * 获取交换区信息 + * @param memory / + * @return / + */ + private Map getSwapInfo(GlobalMemory memory) { + Map swapInfo = new LinkedHashMap<>(); + VirtualMemory virtualMemory = memory.getVirtualMemory(); + long total = virtualMemory.getSwapTotal(); + long used = virtualMemory.getSwapUsed(); + swapInfo.put("total", FormatUtil.formatBytes(total)); + swapInfo.put("used", FormatUtil.formatBytes(used)); + swapInfo.put("available", FormatUtil.formatBytes(total - used)); + if(used == 0){ + swapInfo.put("usageRate", 0); + } else { + swapInfo.put("usageRate", df.format(used/(double)total * 100)); + } + return swapInfo; + } + + /** + * 获取内存信息 + * @param memory / + * @return / + */ + private Map getMemoryInfo(GlobalMemory memory) { + Map memoryInfo = new LinkedHashMap<>(); + memoryInfo.put("total", FormatUtil.formatBytes(memory.getTotal())); + memoryInfo.put("available", FormatUtil.formatBytes(memory.getAvailable())); + memoryInfo.put("used", FormatUtil.formatBytes(memory.getTotal() - memory.getAvailable())); + memoryInfo.put("usageRate", df.format((memory.getTotal() - memory.getAvailable())/(double)memory.getTotal() * 100)); + return memoryInfo; + } + + /** + * 获取Cpu相关信息 + * @param processor / + * @return / + */ + private Map getCpuInfo(CentralProcessor processor) { + Map cpuInfo = new LinkedHashMap<>(); + cpuInfo.put("name", processor.getProcessorIdentifier().getName()); + cpuInfo.put("package", processor.getPhysicalPackageCount() + "个物理CPU"); + cpuInfo.put("core", processor.getPhysicalProcessorCount() + "个物理核心"); + cpuInfo.put("coreNumber", processor.getPhysicalProcessorCount()); + cpuInfo.put("logic", processor.getLogicalProcessorCount() + "个逻辑CPU"); + // CPU信息 + long[] prevTicks = processor.getSystemCpuLoadTicks(); + // 等待1秒... + Util.sleep(1000); + long[] ticks = processor.getSystemCpuLoadTicks(); + long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()]; + long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()]; + long sys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()]; + long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()]; + long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()]; + long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()]; + long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()]; + long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()]; + long totalCpu = user + nice + sys + idle + iowait + irq + softirq + steal; + cpuInfo.put("used", df.format(100d * user / totalCpu + 100d * sys / totalCpu)); + cpuInfo.put("idle", df.format(100d * idle / totalCpu)); + return cpuInfo; + } + + /** + * 获取系统相关信息,系统、运行天数、系统IP + * @param os / + * @return / + */ + private Map getSystemInfo(OperatingSystem os){ + Map systemInfo = new LinkedHashMap<>(); + // jvm 运行时间 + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + Date date = new Date(time); + // 计算项目运行时间 + String formatBetween = DateUtil.formatBetween(date, new Date(),BetweenFormater.Level.HOUR); + // 系统信息 + systemInfo.put("os", os.toString()); + systemInfo.put("day", formatBetween); + systemInfo.put("ip", StringUtils.getLocalIp()); + return systemInfo; + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java new file mode 100644 index 0000000..e8b4143 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java @@ -0,0 +1,226 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import lombok.RequiredArgsConstructor; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.security.service.UserCacheClean; +import me.zhengjie.modules.system.domain.Menu; +import me.zhengjie.modules.system.domain.Role; +import me.zhengjie.exception.EntityExistException; +import me.zhengjie.modules.system.domain.User; +import me.zhengjie.modules.system.repository.RoleRepository; +import me.zhengjie.modules.system.repository.UserRepository; +import me.zhengjie.modules.system.service.RoleService; +import me.zhengjie.modules.system.service.dto.RoleDto; +import me.zhengjie.modules.system.service.dto.RoleQueryCriteria; +import me.zhengjie.modules.system.service.dto.RoleSmallDto; +import me.zhengjie.modules.system.service.dto.UserDto; +import me.zhengjie.modules.system.service.mapstruct.RoleMapper; +import me.zhengjie.modules.system.service.mapstruct.RoleSmallMapper; +import me.zhengjie.utils.*; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + * @date 2018-12-03 + */ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "role") +public class RoleServiceImpl implements RoleService { + + private final RoleRepository roleRepository; + private final RoleMapper roleMapper; + private final RoleSmallMapper roleSmallMapper; + private final RedisUtils redisUtils; + private final UserRepository userRepository; + private final UserCacheClean userCacheClean; + + @Override + public List queryAll() { + Sort sort = Sort.by(Sort.Direction.ASC, "level"); + return roleMapper.toDto(roleRepository.findAll(sort)); + } + + @Override + public List queryAll(RoleQueryCriteria criteria) { + return roleMapper.toDto(roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder))); + } + + @Override + public Object queryAll(RoleQueryCriteria criteria, Pageable pageable) { + Page page = roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable); + return PageUtil.toPage(page.map(roleMapper::toDto)); + } + + @Override + @Cacheable(key = "'id:' + #p0") + @Transactional(rollbackFor = Exception.class) + public RoleDto findById(long id) { + Role role = roleRepository.findById(id).orElseGet(Role::new); + ValidationUtil.isNull(role.getId(), "Role", "id", id); + return roleMapper.toDto(role); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Role resources) { + if (roleRepository.findByName(resources.getName()) != null) { + throw new EntityExistException(Role.class, "username", resources.getName()); + } + roleRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Role resources) { + Role role = roleRepository.findById(resources.getId()).orElseGet(Role::new); + ValidationUtil.isNull(role.getId(), "Role", "id", resources.getId()); + + Role role1 = roleRepository.findByName(resources.getName()); + + if (role1 != null && !role1.getId().equals(role.getId())) { + throw new EntityExistException(Role.class, "username", resources.getName()); + } + role.setName(resources.getName()); + role.setDescription(resources.getDescription()); + role.setDataScope(resources.getDataScope()); + role.setDepts(resources.getDepts()); + role.setLevel(resources.getLevel()); + roleRepository.save(role); + // 更新相关缓存 + delCaches(role.getId(), null); + } + + @Override + public void updateMenu(Role resources, RoleDto roleDTO) { + Role role = roleMapper.toEntity(roleDTO); + List users = userRepository.findByRoleId(role.getId()); + // 更新菜单 + role.setMenus(resources.getMenus()); + delCaches(resources.getId(), users); + roleRepository.save(role); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void untiedMenu(Long menuId) { + // 更新菜单 + roleRepository.untiedMenu(menuId); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + for (Long id : ids) { + // 更新相关缓存 + delCaches(id, null); + } + roleRepository.deleteAllByIdIn(ids); + } + + @Override + public List findByUsersId(Long id) { + return roleSmallMapper.toDto(new ArrayList<>(roleRepository.findByUserId(id))); + } + + @Override + public Integer findByRoles(Set roles) { + if (roles.size() == 0) { + return Integer.MAX_VALUE; + } + Set roleDtos = new HashSet<>(); + for (Role role : roles) { + roleDtos.add(findById(role.getId())); + } + return Collections.min(roleDtos.stream().map(RoleDto::getLevel).collect(Collectors.toList())); + } + + @Override + @Cacheable(key = "'auth:' + #p0.id") + public List mapToGrantedAuthorities(UserDto user) { + Set permissions = new HashSet<>(); + // 如果是管理员直接返回 + if (user.getIsAdmin()) { + permissions.add("admin"); + return permissions.stream().map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + } + Set roles = roleRepository.findByUserId(user.getId()); + permissions = roles.stream().flatMap(role -> role.getMenus().stream()) + .filter(menu -> StringUtils.isNotBlank(menu.getPermission())) + .map(Menu::getPermission).collect(Collectors.toSet()); + return permissions.stream().map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + } + + @Override + public void download(List roles, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (RoleDto role : roles) { + Map map = new LinkedHashMap<>(); + map.put("角色名称", role.getName()); + map.put("角色级别", role.getLevel()); + map.put("描述", role.getDescription()); + map.put("创建日期", role.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + @Override + public void verification(Set ids) { + if (userRepository.countByRoles(ids) > 0) { + throw new BadRequestException("所选角色存在用户关联,请解除关联再试!"); + } + } + + @Override + public List findInMenuId(List menuIds) { + return roleRepository.findInMenuId(menuIds); + } + + /** + * 清理缓存 + * @param id / + */ + public void delCaches(Long id, List users) { + users = CollectionUtil.isEmpty(users) ? userRepository.findByRoleId(id) : users; + if (CollectionUtil.isNotEmpty(users)) { + users.forEach(item -> userCacheClean.cleanUserCache(item.getUsername())); + Set userIds = users.stream().map(User::getId).collect(Collectors.toSet()); + redisUtils.delByKeys(CacheKey.DATA_USER, userIds); + redisUtils.delByKeys(CacheKey.MENU_USER, userIds); + redisUtils.delByKeys(CacheKey.ROLE_AUTH, userIds); + } + redisUtils.del(CacheKey.ROLE_ID + id); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..3a56692 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java @@ -0,0 +1,282 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import lombok.RequiredArgsConstructor; +import me.zhengjie.config.FileProperties; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.security.service.OnlineUserService; +import me.zhengjie.modules.security.service.UserCacheClean; +import me.zhengjie.modules.system.domain.User; +import me.zhengjie.exception.EntityExistException; +import me.zhengjie.exception.EntityNotFoundException; +import me.zhengjie.modules.system.repository.UserRepository; +import me.zhengjie.modules.system.service.UserService; +import me.zhengjie.modules.system.service.dto.JobSmallDto; +import me.zhengjie.modules.system.service.dto.RoleSmallDto; +import me.zhengjie.modules.system.service.dto.UserDto; +import me.zhengjie.modules.system.service.dto.UserQueryCriteria; +import me.zhengjie.modules.system.service.mapstruct.UserMapper; +import me.zhengjie.utils.*; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.NotBlank; +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "user") +public class UserServiceImpl implements UserService { + + private final UserRepository userRepository; + private final UserMapper userMapper; + private final FileProperties properties; + private final RedisUtils redisUtils; + private final UserCacheClean userCacheClean; + private final OnlineUserService onlineUserService; + + @Override + public Object queryAll(UserQueryCriteria criteria, Pageable pageable) { + Page page = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable); + // 添加用户账户冻结状态 + Map map = PageUtil.toPage(page.map(userMapper::toDto)); + + List userDtoList = (List) map.get("content"); + if (ObjectUtil.isNotEmpty(userDtoList)) { + List list = new ArrayList(); + for (UserDto userDto : userDtoList) { + String key = String.format(RedisUtils.BLOCKED_ACCOUNT, userDto.getUsername()); + long expire = redisUtils.getExpire(key); + Integer blockedStatus = 0; + String blockedTime = ""; + if (expire > 0) { + blockedStatus = 1; + blockedTime = DateUtil.getHour(expire); + } + Map toMap = JSONUtil.parseObj(userDto); + toMap.put("blockedStatus", blockedStatus); + toMap.put("blockedTime", blockedTime); + list.add(toMap); + } + map.put("content", list); + } + + return map; + } + + @Override + public List queryAll(UserQueryCriteria criteria) { + List users = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)); + return userMapper.toDto(users); + } + + @Override + @Cacheable(key = "'id:' + #p0") + @Transactional(rollbackFor = Exception.class) + public UserDto findById(long id) { + User user = userRepository.findById(id).orElseGet(User::new); + ValidationUtil.isNull(user.getId(), "User", "id", id); + return userMapper.toDto(user); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(User resources) { + if (userRepository.findByUsername(resources.getUsername()) != null) { + throw new EntityExistException(User.class, "username", resources.getUsername()); + } + if (userRepository.findByEmail(resources.getEmail()) != null) { + throw new EntityExistException(User.class, "email", resources.getEmail()); + } + if (userRepository.findByPhone(resources.getPhone()) != null) { + throw new EntityExistException(User.class, "phone", resources.getPhone()); + } + userRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(User resources) throws Exception { + User user = userRepository.findById(resources.getId()).orElseGet(User::new); + ValidationUtil.isNull(user.getId(), "User", "id", resources.getId()); + User user1 = userRepository.findByUsername(resources.getUsername()); + User user2 = userRepository.findByEmail(resources.getEmail()); + User user3 = userRepository.findByPhone(resources.getPhone()); + if (user1 != null && !user.getId().equals(user1.getId())) { + throw new EntityExistException(User.class, "username", resources.getUsername()); + } + if (user2 != null && !user.getId().equals(user2.getId())) { + throw new EntityExistException(User.class, "email", resources.getEmail()); + } + if (user3 != null && !user.getId().equals(user3.getId())) { + throw new EntityExistException(User.class, "phone", resources.getPhone()); + } + // 如果用户的角色改变 + if (!resources.getRoles().equals(user.getRoles())) { + redisUtils.del(CacheKey.DATA_USER + resources.getId()); + redisUtils.del(CacheKey.MENU_USER + resources.getId()); + redisUtils.del(CacheKey.ROLE_AUTH + resources.getId()); + } + // 如果用户被禁用,则清除用户登录信息 + if(!resources.getEnabled()){ + onlineUserService.kickOutForUsername(resources.getUsername()); + } + user.setUsername(resources.getUsername()); + user.setEmail(resources.getEmail()); + user.setEnabled(resources.getEnabled()); + user.setRoles(resources.getRoles()); + user.setDept(resources.getDept()); + user.setJobs(resources.getJobs()); + user.setPhone(resources.getPhone()); + user.setNickName(resources.getNickName()); + user.setGender(resources.getGender()); + userRepository.save(user); + // 清除缓存 + delCaches(user.getId(), user.getUsername()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateCenter(User resources) { + User user = userRepository.findById(resources.getId()).orElseGet(User::new); + User user1 = userRepository.findByPhone(resources.getPhone()); + if (user1 != null && !user.getId().equals(user1.getId())) { + throw new EntityExistException(User.class, "phone", resources.getPhone()); + } + user.setNickName(resources.getNickName()); + user.setPhone(resources.getPhone()); + user.setGender(resources.getGender()); + userRepository.save(user); + // 清理缓存 + delCaches(user.getId(), user.getUsername()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + for (Long id : ids) { + // 清理缓存 + UserDto user = findById(id); + delCaches(user.getId(), user.getUsername()); + } + userRepository.deleteAllByIdIn(ids); + } + + @Override + public UserDto findByName(String userName) { + User user = userRepository.findByUsername(userName); + if (user == null) { + throw new EntityNotFoundException(User.class, "name", userName); + } else { + return userMapper.toDto(user); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updatePass(String username, String pass) { + userRepository.updatePass(username, pass, new Date()); + flushCache(username); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Map updateAvatar(MultipartFile multipartFile) { + // 文件大小验证 + FileUtil.checkSize(properties.getAvatarMaxSize(), multipartFile.getSize()); + // 验证文件上传的格式 + String image = "gif jpg png jpeg"; + String fileType = FileUtil.getExtensionName(multipartFile.getOriginalFilename()); + if(fileType != null && !image.contains(fileType)){ + throw new BadRequestException("文件格式错误!, 仅支持 " + image +" 格式"); + } + User user = userRepository.findByUsername(SecurityUtils.getCurrentUsername()); + String oldPath = user.getAvatarPath(); + File file = FileUtil.upload(multipartFile, properties.getPath().getAvatar()); + user.setAvatarPath(Objects.requireNonNull(file).getPath()); + user.setAvatarName(file.getName()); + userRepository.save(user); + if (StringUtils.isNotBlank(oldPath)) { + FileUtil.del(oldPath); + } + @NotBlank String username = user.getUsername(); + flushCache(username); + return new HashMap(1) {{ + put("avatar", file.getName()); + }}; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateEmail(String username, String email) { + userRepository.updateEmail(username, email); + flushCache(username); + } + + @Override + public void download(List queryAll, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (UserDto userDTO : queryAll) { + List roles = userDTO.getRoles().stream().map(RoleSmallDto::getName).collect(Collectors.toList()); + Map map = new LinkedHashMap<>(); + map.put("用户名", userDTO.getUsername()); + map.put("角色", roles); + map.put("部门", userDTO.getDept().getName()); + map.put("岗位", userDTO.getJobs().stream().map(JobSmallDto::getName).collect(Collectors.toList())); + map.put("邮箱", userDTO.getEmail()); + map.put("状态", userDTO.getEnabled() ? "启用" : "禁用"); + map.put("手机号码", userDTO.getPhone()); + map.put("修改密码的时间", userDTO.getPwdResetTime()); + map.put("创建日期", userDTO.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + /** + * 清理缓存 + * + * @param id / + */ + public void delCaches(Long id, String username) { + redisUtils.del(CacheKey.USER_ID + id); + flushCache(username); + } + + /** + * 清理 登陆时 用户缓存信息 + * + * @param username / + */ + private void flushCache(String username) { + userCacheClean.cleanUserCache(username); + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/VerifyServiceImpl.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/VerifyServiceImpl.java new file mode 100644 index 0000000..ec3230c --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/impl/VerifyServiceImpl.java @@ -0,0 +1,81 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.impl; + +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.RandomUtil; +import cn.hutool.extra.template.Template; +import cn.hutool.extra.template.TemplateConfig; +import cn.hutool.extra.template.TemplateEngine; +import cn.hutool.extra.template.TemplateUtil; +import lombok.RequiredArgsConstructor; +import me.zhengjie.domain.vo.EmailVo; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.system.service.VerifyService; +import me.zhengjie.utils.RedisUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.Collections; + +/** + * @author Zheng Jie + * @date 2018-12-26 + */ +@Service +@RequiredArgsConstructor +public class VerifyServiceImpl implements VerifyService { + + @Value("${code.expiration}") + private Long expiration; + private final RedisUtils redisUtils; + + @Override + @Transactional(rollbackFor = Exception.class) + public EmailVo sendEmail(String email, String key) { + EmailVo emailVo; + String content; + String redisKey = key + email; + // 如果不存在有效的验证码,就创建一个新的 + TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH)); + Template template = engine.getTemplate("email/email.ftl"); + Object oldCode = redisUtils.get(redisKey); + if(oldCode == null){ + String code = RandomUtil.randomNumbers (6); + // 存入缓存 + if(!redisUtils.set(redisKey, code, expiration)){ + throw new BadRequestException("服务异常,请联系网站负责人"); + } + content = template.render(Dict.create().set("code",code)); + emailVo = new EmailVo(Collections.singletonList(email),"EL-ADMIN后台管理系统",content); + // 存在就再次发送原来的验证码 + } else { + content = template.render(Dict.create().set("code",oldCode)); + emailVo = new EmailVo(Collections.singletonList(email),"EL-ADMIN后台管理系统",content); + } + return emailVo; + } + + @Override + public void validated(String key, String code) { + Object value = redisUtils.get(key); + if(value == null || !value.toString().equals(code)){ + throw new BadRequestException("无效验证码"); + } else { + redisUtils.del(key); + } + } +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DeptMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DeptMapper.java new file mode 100644 index 0000000..b0fb904 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DeptMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.system.domain.Dept; +import me.zhengjie.modules.system.service.dto.DeptDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DeptMapper extends BaseMapper { +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DeptSmallMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DeptSmallMapper.java new file mode 100644 index 0000000..7507600 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DeptSmallMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.system.domain.Dept; +import me.zhengjie.modules.system.service.dto.DeptSmallDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DeptSmallMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DictDetailMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DictDetailMapper.java new file mode 100644 index 0000000..3f9fe84 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DictDetailMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.system.domain.DictDetail; +import me.zhengjie.modules.system.service.dto.DictDetailDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Mapper(componentModel = "spring", uses = {DictSmallMapper.class}, unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DictDetailMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DictMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DictMapper.java new file mode 100644 index 0000000..1047b3b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DictMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.system.domain.Dict; +import me.zhengjie.modules.system.service.dto.DictDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DictMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DictSmallMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DictSmallMapper.java new file mode 100644 index 0000000..80ccc4e --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/DictSmallMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.system.domain.Dict; +import me.zhengjie.modules.system.service.dto.DictSmallDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DictSmallMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/JobMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/JobMapper.java new file mode 100644 index 0000000..3771930 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/JobMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.system.domain.Job; +import me.zhengjie.modules.system.service.dto.JobDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +@Mapper(componentModel = "spring",uses = {DeptMapper.class},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface JobMapper extends BaseMapper { +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/JobSmallMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/JobSmallMapper.java new file mode 100644 index 0000000..36a59cf --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/JobSmallMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.system.domain.Job; +import me.zhengjie.modules.system.service.dto.JobSmallDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface JobSmallMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/MenuMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/MenuMapper.java new file mode 100644 index 0000000..6d8bffa --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/MenuMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.system.domain.Menu; +import me.zhengjie.modules.system.service.dto.MenuDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Zheng Jie + * @date 2018-12-17 + */ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface MenuMapper extends BaseMapper { +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/RoleMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/RoleMapper.java new file mode 100644 index 0000000..5dc551d --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/RoleMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.system.domain.Role; +import me.zhengjie.modules.system.service.dto.RoleDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Mapper(componentModel = "spring", uses = {MenuMapper.class, DeptMapper.class}, unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface RoleMapper extends BaseMapper { + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/RoleSmallMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/RoleSmallMapper.java new file mode 100644 index 0000000..db034b5 --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/RoleSmallMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.system.domain.Role; +import me.zhengjie.modules.system.service.dto.RoleSmallDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Zheng Jie + * @date 2019-5-23 + */ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface RoleSmallMapper extends BaseMapper { + +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/UserMapper.java b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/UserMapper.java new file mode 100644 index 0000000..510c21b --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/UserMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.system.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.system.domain.User; +import me.zhengjie.modules.system.service.dto.UserDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Mapper(componentModel = "spring",uses = {RoleMapper.class, DeptMapper.class, JobMapper.class},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface UserMapper extends BaseMapper { +} diff --git a/wjcy-system/src/main/java/me/zhengjie/modules/utils/GoogleAuthenticatorUtil.java b/wjcy-system/src/main/java/me/zhengjie/modules/utils/GoogleAuthenticatorUtil.java new file mode 100644 index 0000000..0861ddf --- /dev/null +++ b/wjcy-system/src/main/java/me/zhengjie/modules/utils/GoogleAuthenticatorUtil.java @@ -0,0 +1,179 @@ +package me.zhengjie.modules.utils; + +import cn.hutool.core.util.ObjectUtil; +import me.zhengjie.config.GoogleAuthProperties; +import me.zhengjie.utils.RedisUtils; +import org.apache.commons.codec.binary.Base32; +import org.apache.commons.codec.binary.Base64; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +/** + *

+ * Google Authenticator 工具类 + *

+ * + * @author: rch + * @since: 2020-08-25 + */ +@Component +public class GoogleAuthenticatorUtil { + + private static RedisUtils redisUtils; + @Resource(name = "redisUtils") + public void setRedisUtils(RedisUtils redisUtils) { + GoogleAuthenticatorUtil.redisUtils = redisUtils; + } + + /** default 3 - max 17 (from google docs)最多可偏移的时间 */ + int window_size = 0; + + public void setWindowSize(int s) { + if (s >= 1 && s <= 17) { + window_size = s; + } + } + + /** + * 验证身份验证码是否正确 + * + * @param codes + * 输入的身份验证码 + * @param savedSecret + * 密钥 + * @return + */ + public static Boolean authcode(String codes, String savedSecret) { + long code = 0; + try { + code = Long.parseLong(codes); + } catch (Exception e) { + e.printStackTrace(); + } + long t = System.currentTimeMillis(); + GoogleAuthenticatorUtil ga = new GoogleAuthenticatorUtil(); + // should give 5 * 30 seconds of grace... + ga.setWindowSize(GoogleAuthProperties.WINDOW_SIZE); + boolean r = ga.check_code(savedSecret, code, t); + return r; + } + + /** + * 获取密钥 + * + * @param user + * 用户 + * @param host + * 域 + * @return 密钥 + */ + public static String genSecret(String user, String host) { + + String secretKey = GoogleAuthProperties.REDIS_GOOGLE_AUTH_KEY + "_" + GoogleAuthProperties.SEED + "_" + user; + Object secretValue = redisUtils.get(secretKey); + if (ObjectUtil.isEmpty(secretValue)) { + String secret = generateSecretKey(); + getQRBarcodeURL(user, host, secret); + secretValue = secret; + redisUtils.set(secretKey, secret); + } + + return secretValue.toString(); + } + + private static String generateSecretKey() { + SecureRandom sr = null; + try { + sr = SecureRandom.getInstance(GoogleAuthProperties.RANDOM_NUMBER_ALGORITHM); + sr.setSeed(Base64.decodeBase64(GoogleAuthProperties.SEED)); + byte[] buffer = sr.generateSeed(GoogleAuthProperties.SECRET_SIZE); + Base32 codec = new Base32(); + byte[] bEncodedKey = codec.encode(buffer); + String encodedKey = new String(bEncodedKey); + return encodedKey; + } catch (NoSuchAlgorithmException e) { + // should never occur... configuration error + } + return null; + } + + /** + * 获取二维码图片URL + * + * @param user + * 用户 + * @param host + * 域 + * @param secret + * 密钥 + * @return 二维码URL + */ + public static String getQRBarcodeURL(String user, String host, String secret) { + return String.format(GoogleAuthProperties.QR_CREATE_PREFIX_URL, user, host, secret); + } + + private boolean check_code(String secret, long code, long timeMsec) { + Base32 codec = new Base32(); + byte[] decodedKey = codec.decode(secret); + long t = (timeMsec / 1000L) / 30L; + for (int i = -window_size; i <= window_size; ++i) { + long hash; + try { + hash = verify_code(decodedKey, t + i); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + if (hash == code) { + return true; + } + } + return false; + } + + private static int verify_code(byte[] key, long t) + throws NoSuchAlgorithmException, InvalidKeyException { + byte[] data = new byte[8]; + long value = t; + for (int i = 8; i-- > 0; value >>>= 8) { + data[i] = (byte) value; + } + SecretKeySpec signKey = new SecretKeySpec(key, "HmacSHA1"); + Mac mac = Mac.getInstance("HmacSHA1"); + mac.init(signKey); + byte[] hash = mac.doFinal(data); + int offset = hash[20 - 1] & 0xF; + long truncatedHash = 0; + for (int i = 0; i < 4; ++i) { + truncatedHash <<= 8; + truncatedHash |= (hash[offset + i] & 0xFF); + } + truncatedHash &= 0x7FFFFFFF; + truncatedHash %= 1000000; + return (int) truncatedHash; + } + + public static void main(String[] args) { + /* + * 注意:先运行前两步,获取密钥和二维码url。 然后只运行第三步,填写需要验证的验证码,和第一步生成的密钥 + */ + String user = "testUser"; + String host = "testHost"; + // 第一步:获取密钥 + String secret = genSecret(user, host); + System.out.println("secret:" + secret); + // 第二步:根据密钥获取二维码图片url(可忽略) + String url = getQRBarcodeURL(user, host, secret); + System.out.println("url:" + url); + // 第三步:验证(第一个参数是需要验证的验证码,第二个参数是第一步生成的secret运行) + boolean result = authcode("271239", "OHXU6PLMZMDJIDY6"); + System.out.println("result:" + result); + } +} + diff --git a/wjcy-system/src/main/resources/banner.txt b/wjcy-system/src/main/resources/banner.txt new file mode 100644 index 0000000..d0f401a --- /dev/null +++ b/wjcy-system/src/main/resources/banner.txt @@ -0,0 +1,8 @@ + _ _ _ + | | | | (_) + ___| |______ __ _ __| |_ __ ___ _ _ __ + / _ | |______/ _` |/ _` | '_ ` _ \| | '_ \ + | __| | | (_| | (_| | | | | | | | | | | + \___|_| \__,_|\__,_|_| |_| |_|_|_| |_| + + :: Spring Boot :: (v2.1.0.RELEASE) \ No newline at end of file diff --git a/wjcy-system/src/main/resources/config/application-dev.yml b/wjcy-system/src/main/resources/config/application-dev.yml new file mode 100644 index 0000000..81d0a99 --- /dev/null +++ b/wjcy-system/src/main/resources/config/application-dev.yml @@ -0,0 +1,285 @@ +#配置数据源 +spring: + datasource: + druid: + db-type: com.alibaba.druid.pool.DruidDataSource + driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy + url: jdbc:log4jdbc:mysql://192.168.10.136:3306/wjcy?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false +# url: jdbc:log4jdbc:mysql://192.168.10.85:3306/wjcy?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false + username: root + password: wjcy@123456 +# url: jdbc:log4jdbc:mysql://120.77.145.59:3306/wjcy_2?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false +# username: root +# password: 416909 + # 初始连接数 + initial-size: 5 + # 最小连接数 + min-idle: 15 + # 最大连接数 + max-active: 30 + # 超时时间(以秒数为单位) + remove-abandoned-timeout: 180 + # 获取连接超时时间 + max-wait: 3000 + # 连接有效性检测时间 + time-between-eviction-runs-millis: 60000 + # 连接在池中最小生存的时间 + min-evictable-idle-time-millis: 300000 + # 连接在池中最大生存的时间 + max-evictable-idle-time-millis: 900000 + # 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除 + test-while-idle: true + # 指明是否在从池中取出连接前进行检验,如果检验失败, 则从池中去除连接并尝试取出另一个 + test-on-borrow: true + # 是否在归还到池中前进行检验 + test-on-return: false + # 检测连接是否有效 + validation-query: select 1 + # 配置监控统计 + webStatFilter: + enabled: true + stat-view-servlet: + enabled: true + url-pattern: /druid/* + reset-enable: false + filter: + stat: + enabled: true + # 记录慢SQL + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + slf4j: + enabled: true + statement-create-after-log-enabled: false + statement-close-after-log-enabled: false + result-set-open-after-log-enabled: false + result-set-close-after-log-enabled: false + result-set-next-after-log-enabled: false + + redis: + #数据库索引 + database: 13 + host: 192.168.10.136 + port: 6379 + password: wjcy@123456 +# host: 120.77.145.59 +# port: 6379 +# password: 416909 + #连接超时时间 + timeout: 5000 + #过期时间 1个月(60*60*24*30) + expired: 2592000 + + mvc: + view: + prefix: classpath:/templates/ + suffix: .html + thymeleaf: + cache: false + +knife4j: + enable: true + basic: + enable: true + username: wjcy + password: 123456 + + +logging: + config: classpath:log4j2.xml + level: + me.zhengjie: debug + +#Mybatis plus 配置 +mybatis-plus: + # 映射文件所在路径 + mapper-locations: classpath*:me/zhengjie/dao/mapper/*.xml + # pojo类所在包路径 + #typeAliasesPackage: + # 开启驼峰命名规则自动转换 + configuration: + map-underscore-to-camel-case: true + log-impl: org.apache.ibatis.logging.log4j2.Log4j2Impl + global-config: + db-config: + # 配置表明前缀,例如表设计时表名为tb_manager,对应entity为Manager + #table-prefix: tb_ + #逻辑已删除值 + logic-delete-value: 1 + #逻辑未删除值 + logic-not-delete-value: 0 + # 是否开启like查询,即对 stirng 字段是否使用 like,默认不开启 + column-like: true + +# 登录相关配置 +login: + # 登录缓存 + cache-enable: true + # 是否限制单用户登录 + single-login: false + # 验证码 + login-code: + # 验证码类型配置 查看 LoginProperties 类 + code-type: arithmetic + # 登录图形验证码有效时间/分钟 + expiration: 2 + # 验证码高度 + width: 111 + # 验证码宽度 + height: 36 + # 内容长度 + length: 2 + # 字体名称,为空则使用默认字体 + font-name: + # 字体大小 + font-size: 25 + +#jwt +jwt: + header: Authorization + # 令牌前缀 + token-start-with: Bearer + # 必须使用最少88位的Base64对该令牌进行编码 + base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI= + # 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html + token-validity-in-seconds: 14400000 + # 在线用户key + online-key: online-token- + # 验证码 + code-key: code-key- + # token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期 + detect: 1800000 + # 续期时间范围,默认1小时,单位毫秒 + renew: 3600000 + +#是否允许生成代码,生产环境设置为false +generator: + enabled: true + +#是否开启 swagger-ui +swagger: + enabled: true + +# IP 本地解析 +ip: + local-parsing: true + +# 文件存储路径 +file: + mac: + path: ~/file/ + avatar: ~/avatar/ + linux: + path: /home/luckyDraw/file/ + avatar: /home/luckyDraw/avatar/ + windows: + path: E:\wjcyFileSpace\file\ + avatar: E:\wjcyFileSpace\avatar\ + # 文件大小 /M + maxSize: 100 + avatarMaxSize: 5 + + +system: + imgPath: E:\wjcyFileSpace\file + # 静态资源访问路径(返回前端时添加) +# fileVisitAddr: http://www.images.com + fileVisitAddr: http://localhost:8008/file + #文件上传接口后缀,用来放行xss过滤 + uploadSuffix: file/uploadFile + # 单文件上传大小限制,单位 :MB + maxFileSize: 10 + # 视频单文件上传限制,单位 :MB + maxVideoFileSize: 25 + # ip库文件的绝对路径 window 就是指到resource下的ip2region下 + ip2regionDbPath: E:\CodeWorkSpace\wjcy\wjcy-system\src\main\resources\ip2region\ip2region.db + # 多语言文件路径 + languagePath: /home/waguda/wjcy/language + +config: + # 放掉的api 校验token huijia@biying123 - https://md5jiami.51240.com/ + apiToken: "e6f5e41ca6b103070ff89c812a36eaec" + #文件上传前缀(首位+'/' 末尾不加'/'),用来放行静态资源访问权限(图片,音频等) + uploadPrefix: /capital + # 图片上传保存路径(注意格式,首尾带‘/’) key:图片上传类型 value: + uploadImgPath: + # 用户头像修改 + 1: /wjcy/img/ + 2: /wjcy/rotation/ + 3: /wjcy/article/ + 4: /wjcy/currency/ + # 提现审核提示音 + 5: /wjcy/tones/ + # 聊天室默认头像 + 6: /wjcy/chat/head/ + # 聊天室会员上传的图片 + 7: /wjcy/chat/img/ + # 聊天室会员上传视频 + 8: /wjcy/chat/video/ + 9: /wjcy/promotion/ + # excel + 10: /wjcy/excel/ + 11: /wjcy/export/ + 12: /wjcy/wellReceived/ + 13: /wjcy/dhWellReceived/ + # 支持文件上传的文件格式 + sustainImgFormat: + - img + - jpg + - png + - mp3 + - pem + - jpeg + - gif + - JPG + - JPEG + - PNG + - AVI + - mov + - rmvb + - rm + - FLV + - mp4 + - 3GP + - zip + - xlsx + +# Goole Auth +auth: + secret_size: 10 + seed: g8GjEvTbW5oVSV7avLBdwIHqGlUYNzKFI7izOF8GwLDVKs2m0QN7vxRs2im5MDaNCWGmcD2rvcZx + random_number_algorithm: SHA1PRNG + window_size: 0 + redis_google_auth_key: googelAuthKey + qr_create_prefix_url: https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=otpauth://totp/%s@%s?secret=%s + + +#敦煌api 请求参数 +dh: + access_token: 0QkUo9opYCcmB0UMzqK2XKFFNDDvlpmpRYyDkcVJ + buy_order_url: http://api.dhgate.com/dop/router + buy_order_method: dh.buyer.order.place + buy_order_v: 2.0 + pay_order_url: http://api.dhgate.com/dop/router + pay_order_method: dh.buyer.order.pay + pay_order_v: 1.0 + +# 平台配置 +plats: + dh: + buyOrderUrl: http://api.dhgate.com/dop/router + buyOrderMethod: dh.buyer.order.place + buyOrderv: 2.0 + payOrder_url: http://api.dhgate.com/dop/router + payOrderMethod: dh.buyer.order.pay + payOrderv: 1.0 + +# 影刀 +yd: + accessKeyId: navkbKspVWfjPgm6@platform + accessKeySecret: SuUc0zMfhrQX594eJnwFPm1sqk8CYtNv + callback: http://test.vogocm.com:8008/api/yd/callback diff --git a/wjcy-system/src/main/resources/config/application-local.yml b/wjcy-system/src/main/resources/config/application-local.yml new file mode 100644 index 0000000..262baba --- /dev/null +++ b/wjcy-system/src/main/resources/config/application-local.yml @@ -0,0 +1,411 @@ +#配置数据源 +spring: + datasource: + druid: + db-type: com.alibaba.druid.pool.DruidDataSource + driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy + url: jdbc:log4jdbc:mysql://192.168.110.108:3306/jlt_capiltal_xxs5?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false + username: root + password: root + # 初始连接数 + initial-size: 5 + # 最小连接数 + min-idle: 15 + # 最大连接数 + max-active: 30 + # 超时时间(以秒数为单位) + remove-abandoned-timeout: 180 + # 获取连接超时时间 + max-wait: 3000 + # 连接有效性检测时间 + time-between-eviction-runs-millis: 60000 + # 连接在池中最小生存的时间 + min-evictable-idle-time-millis: 300000 + # 连接在池中最大生存的时间 + max-evictable-idle-time-millis: 900000 + # 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除 + test-while-idle: true + # 指明是否在从池中取出连接前进行检验,如果检验失败, 则从池中去除连接并尝试取出另一个 + test-on-borrow: true + # 是否在归还到池中前进行检验 + test-on-return: false + # 检测连接是否有效 + validation-query: select 1 + # 配置监控统计 + webStatFilter: + enabled: true + stat-view-servlet: + enabled: true + url-pattern: /druid/* + reset-enable: false + filter: + stat: + enabled: true + # 记录慢SQL + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + slf4j: + enabled: true + statement-create-after-log-enabled: false + statement-close-after-log-enabled: false + result-set-open-after-log-enabled: false + result-set-close-after-log-enabled: false + result-set-next-after-log-enabled: false + + redis: + #数据库索引 + database: 12 + host: 192.168.110.108 + port: 6379 + password: tiyu!tiyu! + #连接超时时间 + timeout: 5000 + #过期时间 1个月(60*60*24*30) + expired: 2592000 + + mvc: + view: + prefix: classpath:/templates/ + suffix: .html + thymeleaf: + cache: false + + +logging: + config: classpath:log4j2.xml + level: + me.zhengjie: debug + +#Mybatis plus 配置 +mybatis-plus: + # 映射文件所在路径 + mapper-locations: classpath*:me/zhengjie/dao/mapper/*.xml + # pojo类所在包路径 + #typeAliasesPackage: + # 开启驼峰命名规则自动转换 + configuration: + map-underscore-to-camel-case: true + log-impl: org.apache.ibatis.logging.log4j2.Log4j2Impl + global-config: + db-config: + # 配置表明前缀,例如表设计时表名为tb_manager,对应entity为Manager + #table-prefix: tb_ + #逻辑已删除值 + logic-delete-value: 1 + #逻辑未删除值 + logic-not-delete-value: 0 + # 是否开启like查询,即对 stirng 字段是否使用 like,默认不开启 + column-like: true + +# 登录相关配置 +login: + # 登录缓存 + cache-enable: true + # 是否限制单用户登录 + single-login: false + # 验证码 + login-code: + # 验证码类型配置 查看 LoginProperties 类 + code-type: arithmetic + # 登录图形验证码有效时间/分钟 + expiration: 2 + # 验证码高度 + width: 111 + # 验证码宽度 + height: 36 + # 内容长度 + length: 2 + # 字体名称,为空则使用默认字体 + font-name: + # 字体大小 + font-size: 25 + +#jwt +jwt: + header: Authorization + # 令牌前缀 + token-start-with: Bearer + # 必须使用最少88位的Base64对该令牌进行编码 + base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI= + # 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html + token-validity-in-seconds: 14400000 + # 在线用户key + online-key: online-token- + # 验证码 + code-key: code-key- + # token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期 + detect: 1800000 + # 续期时间范围,默认1小时,单位毫秒 + renew: 3600000 + +#是否允许生成代码,生产环境设置为false +generator: + enabled: true + +#是否开启 swagger-ui +swagger: + enabled: true + +# IP 本地解析 +ip: + local-parsing: true + +# 文件存储路径 +file: + mac: + path: ~/file/ + avatar: ~/avatar/ + linux: + path: /home/luckyDraw/file/ + avatar: /home/luckyDraw/avatar/ + windows: + path: C:\luckyDraw\file\ + avatar: C:\luckyDraw\avatar\ + # 文件大小 /M + maxSize: 100 + avatarMaxSize: 5 + + +system: + imgPath: /home/waguda/capiltal/file/ + # 静态资源访问路径(返回前端时添加) + fileVisitAddr: http://img.com + #文件上传接口后缀,用来放行xss过滤 + uploadSuffix: file/uploadFile + # 单文件上传大小限制,单位 :MB + maxFileSize: 10 + # 视频单文件上传限制,单位 :MB + maxVideoFileSize: 25 + # ip库文件的绝对路径 window 就是指到resource下的ip2region下 + ip2regionDbPath: /home/work/services/capiltal/capiltal-system/ip2region/ip2region.db + # 多语言文件路径 + languagePath: /home/waguda/capiltal/language + wsUrl: ws://192.168.110.99:8110 + # 百度翻译 APPID + baiduAppId: 20211116001000718 + # 百度翻译privateKey + baiduPrivateKey: jSDxw0_QkRnbRdRT0rKY + +config: + # 放掉的api 校验token huijia@biying123 - https://md5jiami.51240.com/ + apiToken: "e6f5e41ca6b103070ff89c812a36eaec" + #文件上传前缀(首位+'/' 末尾不加'/'),用来放行静态资源访问权限(图片,音频等) + uploadPrefix: /capital + # 图片上传保存路径(注意格式,首尾带‘/’) key:图片上传类型 value: + uploadImgPath: + # 用户头像修改 + 1: /capital/img/ + 2: /capital/rotation/ + 3: /capital/article/ + 4: /capital/currency/ + + # 支持文件上传的文件格式 + sustainImgFormat: + - img + - jpg + - png + - mp3 + - pem + - jpeg + - gif + - JPG + - JPEG + - PNG + - AVI + - mov + - rmvb + - rm + - FLV + - mp4 + - 3GP + - zip + +web3j: + # web3j 区块链信息 + linkAddress: + #火币 + - name: HECO + # 服务实现类全限定类名 + serverName: "me.zhengjie.web3j.service.impl.ETHBlockchainServiceImpl" + # rpc 连接地址 + url: https://http-testnet.hecochain.com + # 官网域名+查询交易明细 + domain: https://testnet.hecoinfo.com/tx + # 链路Id,必须以 0x开头 + chainId: "0x100" + #合约币种 + contracts: + USDT: + address: "0x425a2d7c3df8a7872f05405dc6e34b6d9cd714be" + accuracy: 18 + MDX: + address: "0x30e552B5Ce0495A55b9138343dD88d6457a6C66b" + accuracy: 18 + DMT: + address: "0x4da2F416aa79fB0BeCA3D6cf6EB6Fe86b4a747CF" + accuracy: 18 + + # ok链 + - name: OKEX + # 服务实现类全限定类名 + serverName: "me.zhengjie.web3j.service.impl.ETHBlockchainServiceImpl" + # rpc 连接地址 + url: https://exchaintestrpc.okex.org + # 官网域名+查询交易明细 + domain: https://www.oklink.com/zh-cn/oec-test/tx + # 链路Id,必须以 0x开头 + chainId: "0x41" + #合约币种 + contracts: + USDT: + address: "0x1328bB18fe06647878d04fcB94BA5474c85C7616" + accuracy: 18 + MDX: + address: "" + accuracy: 0 + DMT: + address: "" + accuracy: 0 + + # 币安链 + - name: BNB + # 服务实现类全限定类名 + serverName: "me.zhengjie.web3j.service.impl.ETHBlockchainServiceImpl" + # rpc 连接地址 https://data-seed-prebsc-1-s1.binance.org:8545/ https://data-seed-prebsc-2-s3.binance.org:8545 + url: https://data-seed-prebsc-1-s1.binance.org:8545/ + # 官网域名+查询交易明细 + domain: https://testnet.bscscan.com/tx + # 链路Id,必须以 0x开头 + chainId: "0x61" + #合约币种 + contracts: + USDT: + # address: "0x3D39e763d2942816c96E783bb53C7c5DB44AFFF3" + address: "0xA12327AaE5C6CCcf816bAC49136f050FeFe89CB6" + accuracy: 18 + MDX: + address: "0x79CA70F863c4273Bb276F37381e1aD2096b77CeE" + accuracy: 18 + ETH: + address: "0x19E6689Bb9CF7Ef04AFf57B77562E4C943c415cD" + accuracy: 18 + CAKE: + address: "0xeBb3CD5EF4a5875AEfcf02CeAaa77Ac8A164523f" + accuracy: 18 + + # 波场 + - name: TRON + # 服务实现类全限定类名 + serverName: "me.zhengjie.web3j.service.impl.TronBlockchainServiceImpl" + # rpc 连接地址, 可选: mainnet、shasta、nile,或其他节点(例:47.252.19.181) + network: shasta + # http接口请求的URL + url: https://api.shasta.trongrid.io + # 官网域名+查询交易明细 + domain: https://shasta.tronscan.org//#/transaction + # 私钥,波场调用API时,不管什么接口都必须要设置私钥 + hexPrivateKey: "780e0d9997862dfac8e0698c8dd457531c9c13ecf6cec377315e95c30b43c8c4" + # 说明:https://cn.developers.tron.network/reference/%E4%BB%80%E4%B9%88%E6%98%AFapi-key e3506c97-a4b6-4bf7-829a-6a5d48b112f7 + apiKey: "" + #合约币种 + contracts: + USDT: + # TNuoKL1ni8aoshfFL1ASca1Gou9RXwAzfn USDT:TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf + address: "TNpzntv25qsy1HVWQW2jCrhWj5wad3tVcj" + accuracy: 10 + MDX: + address: "" + accuracy: 0 + DMT: + address: "" + accuracy: 0 + + blockchain: + 1: + - currencyType: 1 + name: USDT + - currencyType: 2 + name: MDX + - currencyType: 3 + name: DMT + 2: + - currencyType: 1 + name: USDT + 4: + - currencyType: 1 + name: USDT + - currencyType: 2 + name: MDX + - currencyType: 5 + name: ETH + - currencyType: 4 + name: CAKE + 5: + - currencyType: 1 + name: USDT + +# 采集开奖结果配置 +draw: + config: + configs: + - passType: 1 #链路 火币链 + currency: BTC #采集币种 BTC + url: https://api.huobi.pro/market/history/kline #采集地址 + period: 1min #采集周期 1min, 5min, 15min, 30min, ---- 60min, 4hour, 1day, 1mon, 1week, 1year + symbol: btcusdt #交易对 btcusdt, ethbtc + size: 10 #返回数据条数 1 - 2000 + - passType: 4 #链路 币安链 + currency: BTC #采集币种 BTC + url: https://api.binance.com/api/v3/klines #采集地址 + period: 1m #采集周期 #采集周期 1m, 3m, 5m, 15m, 30m, ---- 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M + symbol: BTCUSDT #交易对 + size: 10 #返回数据条数 1 - 1000 + + + + +#该应用是否启用生产者 +rocketmq: + producer: + isOnOff: on + #发送同一类消息的设置为同一个group,保证唯一,默认不需要设置,rocketmq会使用ip@pid(pid代表jvm名字)作为唯一标示 + groupName: springboot-rocketmq-producer-capiltal + #mq的nameserver地址 43.240.95.168 + namesrvAddr: 192.168.110.108:9876 + #消息最大长度 默认1024*4(4M) + maxMessageSize: 4096 + #发送消息超时时间,默认3000 + sendMsgTimeout: 3000 + #发送消息失败重试次数,默认2 + retryTimesWhenSendFailed: 2 + consumer: + isOnOff: on + groupName: springboot-rocketmq-consumer-capiltal + #mq的nameserver地址 43.240.95.168 + namesrvAddr: 192.168.110.108:9876 + #该消费者订阅的主题和tags("*"号表示订阅该主题下所有的tags),格式:topic~tag1||tag2||tag3;topic2~*; + topics: capiltal-settlement-top~*;capiltal-statistics-member-top~* + consumeThreadMin: 20 + consumeThreadMax: 64 + #设置一次消费消息的条数,默认为1条 + consumeMessageBatchMaxSize: 1 + + +#Goole Auth +auth: + secret_size: 10 + seed: g8GjEvTbW5oVSV7avLBdwIHqGlUYNzKFI7izOF8GwLDVKs2m0QN7vxRs2im5MDaNCWGmcD2rvcZx + random_number_algorithm: SHA1PRNG + window_size: 0 + redis_google_auth_key: googelAuthKey + qr_create_prefix_url: https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=otpauth://totp/%s@%s?secret=%s + +telegram: + bot: + username: capiltal_uat_bot + token: 5008414161:AAHflrbo2v0DN8hpLhZAg5gC787yxFloWlk + chatId: -665412272 \ No newline at end of file diff --git a/wjcy-system/src/main/resources/config/application-prod.yml b/wjcy-system/src/main/resources/config/application-prod.yml new file mode 100644 index 0000000..08396dc --- /dev/null +++ b/wjcy-system/src/main/resources/config/application-prod.yml @@ -0,0 +1,250 @@ +#配置数据源 +spring: + datasource: + druid: + db-type: com.alibaba.druid.pool.DruidDataSource + driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy + url: jdbc:log4jdbc:mysql://mysql:3306/wjcy?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false + username: root + password: wjcy@123456 + # 初始连接数 + initial-size: 5 + # 最小连接数 + min-idle: 15 + # 最大连接数 + max-active: 30 + # 超时时间(以秒数为单位) + remove-abandoned-timeout: 180 + # 获取连接超时时间 + max-wait: 3000 + # 连接有效性检测时间 + time-between-eviction-runs-millis: 60000 + # 连接在池中最小生存的时间 + min-evictable-idle-time-millis: 300000 + # 连接在池中最大生存的时间 + max-evictable-idle-time-millis: 900000 + # 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除 + test-while-idle: true + # 指明是否在从池中取出连接前进行检验,如果检验失败, 则从池中去除连接并尝试取出另一个 + test-on-borrow: true + # 是否在归还到池中前进行检验 + test-on-return: false + # 检测连接是否有效 + validation-query: select 1 + # 配置监控统计 + webStatFilter: + enabled: true + stat-view-servlet: + enabled: true + url-pattern: /druid/* + reset-enable: false + filter: + stat: + enabled: true + # 记录慢SQL + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + slf4j: + enabled: true + statement-create-after-log-enabled: false + statement-close-after-log-enabled: false + result-set-open-after-log-enabled: false + result-set-close-after-log-enabled: false + result-set-next-after-log-enabled: false + + redis: + #数据库索引 + database: 12 + host: redis + port: 6379 + password: wjcy@123456 + #连接超时时间 + timeout: 5000 + #过期时间 1个月(60*60*24*30) + expired: 2592000 + + mvc: + view: + prefix: classpath:/templates/ + suffix: .html + thymeleaf: + cache: false + + +logging: + config: classpath:log4j2.xml + level: + me.zhengjie: debug + +#Mybatis plus 配置 +mybatis-plus: + # 映射文件所在路径 + mapper-locations: classpath*:me/zhengjie/dao/mapper/*.xml + # pojo类所在包路径 + #typeAliasesPackage: + # 开启驼峰命名规则自动转换 + configuration: + map-underscore-to-camel-case: true + log-impl: org.apache.ibatis.logging.log4j2.Log4j2Impl + global-config: + db-config: + # 配置表明前缀,例如表设计时表名为tb_manager,对应entity为Manager + #table-prefix: tb_ + #逻辑已删除值 + logic-delete-value: 1 + #逻辑未删除值 + logic-not-delete-value: 0 + # 是否开启like查询,即对 stirng 字段是否使用 like,默认不开启 + column-like: true + +# 登录相关配置 +login: + # 登录缓存 + cache-enable: true + # 是否限制单用户登录 + single-login: false + # 验证码 + login-code: + # 验证码类型配置 查看 LoginProperties 类 + code-type: arithmetic + # 登录图形验证码有效时间/分钟 + expiration: 2 + # 验证码高度 + width: 111 + # 验证码宽度 + height: 36 + # 内容长度 + length: 2 + # 字体名称,为空则使用默认字体 + font-name: + # 字体大小 + font-size: 25 + +#jwt +jwt: + header: Authorization + # 令牌前缀 + token-start-with: Bearer + # 必须使用最少88位的Base64对该令牌进行编码 + base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI= + # 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html + token-validity-in-seconds: 14400000 + # 在线用户key + online-key: online-token- + # 验证码 + code-key: code-key- + # token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期 + detect: 1800000 + # 续期时间范围,默认1小时,单位毫秒 + renew: 3600000 + +#是否允许生成代码,生产环境设置为false +generator: + enabled: true + +#是否开启 swagger-ui +swagger: + enabled: true + +# IP 本地解析 +ip: + local-parsing: true + +# 文件存储路径 +file: + mac: + path: ~/file/ + avatar: ~/avatar/ + linux: + path: /home/luckyDraw/file/ + avatar: /home/luckyDraw/avatar/ + windows: + path: C:\luckyDraw\file\ + avatar: C:\luckyDraw\avatar\ + # 文件大小 /M + maxSize: 100 + avatarMaxSize: 5 + + +system: + imgPath: /home/work/wjcy/file + # 静态资源访问路径(返回前端时添加) + fileVisitAddr: http://img.com + #文件上传接口后缀,用来放行xss过滤 + uploadSuffix: file/uploadFile + # 单文件上传大小限制,单位 :MB + maxFileSize: 10 + # 视频单文件上传限制,单位 :MB + maxVideoFileSize: 25 + # ip库文件的绝对路径 window 就是指到resource下的ip2region下 + ip2regionDbPath: /home/work/wjcy/wjcy-system/src/main/resources/ip2region/ip2region.db + # 多语言文件路径 + languagePath: /home/work/wjcy/wjcy-system/language + +config: + # 放掉的api 校验token huijia@biying123 - https://md5jiami.51240.com/ + apiToken: "e6f5e41ca6b103070ff89c812a36eaec" + #文件上传前缀(首位+'/' 末尾不加'/'),用来放行静态资源访问权限(图片,音频等) + uploadPrefix: /capital + # 图片上传保存路径(注意格式,首尾带‘/’) key:图片上传类型 value: + uploadImgPath: + # 用户头像修改 + 1: /wjcy/img/ + 2: /wjcy/rotation/ + 3: /wjcy/article/ + 4: /wjcy/currency/ + # 提现审核提示音 + 5: /wjcy/tones/ + # 聊天室默认头像 + 6: /wjcy/chat/head/ + # 聊天室会员上传的图片 + 7: /wjcy/chat/img/ + # 聊天室会员上传视频 + 8: /wjcy/chat/video/ + 9: /wjcy/promotion/ + # excel + 10: /wjcy/excel/ + # 支持文件上传的文件格式 + sustainImgFormat: + - img + - jpg + - png + - mp3 + - pem + - jpeg + - gif + - JPG + - JPEG + - PNG + - AVI + - mov + - rmvb + - rm + - FLV + - mp4 + - 3GP + - zip + - xlsx + +# Goole Auth +auth: + secret_size: 10 + seed: g8GjEvTbW5oVSV7avLBdwIHqGlUYNzKFI7izOF8GwLDVKs2m0QN7vxRs2im5MDaNCWGmcD2rvcZx + random_number_algorithm: SHA1PRNG + window_size: 0 + redis_google_auth_key: googelAuthKey + qr_create_prefix_url: https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=otpauth://totp/%s@%s?secret=%s + +#敦煌api 请求参数 +dh: + access_token: 0QkUo9opYCcmB0UMzqK2XKFFNDDvlpmpRYyDkcVJ + buy_order_url: http://api.dhgate.com/dop/router + buy_order_method: dh.buyer.order.place + buy_order_v: 2.0 + pay_order_url: http://api.dhgate.com/dop/router + pay_order_method: dh.buyer.order.pay + pay_order_v: 1.0 \ No newline at end of file diff --git a/wjcy-system/src/main/resources/config/application-xxs.yml b/wjcy-system/src/main/resources/config/application-xxs.yml new file mode 100644 index 0000000..7471b8b --- /dev/null +++ b/wjcy-system/src/main/resources/config/application-xxs.yml @@ -0,0 +1,417 @@ +#配置数据源 +spring: + datasource: + druid: + db-type: com.alibaba.druid.pool.DruidDataSource + driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy + url: jdbc:log4jdbc:mysql://120.77.145.59:3306/jlt_capiltal?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false + username: root + password: 416909 + # 初始连接数 + initial-size: 5 + # 最小连接数 + min-idle: 15 + # 最大连接数 + max-active: 30 + # 超时时间(以秒数为单位) + remove-abandoned-timeout: 180 + # 获取连接超时时间 + max-wait: 3000 + # 连接有效性检测时间 + time-between-eviction-runs-millis: 60000 + # 连接在池中最小生存的时间 + min-evictable-idle-time-millis: 300000 + # 连接在池中最大生存的时间 + max-evictable-idle-time-millis: 900000 + # 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除 + test-while-idle: true + # 指明是否在从池中取出连接前进行检验,如果检验失败, 则从池中去除连接并尝试取出另一个 + test-on-borrow: true + # 是否在归还到池中前进行检验 + test-on-return: false + # 检测连接是否有效 + validation-query: select 1 + # 配置监控统计 + webStatFilter: + enabled: true + stat-view-servlet: + enabled: true + url-pattern: /druid/* + reset-enable: false + filter: + stat: + enabled: true + # 记录慢SQL + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + slf4j: + enabled: true + statement-create-after-log-enabled: false + statement-close-after-log-enabled: false + result-set-open-after-log-enabled: false + result-set-close-after-log-enabled: false + result-set-next-after-log-enabled: false + + redis: + #数据库索引 + database: 12 + host: 120.77.145.59 + port: 6379 + password: 416909 + #连接超时时间 + timeout: 5000 + #过期时间 1个月(60*60*24*30) + expired: 2592000 + + mvc: + view: + prefix: classpath:/templates/ + suffix: .html + thymeleaf: + cache: false + + +logging: + config: classpath:log4j2.xml + level: + me.zhengjie: debug + +#Mybatis plus 配置 +mybatis-plus: + # 映射文件所在路径 + mapper-locations: classpath*:me/zhengjie/dao/mapper/*.xml + # pojo类所在包路径 + #typeAliasesPackage: + # 开启驼峰命名规则自动转换 + configuration: + map-underscore-to-camel-case: true + log-impl: org.apache.ibatis.logging.log4j2.Log4j2Impl + global-config: + db-config: + # 配置表明前缀,例如表设计时表名为tb_manager,对应entity为Manager + #table-prefix: tb_ + #逻辑已删除值 + logic-delete-value: 1 + #逻辑未删除值 + logic-not-delete-value: 0 + # 是否开启like查询,即对 stirng 字段是否使用 like,默认不开启 + column-like: true + +# 登录相关配置 +login: + # 登录缓存 + cache-enable: true + # 是否限制单用户登录 + single-login: false + # 验证码 + login-code: + # 验证码类型配置 查看 LoginProperties 类 + code-type: arithmetic + # 登录图形验证码有效时间/分钟 + expiration: 2 + # 验证码高度 + width: 111 + # 验证码宽度 + height: 36 + # 内容长度 + length: 2 + # 字体名称,为空则使用默认字体 + font-name: + # 字体大小 + font-size: 25 + +#jwt +jwt: + header: Authorization + # 令牌前缀 + token-start-with: Bearer + # 必须使用最少88位的Base64对该令牌进行编码 + base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI= + # 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html + token-validity-in-seconds: 14400000 + # 在线用户key + online-key: online-token- + # 验证码 + code-key: code-key- + # token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期 + detect: 1800000 + # 续期时间范围,默认1小时,单位毫秒 + renew: 3600000 + +#是否允许生成代码,生产环境设置为false +generator: + enabled: true + +#是否开启 swagger-ui +swagger: + enabled: true + +# IP 本地解析 +ip: + local-parsing: true + +# 文件存储路径 +file: + mac: + path: ~/file/ + avatar: ~/avatar/ + linux: + path: /home/luckyDraw/file/ + avatar: /home/luckyDraw/avatar/ + windows: + path: C:\luckyDraw\file\ + avatar: C:\luckyDraw\avatar\ + # 文件大小 /M + maxSize: 100 + avatarMaxSize: 5 + + +system: + imgPath: /home/waguda/capiltal/file/ + # 静态资源访问路径(返回前端时添加) + fileVisitAddr: http://img.com + #文件上传接口后缀,用来放行xss过滤 + uploadSuffix: file/uploadFile + # 单文件上传大小限制,单位 :MB + maxFileSize: 10 + # 视频单文件上传限制,单位 :MB + maxVideoFileSize: 25 + # ip库文件的绝对路径 window 就是指到resource下的ip2region下 + ip2regionDbPath: /home/work/services/capiltal/capiltal-system/ip2region/ip2region.db + # 多语言文件路径 + languagePath: /home/waguda/capiltal/language + wsUrl: ws://192.168.110.99:8110 + # 百度翻译 APPID + baiduAppId: 20211116001000718 + # 百度翻译privateKey + baiduPrivateKey: jSDxw0_QkRnbRdRT0rKY + +config: + # 放掉的api 校验token huijia@biying123 - https://md5jiami.51240.com/ + apiToken: "e6f5e41ca6b103070ff89c812a36eaec" + #文件上传前缀(首位+'/' 末尾不加'/'),用来放行静态资源访问权限(图片,音频等) + uploadPrefix: /capital + # 图片上传保存路径(注意格式,首尾带‘/’) key:图片上传类型 value: + uploadImgPath: + # 用户头像修改 + 1: /capital/img/ + 2: /capital/rotation/ + 3: /capital/article/ + 4: /capital/currency/ + # 提现审核提示音 + 5: /capital/tones/ + # 聊天室默认头像 + 6: /capital/chat/head/ + # 聊天室会员上传的图片 + 7: /capital/chat/img/ + # 聊天室会员上传视频 + 8: /capital/chat/video/ + 9: /capital/promotion/ + # 平台UBB 富文本 + 10: /capital/platUBB/ + # 支持文件上传的文件格式 + sustainImgFormat: + - img + - jpg + - png + - mp3 + - pem + - jpeg + - gif + - JPG + - JPEG + - PNG + - AVI + - mov + - rmvb + - rm + - FLV + - mp4 + - 3GP + - zip + +web3j: + # web3j 区块链信息 + linkAddress: + #火币 + - name: HECO + # 服务实现类全限定类名 + serverName: "me.zhengjie.web3j.service.impl.ETHBlockchainServiceImpl" + # rpc 连接地址 + url: https://http-testnet.hecochain.com + # 官网域名+查询交易明细 + domain: https://testnet.hecoinfo.com/tx + # 链路Id,必须以 0x开头 + chainId: "0x100" + #合约币种 + contracts: + USDT: + address: "0x425a2d7c3df8a7872f05405dc6e34b6d9cd714be" + accuracy: 18 + MDX: + address: "0x30e552B5Ce0495A55b9138343dD88d6457a6C66b" + accuracy: 18 + DMT: + address: "0x4da2F416aa79fB0BeCA3D6cf6EB6Fe86b4a747CF" + accuracy: 18 + + # ok链 + - name: OKEX + # 服务实现类全限定类名 + serverName: "me.zhengjie.web3j.service.impl.ETHBlockchainServiceImpl" + # rpc 连接地址 + url: https://exchaintestrpc.okex.org + # 官网域名+查询交易明细 + domain: https://www.oklink.com/zh-cn/oec-test/tx + # 链路Id,必须以 0x开头 + chainId: "0x41" + #合约币种 + contracts: + USDT: + address: "0x1328bB18fe06647878d04fcB94BA5474c85C7616" + accuracy: 18 + MDX: + address: "" + accuracy: 0 + DMT: + address: "" + accuracy: 0 + + # 币安链 + - name: BSC + # 服务实现类全限定类名 + serverName: "me.zhengjie.web3j.service.impl.ETHBlockchainServiceImpl" + # rpc 连接地址 https://data-seed-prebsc-1-s1.binance.org:8545/ https://data-seed-prebsc-2-s3.binance.org:8545 + url: https://data-seed-prebsc-1-s1.binance.org:8545/ + # 官网域名+查询交易明细 + domain: https://testnet.bscscan.com/tx + # 链路Id,必须以 0x开头 + chainId: "0x61" + #合约币种 + contracts: + USDT: + # address: "0x3D39e763d2942816c96E783bb53C7c5DB44AFFF3" + address: "0xA12327AaE5C6CCcf816bAC49136f050FeFe89CB6" + accuracy: 18 + MDX: + address: "0x79CA70F863c4273Bb276F37381e1aD2096b77CeE" + accuracy: 18 + ETH: + address: "0x19E6689Bb9CF7Ef04AFf57B77562E4C943c415cD" + accuracy: 18 + CAKE: + address: "0xeBb3CD5EF4a5875AEfcf02CeAaa77Ac8A164523f" + accuracy: 18 + + # 波场 + - name: TRON + # 服务实现类全限定类名 + serverName: "me.zhengjie.web3j.service.impl.TronBlockchainServiceImpl" + # rpc 连接地址, 可选: mainnet、shasta、nile,或其他节点(例:47.252.19.181) + network: shasta + # http接口请求的URL + url: https://api.shasta.trongrid.io + # 官网域名+查询交易明细 + domain: https://shasta.tronscan.org//#/transaction + # 私钥,波场调用API时,不管什么接口都必须要设置私钥 + hexPrivateKey: "780e0d9997862dfac8e0698c8dd457531c9c13ecf6cec377315e95c30b43c8c4" + # 说明:https://cn.developers.tron.network/reference/%E4%BB%80%E4%B9%88%E6%98%AFapi-key e3506c97-a4b6-4bf7-829a-6a5d48b112f7 + apiKey: "" + #合约币种 + contracts: + USDT: + # TNuoKL1ni8aoshfFL1ASca1Gou9RXwAzfn USDT:TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf + address: "TNpzntv25qsy1HVWQW2jCrhWj5wad3tVcj" + accuracy: 10 + MDX: + address: "" + accuracy: 0 + DMT: + address: "" + accuracy: 0 + + blockchain: + 1: + - currencyType: 1 + name: USDT + - currencyType: 2 + name: MDX + - currencyType: 3 + name: DMT + 2: + - currencyType: 1 + name: USDT + 4: + - currencyType: 1 + name: USDT + - currencyType: 2 + name: MDX + - currencyType: 5 + name: ETH + - currencyType: 4 + name: CAKE + 5: + - currencyType: 1 + name: USDT + +# 采集开奖结果配置 +draw: + config: + configs: + - passType: 1 #链路 火币链 + currency: BTC #采集币种 BTC + url: https://api.huobi.pro/market/history/kline #采集地址 + period: 1min #采集周期 1min, 5min, 15min, 30min, ---- 60min, 4hour, 1day, 1mon, 1week, 1year + symbol: btcusdt #交易对 btcusdt, ethbtc + size: 120 #返回数据条数 1 - 2000 + - passType: 4 #链路 币安链 + currency: BTC #采集币种 BTC + url: https://api.binance.com/api/v3/klines #采集地址 + period: 1m #采集周期 #采集周期 1m, 3m, 5m, 15m, 30m, ---- 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M + symbol: BTCUSDT #交易对 + size: 120 #返回数据条数 1 - 1000 + +#该应用是否启用生产者 +rocketmq: + producer: + isOnOff: on + #发送同一类消息的设置为同一个group,保证唯一,默认不需要设置,rocketmq会使用ip@pid(pid代表jvm名字)作为唯一标示 + groupName: springboot-rocketmq-producer-capiltal + #mq的nameserver地址 + namesrvAddr: 120.77.145.59:9876 + #消息最大长度 默认1024*4(4M) + maxMessageSize: 4096 + #发送消息超时时间,默认3000 + sendMsgTimeout: 3000 + #发送消息失败重试次数,默认2 + retryTimesWhenSendFailed: 2 + consumer: + isOnOff: on + groupName: springboot-rocketmq-consumer-capiltal + #mq的nameserver地址 43.240.95.168 + namesrvAddr: 120.77.145.59:9876 + #该消费者订阅的主题和tags("*"号表示订阅该主题下所有的tags),格式:topic~tag1||tag2||tag3;topic2~*; + topics: capiltal-settlement-top~* + consumeThreadMin: 20 + consumeThreadMax: 64 + #设置一次消费消息的条数,默认为1条 + consumeMessageBatchMaxSize: 1 + +# Goole Auth +auth: + secret_size: 10 + seed: g8GjEvTbW5oVSV7avLBdwIHqGlUYNzKFI7izOF8GwLDVKs2m0QN7vxRs2im5MDaNCWGmcD2rvcZx + random_number_algorithm: SHA1PRNG + window_size: 0 + redis_google_auth_key: googelAuthKey + qr_create_prefix_url: https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=otpauth://totp/%s@%s?secret=%s + +#telegram: +# bot: +# username: capiltal_uat_bot +# token: 5008414161:AAHflrbo2v0DN8hpLhZAg5gC787yxFloWlk +# chatId: -665412272 \ No newline at end of file diff --git a/wjcy-system/src/main/resources/config/application.yml b/wjcy-system/src/main/resources/config/application.yml new file mode 100644 index 0000000..bf5a2ad --- /dev/null +++ b/wjcy-system/src/main/resources/config/application.yml @@ -0,0 +1,56 @@ +server: + port: 8008 + +spring: + cache: + type: redis + freemarker: + check-template-location: false + profiles: + active: dev + jackson: + time-zone: GMT+8 + data: + redis: + repositories: + enabled: false + + #配置 Jpa + jpa: + properties: + hibernate: + ddl-auto: none + dialect: org.hibernate.dialect.MySQL5InnoDBDialect + open-in-view: true + +# 开启security功能,配置访问账号密码 +management: + security: + enabled: true +security: + username: admin + userpassword: capiltal&xxs&123 + +task: + pool: + # 核心线程池大小 + core-pool-size: 10 + # 最大线程数 + max-pool-size: 30 + # 活跃时间 + keep-alive-seconds: 60 + # 队列容量 + queue-capacity: 50 + +#七牛云 +qiniu: + # 文件大小 /M + max-size: 15 + +#邮箱验证码有效时间/秒 +code: + expiration: 300 + +#密码加密传输,前端公钥加密,后端私钥解密 +rsa: + private_key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A== diff --git a/wjcy-system/src/main/resources/generator.properties b/wjcy-system/src/main/resources/generator.properties new file mode 100644 index 0000000..2ed9370 --- /dev/null +++ b/wjcy-system/src/main/resources/generator.properties @@ -0,0 +1,27 @@ +#数据库类型转Java类型 +tinyint=Integer +smallint=Integer +mediumint=Integer +int=Integer +integer=Integer + +bigint=Long + +float=Float + +double=Double + +decimal=BigDecimal + +bit=Boolean + +char=String +varchar=String +tinytext=String +text=String +mediumtext=String +longtext=String + +date=Timestamp +datetime=Timestamp +timestamp=Timestamp \ No newline at end of file diff --git a/wjcy-system/src/main/resources/ip2region/ip2region.db b/wjcy-system/src/main/resources/ip2region/ip2region.db new file mode 100644 index 0000000..43e1daf Binary files /dev/null and b/wjcy-system/src/main/resources/ip2region/ip2region.db differ diff --git a/wjcy-system/src/main/resources/log4j2.xml b/wjcy-system/src/main/resources/log4j2.xml new file mode 100644 index 0000000..8a40859 --- /dev/null +++ b/wjcy-system/src/main/resources/log4j2.xml @@ -0,0 +1,252 @@ + + + + + + + + + /home/work/logs/wjcy-system/gz + + + info + + 10M + 1 + 10 + 30d + + 10M + + 7 + 10 + 30d + + 10M + 10 + 30d + + 10M + 10 + 30d + + + %d{yyyy-MM-dd HH:mm:ss.SSS} |-%-5level [%20.40thread] %c [%L] -| %msg%n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/wjcy-system/src/main/resources/log4jdbc.log4j2.properties b/wjcy-system/src/main/resources/log4jdbc.log4j2.properties new file mode 100644 index 0000000..7a39410 --- /dev/null +++ b/wjcy-system/src/main/resources/log4jdbc.log4j2.properties @@ -0,0 +1,5 @@ +# If you use SLF4J. First, you need to tell log4jdbc-log4j2 that you want to use the SLF4J logger +log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator +log4jdbc.auto.load.popular.drivers=false +log4jdbc.drivers=com.mysql.cj.jdbc.Driver +log4j2.formatMsgNoLookups=true \ No newline at end of file diff --git a/wjcy-system/src/main/resources/template/email/email.ftl b/wjcy-system/src/main/resources/template/email/email.ftl new file mode 100644 index 0000000..2f82fcb --- /dev/null +++ b/wjcy-system/src/main/resources/template/email/email.ftl @@ -0,0 +1,48 @@ + + + + + + + +
+
+

尊敬的用户,您好:

+

您正在申请邮箱验证,您的验证码为:

+

${code}

+
+
+
+ Copyright ©${.now?string("yyyy")} EL-ADMIN 后台管理系统 All Rights Reserved. +
+ +
+
+ + diff --git a/wjcy-system/src/main/resources/template/email/taskAlarm.ftl b/wjcy-system/src/main/resources/template/email/taskAlarm.ftl new file mode 100644 index 0000000..b116dec --- /dev/null +++ b/wjcy-system/src/main/resources/template/email/taskAlarm.ftl @@ -0,0 +1,69 @@ + + + + + + + +
+
+

任务信息:

+ + + + + + + + + + + + + + + + + +
任务名称Bean名称执行方法参数内容Cron表达式描述内容
${task.jobName}${task.beanName}${task.methodName}${(task.params)!""}${task.cronExpression}${(task.description)!""}
+
+
+

异常信息:

+
+                ${msg}
+            
+
+
+
+
+ Copyright ©${.now?string("yyyy")} EL-ADMIN 后台管理系统 All Rights Reserved. +
+ +
+ + + diff --git a/wjcy-system/src/main/resources/template/generator/admin/Controller.ftl b/wjcy-system/src/main/resources/template/generator/admin/Controller.ftl new file mode 100644 index 0000000..5a6aa1e --- /dev/null +++ b/wjcy-system/src/main/resources/template/generator/admin/Controller.ftl @@ -0,0 +1,87 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package ${package}.rest; + +import me.zhengjie.annotation.Log; +import ${package}.domain.${className}; +import ${package}.service.${className}Service; +import ${package}.service.dto.${className}QueryCriteria; +import org.springframework.data.domain.Pageable; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import io.swagger.annotations.*; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; + +/** +* @website https://el-admin.vip +* @author ${author} +* @date ${date} +**/ +@RestController +@RequiredArgsConstructor +@Api(tags = "${apiAlias}管理") +@RequestMapping("/api/${changeClassName}") +public class ${className}Controller { + + private final ${className}Service ${changeClassName}Service; + + @Log("导出数据") + @ApiOperation("导出数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('${changeClassName}:list')") + public void download(HttpServletResponse response, ${className}QueryCriteria criteria) throws IOException { + ${changeClassName}Service.download(${changeClassName}Service.queryAll(criteria), response); + } + + @GetMapping + @Log("查询${apiAlias}") + @ApiOperation("查询${apiAlias}") + @PreAuthorize("@el.check('${changeClassName}:list')") + public ResponseEntity query(${className}QueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(${changeClassName}Service.queryAll(criteria,pageable),HttpStatus.OK); + } + + @PostMapping + @Log("新增${apiAlias}") + @ApiOperation("新增${apiAlias}") + @PreAuthorize("@el.check('${changeClassName}:add')") + public ResponseEntity create(@Validated @RequestBody ${className} resources){ + return new ResponseEntity<>(${changeClassName}Service.create(resources),HttpStatus.CREATED); + } + + @PutMapping + @Log("修改${apiAlias}") + @ApiOperation("修改${apiAlias}") + @PreAuthorize("@el.check('${changeClassName}:edit')") + public ResponseEntity update(@Validated @RequestBody ${className} resources){ + ${changeClassName}Service.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除${apiAlias}") + @ApiOperation("删除${apiAlias}") + @PreAuthorize("@el.check('${changeClassName}:del')") + @DeleteMapping + public ResponseEntity delete(@RequestBody ${pkColumnType}[] ids) { + ${changeClassName}Service.deleteAll(ids); + return new ResponseEntity<>(HttpStatus.OK); + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/resources/template/generator/admin/Dto.ftl b/wjcy-system/src/main/resources/template/generator/admin/Dto.ftl new file mode 100644 index 0000000..e388a0b --- /dev/null +++ b/wjcy-system/src/main/resources/template/generator/admin/Dto.ftl @@ -0,0 +1,54 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package ${package}.service.dto; + +import lombok.Data; +<#if hasTimestamp> +import java.sql.Timestamp; + +<#if hasBigDecimal> +import java.math.BigDecimal; + +import java.io.Serializable; +<#if !auto && pkColumnType = 'Long'> +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.ToStringSerializer; + + +/** +* @website https://el-admin.vip +* @description / +* @author ${author} +* @date ${date} +**/ +@Data +public class ${className}Dto implements Serializable { +<#if columns??> + <#list columns as column> + + <#if column.remark != ''> + /** ${column.remark} */ + + <#if column.columnKey = 'PRI'> + <#if !auto && pkColumnType = 'Long'> + /** 防止精度丢失 */ + @JSONField(serializeUsing = ToStringSerializer.class) + + + private ${column.columnType} ${column.changeColumnName}; + + +} \ No newline at end of file diff --git a/wjcy-system/src/main/resources/template/generator/admin/Entity.ftl b/wjcy-system/src/main/resources/template/generator/admin/Entity.ftl new file mode 100644 index 0000000..9d8b1e7 --- /dev/null +++ b/wjcy-system/src/main/resources/template/generator/admin/Entity.ftl @@ -0,0 +1,85 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package ${package}.domain; + +import lombok.Data; +import cn.hutool.core.bean.BeanUtil; +import io.swagger.annotations.ApiModelProperty; +import cn.hutool.core.bean.copier.CopyOptions; +import javax.persistence.*; +<#if isNotNullColumns??> +import javax.validation.constraints.*; + +<#if hasDateAnnotation> +import javax.persistence.Entity; +import javax.persistence.Table; +import org.hibernate.annotations.*; + +<#if hasTimestamp> +import java.sql.Timestamp; + +<#if hasBigDecimal> +import java.math.BigDecimal; + +import java.io.Serializable; + +/** +* @website https://el-admin.vip +* @description / +* @author ${author} +* @date ${date} +**/ +@Entity +@Data +@Table(name="${tableName}") +public class ${className} implements Serializable { +<#if columns??> + <#list columns as column> + + <#if column.columnKey = 'PRI'> + @Id + <#if auto> + @GeneratedValue(strategy = GenerationType.IDENTITY) + + + @Column(name = "${column.columnName}"<#if column.columnKey = 'UNI'>,unique = true<#if column.istNotNull && column.columnKey != 'PRI'>,nullable = false) + <#if column.istNotNull && column.columnKey != 'PRI'> + <#if column.columnType = 'String'> + @NotBlank + <#else> + @NotNull + + + <#if (column.dateAnnotation)?? && column.dateAnnotation != ''> + <#if column.dateAnnotation = 'CreationTimestamp'> + @CreationTimestamp + <#else> + @UpdateTimestamp + + + <#if column.remark != ''> + @ApiModelProperty(value = "${column.remark}") + <#else> + @ApiModelProperty(value = "${column.changeColumnName}") + + private ${column.columnType} ${column.changeColumnName}; + + + + public void copy(${className} source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/resources/template/generator/admin/Mapper.ftl b/wjcy-system/src/main/resources/template/generator/admin/Mapper.ftl new file mode 100644 index 0000000..3387f06 --- /dev/null +++ b/wjcy-system/src/main/resources/template/generator/admin/Mapper.ftl @@ -0,0 +1,32 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package ${package}.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import ${package}.domain.${className}; +import ${package}.service.dto.${className}Dto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @website https://el-admin.vip +* @author ${author} +* @date ${date} +**/ +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface ${className}Mapper extends BaseMapper<${className}Dto, ${className}> { + +} \ No newline at end of file diff --git a/wjcy-system/src/main/resources/template/generator/admin/QueryCriteria.ftl b/wjcy-system/src/main/resources/template/generator/admin/QueryCriteria.ftl new file mode 100644 index 0000000..2a4d1ff --- /dev/null +++ b/wjcy-system/src/main/resources/template/generator/admin/QueryCriteria.ftl @@ -0,0 +1,81 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package ${package}.service.dto; + +import lombok.Data; +<#if queryHasTimestamp> +import java.sql.Timestamp; + +<#if queryHasBigDecimal> +import java.math.BigDecimal; + +<#if betweens??> +import java.util.List; + +<#if queryColumns??> +import me.zhengjie.annotation.Query; + + +/** +* @website https://el-admin.vip +* @author ${author} +* @date ${date} +**/ +@Data +public class ${className}QueryCriteria{ +<#if queryColumns??> + <#list queryColumns as column> + +<#if column.queryType = '='> + /** 精确 */ + @Query + private ${column.columnType} ${column.changeColumnName}; + +<#if column.queryType = 'Like'> + /** 模糊 */ + @Query(type = Query.Type.INNER_LIKE) + private ${column.columnType} ${column.changeColumnName}; + +<#if column.queryType = '!='> + /** 不等于 */ + @Query(type = Query.Type.NOT_EQUAL) + private ${column.columnType} ${column.changeColumnName}; + +<#if column.queryType = 'NotNull'> + /** 不为空 */ + @Query(type = Query.Type.NOT_NULL) + private ${column.columnType} ${column.changeColumnName}; + +<#if column.queryType = '>='> + /** 大于等于 */ + @Query(type = Query.Type.GREATER_THAN) + private ${column.columnType} ${column.changeColumnName}; + +<#if column.queryType = '<='> + /** 小于等于 */ + @Query(type = Query.Type.LESS_THAN) + private ${column.columnType} ${column.changeColumnName}; + + + +<#if betweens??> + <#list betweens as column> + /** BETWEEN */ + @Query(type = Query.Type.BETWEEN) + private List<${column.columnType}> ${column.changeColumnName}; + + +} \ No newline at end of file diff --git a/wjcy-system/src/main/resources/template/generator/admin/Repository.ftl b/wjcy-system/src/main/resources/template/generator/admin/Repository.ftl new file mode 100644 index 0000000..2420d4b --- /dev/null +++ b/wjcy-system/src/main/resources/template/generator/admin/Repository.ftl @@ -0,0 +1,40 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package ${package}.repository; + +import ${package}.domain.${className}; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** +* @website https://el-admin.vip +* @author ${author} +* @date ${date} +**/ +public interface ${className}Repository extends JpaRepository<${className}, ${pkColumnType}>, JpaSpecificationExecutor<${className}> { +<#if columns??> + <#list columns as column> + <#if column.columnKey = 'UNI'> + /** + * 根据 ${column.capitalColumnName} 查询 + * @param ${column.columnName} / + * @return / + */ + ${className} findBy${column.capitalColumnName}(${column.columnType} ${column.columnName}); + + + +} \ No newline at end of file diff --git a/wjcy-system/src/main/resources/template/generator/admin/Service.ftl b/wjcy-system/src/main/resources/template/generator/admin/Service.ftl new file mode 100644 index 0000000..9ecbe24 --- /dev/null +++ b/wjcy-system/src/main/resources/template/generator/admin/Service.ftl @@ -0,0 +1,83 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package ${package}.service; + +import ${package}.domain.${className}; +import ${package}.service.dto.${className}Dto; +import ${package}.service.dto.${className}QueryCriteria; +import org.springframework.data.domain.Pageable; +import java.util.Map; +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; + +/** +* @website https://el-admin.vip +* @description 服务接口 +* @author ${author} +* @date ${date} +**/ +public interface ${className}Service { + + /** + * 查询数据分页 + * @param criteria 条件 + * @param pageable 分页参数 + * @return Map + */ + Map queryAll(${className}QueryCriteria criteria, Pageable pageable); + + /** + * 查询所有数据不分页 + * @param criteria 条件参数 + * @return List<${className}Dto> + */ + List<${className}Dto> queryAll(${className}QueryCriteria criteria); + + /** + * 根据ID查询 + * @param ${pkChangeColName} ID + * @return ${className}Dto + */ + ${className}Dto findById(${pkColumnType} ${pkChangeColName}); + + /** + * 创建 + * @param resources / + * @return ${className}Dto + */ + ${className}Dto create(${className} resources); + + /** + * 编辑 + * @param resources / + */ + void update(${className} resources); + + /** + * 多选删除 + * @param ids / + */ + void deleteAll(${pkColumnType}[] ids); + + /** + * 导出数据 + * @param all 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List<${className}Dto> all, HttpServletResponse response) throws IOException; +} \ No newline at end of file diff --git a/wjcy-system/src/main/resources/template/generator/admin/ServiceImpl.ftl b/wjcy-system/src/main/resources/template/generator/admin/ServiceImpl.ftl new file mode 100644 index 0000000..17f0454 --- /dev/null +++ b/wjcy-system/src/main/resources/template/generator/admin/ServiceImpl.ftl @@ -0,0 +1,157 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package ${package}.service.impl; + +import ${package}.domain.${className}; +<#if columns??> + <#list columns as column> + <#if column.columnKey = 'UNI'> + <#if column_index = 1> +import me.zhengjie.exception.EntityExistException; + + + + +import me.zhengjie.utils.ValidationUtil; +import me.zhengjie.utils.FileUtil; +import lombok.RequiredArgsConstructor; +import ${package}.repository.${className}Repository; +import ${package}.service.${className}Service; +import ${package}.service.dto.${className}Dto; +import ${package}.service.dto.${className}QueryCriteria; +import ${package}.service.mapstruct.${className}Mapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +<#if !auto && pkColumnType = 'Long'> +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.IdUtil; + +<#if !auto && pkColumnType = 'String'> +import cn.hutool.core.util.IdUtil; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.QueryHelp; +import java.util.List; +import java.util.Map; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.LinkedHashMap; + +/** +* @website https://el-admin.vip +* @description 服务实现 +* @author ${author} +* @date ${date} +**/ +@Service +@RequiredArgsConstructor +public class ${className}ServiceImpl implements ${className}Service { + + private final ${className}Repository ${changeClassName}Repository; + private final ${className}Mapper ${changeClassName}Mapper; + + @Override + public Map queryAll(${className}QueryCriteria criteria, Pageable pageable){ + Page<${className}> page = ${changeClassName}Repository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(${changeClassName}Mapper::toDto)); + } + + @Override + public List<${className}Dto> queryAll(${className}QueryCriteria criteria){ + return ${changeClassName}Mapper.toDto(${changeClassName}Repository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); + } + + @Override + @Transactional + public ${className}Dto findById(${pkColumnType} ${pkChangeColName}) { + ${className} ${changeClassName} = ${changeClassName}Repository.findById(${pkChangeColName}).orElseGet(${className}::new); + ValidationUtil.isNull(${changeClassName}.get${pkCapitalColName}(),"${className}","${pkChangeColName}",${pkChangeColName}); + return ${changeClassName}Mapper.toDto(${changeClassName}); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public ${className}Dto create(${className} resources) { +<#if !auto && pkColumnType = 'Long'> + Snowflake snowflake = IdUtil.createSnowflake(1, 1); + resources.set${pkCapitalColName}(snowflake.nextId()); + +<#if !auto && pkColumnType = 'String'> + resources.set${pkCapitalColName}(IdUtil.simpleUUID()); + +<#if columns??> + <#list columns as column> + <#if column.columnKey = 'UNI'> + if(${changeClassName}Repository.findBy${column.capitalColumnName}(resources.get${column.capitalColumnName}()) != null){ + throw new EntityExistException(${className}.class,"${column.columnName}",resources.get${column.capitalColumnName}()); + } + + + + return ${changeClassName}Mapper.toDto(${changeClassName}Repository.save(resources)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(${className} resources) { + ${className} ${changeClassName} = ${changeClassName}Repository.findById(resources.get${pkCapitalColName}()).orElseGet(${className}::new); + ValidationUtil.isNull( ${changeClassName}.get${pkCapitalColName}(),"${className}","id",resources.get${pkCapitalColName}()); +<#if columns??> + <#list columns as column> + <#if column.columnKey = 'UNI'> + <#if column_index = 1> + ${className} ${changeClassName}1 = null; + + ${changeClassName}1 = ${changeClassName}Repository.findBy${column.capitalColumnName}(resources.get${column.capitalColumnName}()); + if(${changeClassName}1 != null && !${changeClassName}1.get${pkCapitalColName}().equals(${changeClassName}.get${pkCapitalColName}())){ + throw new EntityExistException(${className}.class,"${column.columnName}",resources.get${column.capitalColumnName}()); + } + + + + ${changeClassName}.copy(resources); + ${changeClassName}Repository.save(${changeClassName}); + } + + @Override + public void deleteAll(${pkColumnType}[] ids) { + for (${pkColumnType} ${pkChangeColName} : ids) { + ${changeClassName}Repository.deleteById(${pkChangeColName}); + } + } + + @Override + public void download(List<${className}Dto> all, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (${className}Dto ${changeClassName} : all) { + Map map = new LinkedHashMap<>(); + <#list columns as column> + <#if column.columnKey != 'PRI'> + <#if column.remark != ''> + map.put("${column.remark}", ${changeClassName}.get${column.capitalColumnName}()); + <#else> + map.put(" ${column.changeColumnName}", ${changeClassName}.get${column.capitalColumnName}()); + + + + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +} \ No newline at end of file diff --git a/wjcy-system/src/main/resources/template/generator/front/api.ftl b/wjcy-system/src/main/resources/template/generator/front/api.ftl new file mode 100644 index 0000000..9587d0d --- /dev/null +++ b/wjcy-system/src/main/resources/template/generator/front/api.ftl @@ -0,0 +1,27 @@ +import request from '@/utils/request' + +export function add(data) { + return request({ + url: 'api/${changeClassName}', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/${changeClassName}/', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/${changeClassName}', + method: 'put', + data + }) +} + +export default { add, edit, del } diff --git a/wjcy-system/src/main/resources/template/generator/front/index.ftl b/wjcy-system/src/main/resources/template/generator/front/index.ftl new file mode 100644 index 0000000..4b9111a --- /dev/null +++ b/wjcy-system/src/main/resources/template/generator/front/index.ftl @@ -0,0 +1,169 @@ +<#--noinspection ALL--> + + + + + diff --git a/wjcy-system/src/main/resources/templates/index.html b/wjcy-system/src/main/resources/templates/index.html new file mode 100644 index 0000000..e79ccbb --- /dev/null +++ b/wjcy-system/src/main/resources/templates/index.html @@ -0,0 +1,244 @@ + + + + + + 测试页面 + + + + +
+ +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + +
+
    +
  • + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + +
  • +
+
+ +
+
    +
  • +
  • +
  • +
  • +
+
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
    +
  • +
  • +
+
+
    +
  • +
  • + + +
  • +
  • +
+
+ +
+ + +
+ + \ No newline at end of file diff --git a/wjcy-system/src/test/java/me/zhengjie/CtBuyerControllerTest.java b/wjcy-system/src/test/java/me/zhengjie/CtBuyerControllerTest.java new file mode 100644 index 0000000..5f10518 --- /dev/null +++ b/wjcy-system/src/test/java/me/zhengjie/CtBuyerControllerTest.java @@ -0,0 +1,127 @@ +package me.zhengjie; + +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSONArray; +import me.zhengjie.config.SystemConfig; +import me.zhengjie.entity.CtBuyer; +import me.zhengjie.entity.CtExcel; +import me.zhengjie.entity.CtExcelImportInfo; +import me.zhengjie.enums.ExcelStatusEnum; +import me.zhengjie.enums.YesOrNoEnum; +import me.zhengjie.service.CtBuyerService; +import me.zhengjie.service.CtExcelImportInfoService; +import me.zhengjie.service.CtExcelService; +import me.zhengjie.utils.excel.ExcelUtils; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class CtBuyerControllerTest { + + @Resource + private CtBuyerService ctBuyerService; + + @Test + public void testTest() { + + System.out.println("ttttttttttttttttt"); + } + + + @Test + public void batchAddCtBuyer() { + List ctBuyerServiceList = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + CtBuyer ctBuyer = new CtBuyer(); + ctBuyer.setAccount("account-" + i); + ctBuyer.setNickName("nickName-" + i); + ctBuyer.setPwd("pwd-" + i); + + ctBuyerServiceList.add(ctBuyer); + } + + ctBuyerService.saveBatch(ctBuyerServiceList); + } + + + /** + * Excel 导入解析为json + */ + @Test + public void JsonArryByExcel() throws Exception { + + // 读取文件 + File file = new File("E:\\home\\waguda\\wjcy\\file\\wjcy\\excel\\20220622\\1539559881726894080.xlsx"); + JSONArray array = ExcelUtils.readFile(file); + System.out.println("=======json解析:" + array); + } + + + @Test + public void excelJson() { + String value = "[{\"name\":\"rch1\", \"age\":100},{\"name\":\"rch2\", \"age\":101}]"; + + cn.hutool.json.JSONArray userJsonArray = JSONUtil.parseArray(value); + List excelUserTestList = JSONUtil.toList(userJsonArray, ExcelUserTest.class); + for (ExcelUserTest excelUserTest:excelUserTestList) { + System.out.println("----excelUserTest:" + excelUserTest); + } + + // ----excelUserTest:ExcelUserTest(name=rch1, age=100) + // ----excelUserTest:ExcelUserTest(name=rch2, age=101) + } + + + @Resource + private CtExcelService ctExcelService; + @Resource + private CtExcelImportInfoService ctExcelImportInfoService; + + @Test + public void sqlExcelJson() { + CtExcel ctExcel = ctExcelService.getById(22L); + + String platImageUrl = SystemConfig.IMG_PATH; + String pathUrl = ctExcel.getPath(); + String excelPathUrl = platImageUrl + pathUrl; + + // 读取文件 + File file = new File(excelPathUrl); + + + + try { + + JSONArray array = ExcelUtils.readFile(file); + System.out.println("=======json解析:" + array); + + List excelImportInfoList = ExcelUtils.readFile(file, CtExcelImportInfo.class); + System.out.println("array:" + JSONUtil.toJsonStr(excelImportInfoList)); + + + ctExcelImportInfoService.saveBatch(excelImportInfoList); + + System.out.println("=========end"); + } catch (Exception exception) { + System.out.println(exception.getMessage()); + } + } + + @Test + public void enumTest() { + Integer yesOrNo = YesOrNoEnum.YES.value(); + Integer value = ExcelStatusEnum.TOBE.value(); + System.out.println("ttt"); + } +} + + diff --git a/wjcy-system/src/test/java/me/zhengjie/CtPlatformControllerTest.java b/wjcy-system/src/test/java/me/zhengjie/CtPlatformControllerTest.java new file mode 100644 index 0000000..d3acdb2 --- /dev/null +++ b/wjcy-system/src/test/java/me/zhengjie/CtPlatformControllerTest.java @@ -0,0 +1,43 @@ +package me.zhengjie; + +import me.zhengjie.entity.CtPlatform; +import me.zhengjie.service.CtPlatformService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; + + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class CtPlatformControllerTest { + + @Resource + private CtPlatformService ctPlatformService; + + + + + + @Test + public void batchAddCtBuyer() { + List ctPlatformList = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + CtPlatform ctPlatform = new CtPlatform(); + + ctPlatform.setAddress("address-" + i); + ctPlatform.setName("name-" + i); + ctPlatform.setPhone("phone-" + i); + + ctPlatformList.add(ctPlatform); + } + + ctPlatformService.saveBatch(ctPlatformList); + } +} + + diff --git a/wjcy-system/src/test/java/me/zhengjie/DhApiTest.java b/wjcy-system/src/test/java/me/zhengjie/DhApiTest.java new file mode 100644 index 0000000..e51ffcc --- /dev/null +++ b/wjcy-system/src/test/java/me/zhengjie/DhApiTest.java @@ -0,0 +1,461 @@ +package me.zhengjie; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSONArray; +import me.zhengjie.constant.PublicConstant; +import me.zhengjie.entity.*; +import me.zhengjie.entity.quartz.JobQueryByUuidReturn; +import me.zhengjie.entity.quartz.Params; +import me.zhengjie.enums.ClickFarmingStatusEnum; +import me.zhengjie.service.*; +import me.zhengjie.service.vo.BuyOrderVO; +import me.zhengjie.service.vo.CtBuyerDetailVO; +import me.zhengjie.utils.HttpClientUtil; +import me.zhengjie.utils.RedisUtils; +import me.zhengjie.utils.YdSignUtil; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; +import java.io.File; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 对接请求敦煌Api测试 + * + * @author rch + * @create 2022-06-27 + */ + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class DhApiTest { + + @Resource + private CtExcelImportInfoService ctExcelImportInfoService; + @Resource + private YdQuartzService ydQuartzService; + @Resource + private CtClickFarmingService ctClickFarmingService; + @Resource + private CtBuyerService ctBuyerService; + + @Test + public void doGetHttp() { + // PostMan - DoGet - 分销-订单-下单模块-第三方Api + // 1. 请求参数 + + String url = "http://api.dhgate.com/dop/router"; + String v = "2.0"; + String accessToken = "0QkUo9opYCcmB0UMzqK2XKFFNDDvlpmpRYyDkcVJ"; + String method = "dh.buyer.order.place"; + String formDetailInfo = "ssshop"; + + Map params = new HashMap<>(); + // 统一请求参数 + params.put("timestamp", System.currentTimeMillis()); + params.put("v", v); + params.put("access_token", accessToken); + params.put("method", method); + + // boby + params.put("fromDetailInfo", formDetailInfo); + + // PostMan - DoGet - 分销-订单-支付模块-第三方Api + CtExcelImportInfo ctExcelImportInfo = ctExcelImportInfoService.getById(1L); + + String carList = ctExcelImportInfo.getCartList(); + String contacInfo = ctExcelImportInfo.getContactInfo(); + + // Json 处理 参数检验 +// List ctParamProductList = JSONUtil.toList(JSONUtil.parseArray(carList), CtParamProduct.class); +// CtParamContactInfo ctParamContactInfo = JSONUtil.toBean(JSONUtil.parseObj(contacInfo), CtParamContactInfo.class); +// +//// JSONArray ctParamProductJsonArray = new JSONArray(); +//// for (CtParamProduct ctParamProduct:ctParamProductList) { +//// System.out.println("------ctParamProduct:" + ctParamProduct.toString()); +//// // 产品数量 必填 +//// if (ObjectUtil.isEmpty(ctParamProduct.getQuantity())) { +//// // 参数必填 +//// continue; +//// } +//// +//// // 产品编码 必填 +//// if (ObjectUtil.isEmpty(ctParamProduct.getQuantity())) { +//// // 参数必填 +//// continue; +//// } +//// +//// // 产品skuMd5 必填 +//// if (ObjectUtil.isEmpty(ctParamProduct.getQuantity())) { +//// // 参数必填 +//// continue; +//// } +//// +//// // 处理 +//// JSONObject ctParamProductJsonObject = JsonDealUtils.getNoNullValue(JSONUtil.toJsonStr(ctParamProduct)); +//// ctParamProductJsonArray.add(ctParamProductJsonObject); +//// } +//// +//// if (ObjectUtil.isNotEmpty(ctParamContactInfo)) { +//// System.out.println("------contactInfoList:" + ctParamContactInfo.toString()); +//// } +//// +//// // 空值去除 +////// JSONObject carListJsonObject = JsonDealUtils.getNoNullValue(carList); +//// JSONObject contacInfoJsonObject = JsonDealUtils.getNoNullValue(contacInfo); +//// +////// System.out.println("carListJsonObject:" + carListJsonObject.toString()); +//// System.out.println("contacInfoJsonObject:" + contacInfoJsonObject.toString()); +//// System.out.println("ctParamProductJsonArray:" + ctParamProductJsonArray.toString()); + + params.put("cartList", carList); + params.put("contactInfo", contacInfo); + + + String responseStr = HttpClientUtil.doPostHttp(url, params); + System.out.println("responseStr: " + responseStr); + } + + + @Test + public void postParamQuest() { + + String url = "http://api.dhgate.com/dop/router"; + String v = "2.0"; + String accessToken = "0QkUo9opYCcmB0UMzqK2XKFFNDDvlpmpRYyDkcVJ"; + String method = "dh.buyer.order.place"; + String formDetailInfo = "ssshop"; + + Map params = new HashMap<>(); + // 统一请求参数 + params.put("timestamp", System.currentTimeMillis()); + params.put("v", v); + params.put("access_token", accessToken); + params.put("method", method); + + // boby + params.put("fromDetailInfo", formDetailInfo); + params.put("cartList", "[{\"quantity\":10,\"itemcode\":634706114,\"skuMd5\":\"562e86410bd37a7bb4170cfe6e03203f\"}]"); + params.put("contactInfo", "{\"country\":\"US\",\"firstname\":\"zhao\",\"city\":\"Chicago\",\"postalcode\":\"12345\",\"orgnazationbaseid\":\"ff80808166f780340167547325e700e0\",\"addressline2\":\"youshengdasha apartment\",\"addressline1\":\"chengfulu road, hawio\",\"tel\":\"1311111111\",\"state\":\"California\",\"email\":\"zhaoyiyi@163.com\",\"lastname\":\"yiyi\"}"); + + String responseStr = HttpClientUtil.doPostHttp(url, params); + + // JONS 类型转换 + BuyOrderVO buyOrderVO = JSONUtil.toBean(responseStr, BuyOrderVO.class); + System.out.println("==================buyOrderVO:" + buyOrderVO.toString()); + + System.out.println("responseStr: " + responseStr); + } + + + @Resource + private CtOrderService ctOrderService; + + @Test + public void funRequestExcelInfoToOrder() { + CtExcelImportInfo ctExcelImportInfo = ctExcelImportInfoService.getById(2L); + Boolean resultBoolean = ctOrderService.buyOrderApi(ctExcelImportInfo); + System.out.println("========resultBoolean:" + resultBoolean); + } + + + @Test + public void payOrder() { + CtOrder ctOrder = ctOrderService.getById(1L); + Boolean result = ctOrderService.payOrderApi(ctOrder); + System.out.println("pay Order result:" + result); + } + + @Test + public void testAccountName() { +// CtRebot ctRebot = ctRebotService.getByAccountNameLock("supren@vogocm"); +// System.out.println("ctRebot:" + JSONUtil.toJsonStr(ctRebot)); + } + + + @Test + public void testSign() { + // 鉴权 + YdSign ydSign = new YdSign(); + ydSign.setTimestamp(Long.valueOf("1659757066")); + ydSign.setAccessKeyId("navkbKspVWfjPgm6@platform"); + ydSign.setAccessKeySecret("SuUc0zMfhrQX594eJnwFPm1sqk8CYtNv"); + ydSign.setBodyMd5("ed88dfe75bf53a33c49531d0d4635c71"); + + String getSign = "75bd5b7154a738c8b9c65eca523c31abfcfc24c3"; + String sign = YdSignUtil.getSign(ydSign); + System.out.println("sign:" + sign); + + if (ObjectUtil.isEmpty(sign) || !getSign.equals(sign)) { + System.out.println("不相等"); + } + } + + + @Test + public void queryJobByUuid() { + String uuid = "ef75ea22-7b63-4fcb-acf5-6de3b02ce7f7"; + String accessKey = "navkbKspVWfjPgm6@platform"; + String accessSercet = "SuUc0zMfhrQX594eJnwFPm1sqk8CYtNv"; + JobQueryByUuidReturn jobQueryByUuidReturn = ydQuartzService.queryJobUuid(uuid, accessKey, accessSercet); + System.out.println("==========JSON(jobQueryByUuidReturn) =" + JSONUtil.toJsonStr(jobQueryByUuidReturn)); + } + + + /** + * 解析json 区分错误类型 4.有订单id之前的异常 5.有订单未支付 6.支付成功异常 + * @param remark + * @return + */ + private Integer analysisReturnJson(String remark) { + + final String startModular = "】任务失败,在【"; + final String endModular = "】中第"; + final String endLineNumber = "行:出错"; + + // 根据规则解析 + // "remark": "【0757f764-07b4-4d4d-a48d-e1e13b598a1f】任务失败,在【5-1清空银行卡】中第17行:出错:未找到元素, 元素名: 按钮_OK", + // "remark": "【9a92a414-e957-47f8-ada1-7296723769a9】任务失败,在【9-1优惠劵】中第7行:出错:未找到元素", + // "remark": "【60a92f00-f7cb-4321-aa0b-6f18814fb462】任务失败,在【3.切换国家】中第8行:出错:未找到元素", + // "remark": "【81f6c1ac-6493-40cf-83fd-867b1a39e3ca】任务失败,在【9-3添加银行卡】中第5行:出错:未找到元素, 元素名: SAVE CARD", + // "remark": "【e201a1b3-f0a1-42b9-8315-d6736eead5a4】任务失败,在【1-2清空浏览器数据】中第1行:出错:操作无法执行!请重启当前浏览器 或 重装当前浏览器插件后再次尝试。", + + /** + * 1.切换VPN + * 2.关闭弹窗 + * 3.清空浏览器 + * 4.切换国家 + * 5.登录 + * 6.清空购物车 + * 6-1.清空银行卡 + * 7.搜索商品 + * 7-1.随意浏览界面 + * 7-2.滚动鼠标浏览界面 + * 7-3.随机点击商品 + * 7-4.浏览随机商品 + * 7-5匹配商品信息 + * 8.商品下单 --------------------------订单前:流程第12行点击加入购物车 + * 8-1.滚动鼠标浏览商品 + * 8-2.查找规格 + * 8-3.查找颜色 + * 8-4.商品个数 + * 9.购物车 + * 9-1.留言 + * 9-2.添加银行卡 + * 9-3.选择银行卡有效时间 + * 9-4.选择优惠券 + * 10.回到首页----------------------回到首页:流程第11行点击首页 + * 10-1.获取订单信息 + * 11.退出账号 + */ + if (ObjectUtil.isEmpty(remark)) { + return ClickFarmingStatusEnum.EXECUTION_FAILE.value(); + } + + String modular = remark.substring(remark.indexOf(startModular) + 8, remark.indexOf(endModular)); + String lineNumber = remark.substring(remark.indexOf(endModular) + 3, remark.indexOf(endLineNumber)); + + // 子模块可以忽略 + Integer modularInteger = 0; + Integer lineNumberInteger = 0; + if (ObjectUtil.isNotEmpty(modular)) { + if (modular.contains(".")) { + modularInteger = Integer.valueOf(modular.substring(0, modular.indexOf("."))); + } else if (modular.contains("-")) { + modularInteger = Integer.valueOf(modular.split("-")[0]); + } + } + if (ObjectUtil.isNotEmpty(lineNumber)) { + lineNumberInteger = Integer.valueOf(lineNumber); + } + + if (modularInteger < 8) { + return ClickFarmingStatusEnum.EXECUTION_FAILE.value(); + } else if(modularInteger == 8) { + if (lineNumberInteger <= 12) { + return ClickFarmingStatusEnum.EXECUTION_FAILE.value(); + } else { + return ClickFarmingStatusEnum.AWAITING_PAYMENT.value(); + } + } else if (modularInteger < 10){ + return ClickFarmingStatusEnum.AWAITING_PAYMENT.value(); + } else if(modularInteger == 10) { + if (lineNumberInteger <= 11) { + return ClickFarmingStatusEnum.AWAITING_PAYMENT.value(); + } else { + return ClickFarmingStatusEnum.PAY_OK_ERROR.value(); + } + } else { + return ClickFarmingStatusEnum.PAY_OK_ERROR.value(); + } + } + + @Test + public void test11() { + + // 根据规则解析 + // "remark": "【0757f764-07b4-4d4d-a48d-e1e13b598a1f】任务失败,在【5-1清空银行卡】中第17行:出错:未找到元素, 元素名: 按钮_OK", + // "remark": "【9a92a414-e957-47f8-ada1-7296723769a9】任务失败,在【9-1优惠劵】中第7行:出错:未找到元素", + // "remark": "【60a92f00-f7cb-4321-aa0b-6f18814fb462】任务失败,在【3.切换国家】中第8行:出错:未找到元素", + // "remark": "【81f6c1ac-6493-40cf-83fd-867b1a39e3ca】任务失败,在【9-3添加银行卡】中第5行:出错:未找到元素, 元素名: SAVE CARD", + // "remark": "【e201a1b3-f0a1-42b9-8315-d6736eead5a4】任务失败,在【11.清空浏览器数据】中第1行:出错:操作无法执行!请重启当前浏览器 或 重装当前浏览器插件后再次尝试。", + + String remark1 = "【0757f764-07b4-4d4d-a48d-e1e13b598a1f】任务失败,在【5-1清空银行卡】中第17行:出错:未找到元素, 元素名: 按钮_OK"; + String remark2 = "【9a92a414-e957-47f8-ada1-7296723769a9】任务失败,在【9-1优惠劵】中第7行:出错:未找到元素"; + String remark3 = "【60a92f00-f7cb-4321-aa0b-6f18814fb462】任务失败,在【3.切换国家】中第8行:出错:未找到元素"; + String remark4 = "【81f6c1ac-6493-40cf-83fd-867b1a39e3ca】任务失败,在【9-3添加银行卡】中第5行:出错:未找到元素, 元素名: SAVE CARD"; + String remark5 = "【e201a1b3-f0a1-42b9-8315-d6736eead5a4】任务失败,在【11.清空浏览器数据】中第1行:出错:操作无法执行!请重启当前浏览器 或 重装当前浏览器插件后再次尝试。"; + + List remarkList = new ArrayList<>(); + remarkList.add(remark1); + remarkList.add(remark2); + remarkList.add(remark3); + remarkList.add(remark4); + remarkList.add(remark5); + + for (String remark:remarkList) { + Integer status = analysisReturnJson(remark); + System.out.println("status:" + status); + } + } + + @Test + public void test22() { + String t = "3.切换国家".substring(0, "3.切换国家".indexOf(".")); + Integer modularInteger = Integer.valueOf(t); + System.out.println(modularInteger); + } + + + + @Test + public void jsonTest() { + int[] my = new int[5]; + my[0] = 0; + my[1] = 1; + my[2] = 2; + my[3] = 3; + my[4] = 4; + // 数组转为 JSONArray + JSONArray jsonArray = (JSONArray) JSONArray.toJSON(my); + System.out.println(jsonArray instanceof JSONArray); + System.out.println(jsonArray.getClass().isArray()); + System.out.println(jsonArray.toString()); + try { + JSONArray jsonObj = (JSONArray) JSONArray.toJSON(my);// 数组转为JsonArray + System.out.println(jsonObj instanceof JSONArray);// 是否是Json数组? + System.out.println(jsonObj.getClass().isArray());// 是否为数组? + String jsonStr = jsonObj.toString();// JsonArray转为String + System.out.println(jsonStr instanceof String);// 是否为String? + System.out.println(jsonStr); + } catch (Exception e) { + System.out.println("数组转json失败"); + } + } + + @Test + public void test222() { + List resultObjList = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + ResultObj resultObj = new ResultObj(); + resultObj.setName("name-" + i); + resultObj.setType("str"); + resultObj.setValue("value-" + i); + resultObjList.add(resultObj); + } + + String paramsListStr = ((JSONArray) JSONArray.toJSON(resultObjList)).toString(); + System.out.println("paramsListStr:" + paramsListStr); + + System.out.println("==========================="); + Params paramsObj = new Params(); + paramsObj.setAccountName("accountName"); + paramsObj.setApplyId(1L); + paramsObj.setParams(resultObjList.toString()); + System.out.println("JSONUtil.toJsonStr(paramsObj):" + JSONUtil.toJsonStr(paramsObj)); + } + + @Test + public void ruleGetCtBuyer() { + String buyerAccount = "jhudsonyy@gmail.com"; + String country = "Korea"; + String shopName = "JXP Official Store"; + + // 获取所有成功的刷单信息买家 然后统计每个成功的个数并返回 同时剔除传过来的参数信息 + // TODO 先随机取一个好了。 后面有了规则 我们再按照规则处理 这里需要 保证获取的买家信息是没有被占用的 通过redis 再执行的时候 添加redis 信息 + List ctBuyerClickSuccessList = ctClickFarmingService.ruleGetCtBuyer(buyerAccount, country, shopName); + Random random = new Random(); + CtBuyerClickSuccess ctBuyerClickSuccess = ctBuyerClickSuccessList.get(random.nextInt(ctBuyerClickSuccessList.size())); + CtBuyerDetailVO ctBuyerDetailVO = ctBuyerService.getDetailById(ctBuyerClickSuccess.getBuyerId()); + } + + @Resource + private SettingSiteService settingSiteService; + + @Test + public void testSettingSite() { + String googleAuth = settingSiteService.getValue("googleAuth1"); + System.out.println(googleAuth); + } + + + @Resource + private RedisUtils redisUtils; + + @Test + public void getRuleCtBuyer() { + String buyerAccount = "jhudsonyy@gmail.com"; + String country = "Korea"; + String shopName = "JXP Official Store"; + Long clickFarmingId = 56L; + + // 获取所有成功的刷单信息买家 然后统计每个成功的个数并返回 同时剔除传过来的参数信息 + // TODO 这里不能无限制的取, 通过redis 根据 刷单id 设置取过的买家信息,取过的不再取了 + List ctBuyerClickSuccessList = ctClickFarmingService.ruleGetCtBuyer(buyerAccount, country, shopName); + + while (true) { + + String clickFarmingExecBuyerIdPrefix = PublicConstant.getClickFarmingExecBuyerIdPrefix(clickFarmingId); + Long setSize = redisUtils.sGetSetSize(clickFarmingExecBuyerIdPrefix); + Long buyerId = null; + if (setSize == 0) { + buyerId = ctBuyerClickSuccessList.get(new Random().nextInt(ctBuyerClickSuccessList.size())).getBuyerId(); + + } else { + for (CtBuyerClickSuccess ctBuyerClickSuccess : ctBuyerClickSuccessList) { + buyerId = ctBuyerClickSuccess.getBuyerId(); + if (redisUtils.sHasKey(clickFarmingExecBuyerIdPrefix, buyerId.toString())) { + continue; + } + break; + } + System.out.println("没有取到合适的========================================"); + } + System.out.println("==========取到的id:" + buyerId); + redisUtils.sSet(clickFarmingExecBuyerIdPrefix, buyerId.toString()); +// CtBuyerDetailVO ctBuyerDetailVO = ctBuyerService.getDetailById(buyerId); +// System.out.println("ctBuyerDetailVO:" + JSONUtil.toJsonStr(ctBuyerDetailVO)); + } + } + + + @Test + public void joinPath() { + String paths = "123,456,789,012"; + List pathList = Arrays.asList(paths.split(",")); + + String newPaths = pathList.stream().map(s -> s = "pathUrl/" + s).collect(Collectors.joining(",")); + System.out.println(JSONUtil.toJsonStr(pathList)); + System.out.println(newPaths); + } + + @Test + public void testFile() { + System.out.println(File.separator); + } +} diff --git a/wjcy-system/src/test/java/me/zhengjie/ExcelUserTest.java b/wjcy-system/src/test/java/me/zhengjie/ExcelUserTest.java new file mode 100644 index 0000000..0085394 --- /dev/null +++ b/wjcy-system/src/test/java/me/zhengjie/ExcelUserTest.java @@ -0,0 +1,21 @@ +package me.zhengjie; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * ExcelJson导入解析实体对象 + * + * @author rch + * @create 2022-06-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ExcelUserTest { + /** 姓名 */ + private String name; + /** 年龄 */ + private Integer age; +} diff --git a/wjcy-system/src/test/java/me/zhengjie/SettingSiteServiceTest.java b/wjcy-system/src/test/java/me/zhengjie/SettingSiteServiceTest.java new file mode 100644 index 0000000..64c0227 --- /dev/null +++ b/wjcy-system/src/test/java/me/zhengjie/SettingSiteServiceTest.java @@ -0,0 +1,48 @@ +package me.zhengjie; + +import cn.hutool.json.JSONUtil; +import me.zhengjie.entity.CtBuyer; +import me.zhengjie.entity.CtSettingSite; +import me.zhengjie.entity.quartz.JobQueryByUuidReturn; +import me.zhengjie.modules.capital.controller.SettingSiteController; +import me.zhengjie.modules.quartz.service.QuartzJobService; +import me.zhengjie.service.CtBuyerService; +import me.zhengjie.service.SettingSiteService; +import me.zhengjie.service.YdQuartzService; +import org.apache.rocketmq.client.producer.TransactionMQProducer; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; + +/* + * + * @Description 运营设置 + * @Date 2021/11/30 + * @Author zeng + */ +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class SettingSiteServiceTest { + + @Resource + private CtBuyerService ctBuyerService; + @Test + public void batchAddCtBuyer() { + List ctBuyerServiceList = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + CtBuyer ctBuyer = new CtBuyer(); + ctBuyer.setAccount("account-" + i); + ctBuyer.setNickName("nickName-" + i); + ctBuyer.setPwd("pwd-" + i); + + ctBuyerServiceList.add(ctBuyer); + } + + ctBuyerService.saveBatch(ctBuyerServiceList); + } +} diff --git a/wjcy-system/src/test/java/me/zhengjie/TransactionSignDemo.java b/wjcy-system/src/test/java/me/zhengjie/TransactionSignDemo.java new file mode 100644 index 0000000..79fe252 --- /dev/null +++ b/wjcy-system/src/test/java/me/zhengjie/TransactionSignDemo.java @@ -0,0 +1,8 @@ +package me.zhengjie;/** +

+ +

+@author: rch +@date: 2021-10-27 +*/public class TransactionSignDemo { +} diff --git a/wjcy-tools/pom.xml b/wjcy-tools/pom.xml new file mode 100644 index 0000000..b2498c9 --- /dev/null +++ b/wjcy-tools/pom.xml @@ -0,0 +1,57 @@ + + + + me.zhengjie + wjcy + 1.0 + + 4.0.0 + + wjcy-tools + 工具模块 + + + 1.4.7 + [7.2.0, 7.2.99] + 4.9.153.ALL + + + + + + me.zhengjie + wjcy-logging + 1.0 + + + + + javax.mail + mail + ${mail.version} + + + + + com.qiniu + qiniu-java-sdk + ${qiniu.version} + + + + + com.alipay.sdk + alipay-sdk-java + ${alipay.version} + + + + + com.xuxueli + xxl-job-core + 2.2.0 + + + \ No newline at end of file diff --git a/wjcy-tools/src/main/java/me/zhengjie/config/MultipartConfig.java b/wjcy-tools/src/main/java/me/zhengjie/config/MultipartConfig.java new file mode 100644 index 0000000..2700e22 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/config/MultipartConfig.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.config; + +import org.springframework.boot.web.servlet.MultipartConfigFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import javax.servlet.MultipartConfigElement; +import java.io.File; + +/** + * @date 2018-12-28 + * @author https://blog.csdn.net/llibin1024530411/article/details/79474953 + */ +@Configuration +public class MultipartConfig { + + /** + * 文件上传临时路径 + */ + @Bean + MultipartConfigElement multipartConfigElement() { + MultipartConfigFactory factory = new MultipartConfigFactory(); + String location = System.getProperty("user.home") + "/.dy/file/tmp"; + File tmpFile = new File(location); + if (!tmpFile.exists()) { + if (!tmpFile.mkdirs()) { + System.out.println("create was not successful."); + } + } + factory.setLocation(location); + return factory.createMultipartConfig(); + } +} \ No newline at end of file diff --git a/wjcy-tools/src/main/java/me/zhengjie/domain/AlipayConfig.java b/wjcy-tools/src/main/java/me/zhengjie/domain/AlipayConfig.java new file mode 100644 index 0000000..def695d --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/domain/AlipayConfig.java @@ -0,0 +1,76 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * 支付宝配置类 + * @author Zheng Jie + * @date 2018-12-31 + */ +@Data +@Entity +@Table(name = "tool_alipay_config") +public class AlipayConfig implements Serializable { + + @Id + @Column(name = "config_id") + @ApiModelProperty(value = "ID", hidden = true) + private Long id; + + @NotBlank + @ApiModelProperty(value = "应用ID") + private String appId; + + @NotBlank + @ApiModelProperty(value = "商户私钥") + private String privateKey; + + @NotBlank + @ApiModelProperty(value = "支付宝公钥") + private String publicKey; + + @ApiModelProperty(value = "签名方式") + private String signType="RSA2"; + + @Column(name = "gateway_url") + @ApiModelProperty(value = "支付宝开放安全地址", hidden = true) + private String gatewayUrl = "https://openapi.alipaydev.com/gateway.do"; + + @ApiModelProperty(value = "编码", hidden = true) + private String charset= "utf-8"; + + @NotBlank + @ApiModelProperty(value = "异步通知地址") + private String notifyUrl; + + @NotBlank + @ApiModelProperty(value = "订单完成后返回的页面") + private String returnUrl; + + @ApiModelProperty(value = "类型") + private String format="JSON"; + + @NotBlank + @ApiModelProperty(value = "商户号") + private String sysServiceProviderId; + +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/domain/EmailConfig.java b/wjcy-tools/src/main/java/me/zhengjie/domain/EmailConfig.java new file mode 100644 index 0000000..b4fc1e6 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/domain/EmailConfig.java @@ -0,0 +1,58 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * 邮件配置类,数据存覆盖式存入数据存 + * @author Zheng Jie + * @date 2018-12-26 + */ +@Entity +@Data +@Table(name = "tool_email_config") +public class EmailConfig implements Serializable { + + @Id + @Column(name = "config_id") + @ApiModelProperty(value = "ID", hidden = true) + private Long id; + + @NotBlank + @ApiModelProperty(value = "邮件服务器SMTP地址") + private String host; + + @NotBlank + @ApiModelProperty(value = "邮件服务器 SMTP 端口") + private String port; + + @NotBlank + @ApiModelProperty(value = "发件者用户名") + private String user; + + @NotBlank + @ApiModelProperty(value = "密码") + private String pass; + + @NotBlank + @ApiModelProperty(value = "收件人") + private String fromUser; +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/domain/LocalStorage.java b/wjcy-tools/src/main/java/me/zhengjie/domain/LocalStorage.java new file mode 100644 index 0000000..59fd0ab --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/domain/LocalStorage.java @@ -0,0 +1,73 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.*; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import me.zhengjie.base.BaseEntity; +import javax.persistence.*; +import java.io.Serializable; + +/** +* @author Zheng Jie +* @date 2019-09-05 +*/ +@Getter +@Setter +@Entity +@Table(name="tool_local_storage") +@NoArgsConstructor +public class LocalStorage extends BaseEntity implements Serializable { + + @Id + @Column(name = "storage_id") + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ApiModelProperty(value = "真实文件名") + private String realName; + + @ApiModelProperty(value = "文件名") + private String name; + + @ApiModelProperty(value = "后缀") + private String suffix; + + @ApiModelProperty(value = "路径") + private String path; + + @ApiModelProperty(value = "类型") + private String type; + + @ApiModelProperty(value = "大小") + private String size; + + public LocalStorage(String realName,String name, String suffix, String path, String type, String size) { + this.realName = realName; + this.name = name; + this.suffix = suffix; + this.path = path; + this.type = type; + this.size = size; + } + + public void copy(LocalStorage source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} \ No newline at end of file diff --git a/wjcy-tools/src/main/java/me/zhengjie/domain/QiniuConfig.java b/wjcy-tools/src/main/java/me/zhengjie/domain/QiniuConfig.java new file mode 100644 index 0000000..0247e67 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/domain/QiniuConfig.java @@ -0,0 +1,69 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * 七牛云对象存储配置类 + * @author Zheng Jie + * @date 2018-12-31 + */ +@Data +@Entity +@Table(name = "tool_qiniu_config") +public class QiniuConfig implements Serializable { + + @Id + @Column(name = "config_id") + @ApiModelProperty(value = "ID") + private Long id; + + @NotBlank + @ApiModelProperty(value = "accessKey") + private String accessKey; + + @NotBlank + @ApiModelProperty(value = "secretKey") + private String secretKey; + + @NotBlank + @ApiModelProperty(value = "存储空间名称作为唯一的 Bucket 识别符") + private String bucket; + + /** + * Zone表示与机房的对应关系 + * 华东 Zone.zone0() + * 华北 Zone.zone1() + * 华南 Zone.zone2() + * 北美 Zone.zoneNa0() + * 东南亚 Zone.zoneAs0() + */ + @NotBlank + @ApiModelProperty(value = "Zone表示与机房的对应关系") + private String zone; + + @NotBlank + @ApiModelProperty(value = "外链域名,可自定义,需在七牛云绑定") + private String host; + + @ApiModelProperty(value = "空间类型:公开/私有") + private String type = "公开"; +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/domain/QiniuContent.java b/wjcy-tools/src/main/java/me/zhengjie/domain/QiniuContent.java new file mode 100644 index 0000000..db69a6a --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/domain/QiniuContent.java @@ -0,0 +1,64 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.annotations.UpdateTimestamp; +import javax.persistence.*; +import java.io.Serializable; +import java.sql.Timestamp; + +/** + * 上传成功后,存储结果 + * @author Zheng Jie + * @date 2018-12-31 + */ +@Data +@Entity +@Table(name = "tool_qiniu_content") +public class QiniuContent implements Serializable { + + @Id + @Column(name = "content_id") + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "name") + @ApiModelProperty(value = "文件名") + private String key; + + @ApiModelProperty(value = "空间名") + private String bucket; + + @ApiModelProperty(value = "大小") + private String size; + + @ApiModelProperty(value = "文件地址") + private String url; + + @ApiModelProperty(value = "文件类型") + private String suffix; + + @ApiModelProperty(value = "空间类型:公开/私有") + private String type = "公开"; + + @UpdateTimestamp + @ApiModelProperty(value = "创建或更新时间") + @Column(name = "update_time") + private Timestamp updateTime; +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/domain/vo/EmailVo.java b/wjcy-tools/src/main/java/me/zhengjie/domain/vo/EmailVo.java new file mode 100644 index 0000000..1fb759f --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/domain/vo/EmailVo.java @@ -0,0 +1,44 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.domain.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.util.List; + +/** + * 发送邮件时,接收参数的类 + * @author 郑杰 + * @date 2018/09/28 12:02:14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class EmailVo { + + /** 收件人,支持多个收件人 */ + @NotEmpty + private List tos; + + @NotBlank + private String subject; + + @NotBlank + private String content; +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/domain/vo/TradeVo.java b/wjcy-tools/src/main/java/me/zhengjie/domain/vo/TradeVo.java new file mode 100644 index 0000000..01c1c2f --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/domain/vo/TradeVo.java @@ -0,0 +1,63 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import javax.validation.constraints.NotBlank; +import java.sql.Date; +import java.sql.Timestamp; + +/** + * 交易详情,按需应该存入数据库,这里存入数据库,仅供临时测试 + * @author Zheng Jie + * @date 2018-12-31 + */ +@Data +public class TradeVo { + + /** (必填)商品描述 */ + @NotBlank + private String body; + + /** (必填)商品名称 */ + @NotBlank + private String subject; + + /** (必填)商户订单号,应该由后台生成 */ + @ApiModelProperty(hidden = true) + private String outTradeNo; + + /** (必填)第三方订单号 */ + @ApiModelProperty(hidden = true) + private String tradeNo; + + /** (必填)价格 */ + @NotBlank + private String totalAmount; + + /** 订单状态,已支付,未支付,作废 */ + @ApiModelProperty(hidden = true) + private String state; + + /** 创建时间,存入数据库时需要 */ + @ApiModelProperty(hidden = true) + private Timestamp createTime; + + /** 作废时间,存入数据库时需要 */ + @ApiModelProperty(hidden = true) + private Date cancelTime; +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/repository/AliPayRepository.java b/wjcy-tools/src/main/java/me/zhengjie/repository/AliPayRepository.java new file mode 100644 index 0000000..61183b4 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/repository/AliPayRepository.java @@ -0,0 +1,26 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.repository; + +import me.zhengjie.domain.AlipayConfig; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * @author Zheng Jie + * @date 2018-12-31 + */ +public interface AliPayRepository extends JpaRepository { +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/repository/EmailRepository.java b/wjcy-tools/src/main/java/me/zhengjie/repository/EmailRepository.java new file mode 100644 index 0000000..7765602 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/repository/EmailRepository.java @@ -0,0 +1,26 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.repository; + +import me.zhengjie.domain.EmailConfig; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * @author Zheng Jie + * @date 2018-12-26 + */ +public interface EmailRepository extends JpaRepository { +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/repository/LocalStorageRepository.java b/wjcy-tools/src/main/java/me/zhengjie/repository/LocalStorageRepository.java new file mode 100644 index 0000000..8c1e85a --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/repository/LocalStorageRepository.java @@ -0,0 +1,27 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.repository; + +import me.zhengjie.domain.LocalStorage; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** +* @author Zheng Jie +* @date 2019-09-05 +*/ +public interface LocalStorageRepository extends JpaRepository, JpaSpecificationExecutor { +} \ No newline at end of file diff --git a/wjcy-tools/src/main/java/me/zhengjie/repository/QiNiuConfigRepository.java b/wjcy-tools/src/main/java/me/zhengjie/repository/QiNiuConfigRepository.java new file mode 100644 index 0000000..9379f55 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/repository/QiNiuConfigRepository.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.repository; + +import me.zhengjie.domain.QiniuConfig; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; + +/** + * @author Zheng Jie + * @date 2018-12-31 + */ +public interface QiNiuConfigRepository extends JpaRepository { + + /** + * 编辑类型 + * @param type + */ + @Modifying + @Query(value = "update QiniuConfig set type = ?1") + void update(String type); +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/repository/QiniuContentRepository.java b/wjcy-tools/src/main/java/me/zhengjie/repository/QiniuContentRepository.java new file mode 100644 index 0000000..55f813f --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/repository/QiniuContentRepository.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.repository; + +import me.zhengjie.domain.QiniuContent; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** + * @author Zheng Jie + * @date 2018-12-31 + */ +public interface QiniuContentRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据key查询 + * @param key 文件名 + * @return QiniuContent + */ + QiniuContent findByKey(String key); +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/rest/AliPayController.java b/wjcy-tools/src/main/java/me/zhengjie/rest/AliPayController.java new file mode 100644 index 0000000..128bb40 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/rest/AliPayController.java @@ -0,0 +1,135 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.annotation.Log; +import me.zhengjie.annotation.rest.AnonymousGetMapping; +import me.zhengjie.domain.vo.TradeVo; +import me.zhengjie.domain.AlipayConfig; +import me.zhengjie.utils.AliPayStatusEnum; +import me.zhengjie.utils.AlipayUtils; +import me.zhengjie.service.AliPayService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +/** + * @author Zheng Jie + * @date 2018-12-31 + */ +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/aliPay") +@Api(tags = "工具:支付宝管理") +public class AliPayController { + + private final AlipayUtils alipayUtils; + private final AliPayService alipayService; + + @GetMapping + public ResponseEntity queryConfig() { + return new ResponseEntity<>(alipayService.find(), HttpStatus.OK); + } + + @Log("配置支付宝") + @ApiOperation("配置支付宝") + @PutMapping + public ResponseEntity updateConfig(@Validated @RequestBody AlipayConfig alipayConfig) { + alipayService.config(alipayConfig); + return new ResponseEntity<>(HttpStatus.OK); + } + + @Log("支付宝PC网页支付") + @ApiOperation("PC网页支付") + @PostMapping(value = "/toPayAsPC") + public ResponseEntity toPayAsPc(@Validated @RequestBody TradeVo trade) throws Exception { + AlipayConfig aliPay = alipayService.find(); + trade.setOutTradeNo(alipayUtils.getOrderCode()); + String payUrl = alipayService.toPayAsPc(aliPay, trade); + return ResponseEntity.ok(payUrl); + } + + @Log("支付宝手机网页支付") + @ApiOperation("手机网页支付") + @PostMapping(value = "/toPayAsWeb") + public ResponseEntity toPayAsWeb(@Validated @RequestBody TradeVo trade) throws Exception { + AlipayConfig alipay = alipayService.find(); + trade.setOutTradeNo(alipayUtils.getOrderCode()); + String payUrl = alipayService.toPayAsWeb(alipay, trade); + return ResponseEntity.ok(payUrl); + } + + @ApiIgnore + @AnonymousGetMapping("/return") + @ApiOperation("支付之后跳转的链接") + public ResponseEntity returnPage(HttpServletRequest request, HttpServletResponse response) { + AlipayConfig alipay = alipayService.find(); + response.setContentType("text/html;charset=" + alipay.getCharset()); + //内容验签,防止黑客篡改参数 + if (alipayUtils.rsaCheck(request, alipay)) { + //商户订单号 + String outTradeNo = new String(request.getParameter("out_trade_no").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); + //支付宝交易号 + String tradeNo = new String(request.getParameter("trade_no").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); + System.out.println("商户订单号" + outTradeNo + " " + "第三方交易号" + tradeNo); + + // 根据业务需要返回数据,这里统一返回OK + return new ResponseEntity<>("payment successful", HttpStatus.OK); + } else { + // 根据业务需要返回数据 + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } + } + + @ApiIgnore + @RequestMapping("/notify") + @AnonymousAccess + @ApiOperation("支付异步通知(要公网访问),接收异步通知,检查通知内容app_id、out_trade_no、total_amount是否与请求中的一致,根据trade_status进行后续业务处理") + public ResponseEntity notify(HttpServletRequest request) { + AlipayConfig alipay = alipayService.find(); + Map parameterMap = request.getParameterMap(); + //内容验签,防止黑客篡改参数 + if (alipayUtils.rsaCheck(request, alipay)) { + //交易状态 + String tradeStatus = new String(request.getParameter("trade_status").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); + // 商户订单号 + String outTradeNo = new String(request.getParameter("out_trade_no").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); + //支付宝交易号 + String tradeNo = new String(request.getParameter("trade_no").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); + //付款金额 + String totalAmount = new String(request.getParameter("total_amount").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); + //验证 + if (tradeStatus.equals(AliPayStatusEnum.SUCCESS.getValue()) || tradeStatus.equals(AliPayStatusEnum.FINISHED.getValue())) { + // 验证通过后应该根据业务需要处理订单 + } + return new ResponseEntity<>(HttpStatus.OK); + } + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/rest/EmailController.java b/wjcy-tools/src/main/java/me/zhengjie/rest/EmailController.java new file mode 100644 index 0000000..974de99 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/rest/EmailController.java @@ -0,0 +1,63 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.domain.vo.EmailVo; +import me.zhengjie.domain.EmailConfig; +import me.zhengjie.service.EmailService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +/** + * 发送邮件 + * @author 郑杰 + * @date 2018/09/28 6:55:53 + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("api/email") +@Api(tags = "工具:邮件管理") +public class EmailController { + + private final EmailService emailService; + + @GetMapping + public ResponseEntity queryConfig(){ + return new ResponseEntity<>(emailService.find(),HttpStatus.OK); + } + + @Log("配置邮件") + @PutMapping + @ApiOperation("配置邮件") + public ResponseEntity updateConfig(@Validated @RequestBody EmailConfig emailConfig) throws Exception { + emailService.config(emailConfig,emailService.find()); + return new ResponseEntity<>(HttpStatus.OK); + } + + @Log("发送邮件") + @PostMapping + @ApiOperation("发送邮件") + public ResponseEntity sendEmail(@Validated @RequestBody EmailVo emailVo){ + emailService.send(emailVo,emailService.find()); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/rest/LocalStorageController.java b/wjcy-tools/src/main/java/me/zhengjie/rest/LocalStorageController.java new file mode 100644 index 0000000..6d7083d --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/rest/LocalStorageController.java @@ -0,0 +1,98 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.rest; + +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.domain.LocalStorage; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.service.LocalStorageService; +import me.zhengjie.service.dto.LocalStorageQueryCriteria; +import me.zhengjie.utils.FileUtil; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import io.swagger.annotations.*; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** +* @author Zheng Jie +* @date 2019-09-05 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "工具:本地存储管理") +@RequestMapping("/api/localStorage") +public class LocalStorageController { + + private final LocalStorageService localStorageService; + + @ApiOperation("查询文件") + @GetMapping + @PreAuthorize("@el.check('storage:list')") + public ResponseEntity query(LocalStorageQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(localStorageService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @ApiOperation("导出数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('storage:list')") + public void download(HttpServletResponse response, LocalStorageQueryCriteria criteria) throws IOException { + localStorageService.download(localStorageService.queryAll(criteria), response); + } + + @ApiOperation("上传文件") + @PostMapping + @PreAuthorize("@el.check('storage:add')") + public ResponseEntity create(@RequestParam String name, @RequestParam("file") MultipartFile file){ + localStorageService.create(name, file); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @PostMapping("/pictures") + @ApiOperation("上传图片") + public ResponseEntity upload(@RequestParam MultipartFile file){ + // 判断文件是否为图片 + String suffix = FileUtil.getExtensionName(file.getOriginalFilename()); + if(!FileUtil.IMAGE.equals(FileUtil.getFileType(suffix))){ + throw new BadRequestException("只能上传图片"); + } + LocalStorage localStorage = localStorageService.create(null, file); + return new ResponseEntity<>(localStorage, HttpStatus.OK); + } + + @Log("修改文件") + @ApiOperation("修改文件") + @PutMapping + @PreAuthorize("@el.check('storage:edit')") + public ResponseEntity update(@Validated @RequestBody LocalStorage resources){ + localStorageService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除文件") + @DeleteMapping + @ApiOperation("多选删除") + public ResponseEntity delete(@RequestBody Long[] ids) { + localStorageService.deleteAll(ids); + return new ResponseEntity<>(HttpStatus.OK); + } +} \ No newline at end of file diff --git a/wjcy-tools/src/main/java/me/zhengjie/rest/QiniuController.java b/wjcy-tools/src/main/java/me/zhengjie/rest/QiniuController.java new file mode 100644 index 0000000..1bb32d7 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/rest/QiniuController.java @@ -0,0 +1,122 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.Log; +import me.zhengjie.domain.QiniuConfig; +import me.zhengjie.domain.QiniuContent; +import me.zhengjie.service.dto.QiniuQueryCriteria; +import me.zhengjie.service.QiNiuService; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * 发送邮件 + * @author 郑杰 + * @date 2018/09/28 6:55:53 + */ +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/qiNiuContent") +@Api(tags = "工具:七牛云存储管理") +public class QiniuController { + + private final QiNiuService qiNiuService; + + @GetMapping(value = "/config") + public ResponseEntity queryConfig(){ + return new ResponseEntity<>(qiNiuService.find(), HttpStatus.OK); + } + + @Log("配置七牛云存储") + @ApiOperation("配置七牛云存储") + @PutMapping(value = "/config") + public ResponseEntity updateConfig(@Validated @RequestBody QiniuConfig qiniuConfig){ + qiNiuService.config(qiniuConfig); + qiNiuService.update(qiniuConfig.getType()); + return new ResponseEntity<>(HttpStatus.OK); + } + + @ApiOperation("导出数据") + @GetMapping(value = "/download") + public void download(HttpServletResponse response, QiniuQueryCriteria criteria) throws IOException { + qiNiuService.downloadList(qiNiuService.queryAll(criteria), response); + } + + @ApiOperation("查询文件") + @GetMapping + public ResponseEntity query(QiniuQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(qiNiuService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @Log("上传文件") + @ApiOperation("上传文件") + @PostMapping + public ResponseEntity upload(@RequestParam MultipartFile file){ + QiniuContent qiniuContent = qiNiuService.upload(file,qiNiuService.find()); + Map map = new HashMap<>(3); + map.put("id",qiniuContent.getId()); + map.put("errno",0); + map.put("data",new String[]{qiniuContent.getUrl()}); + return new ResponseEntity<>(map,HttpStatus.OK); + } + + @Log("同步七牛云数据") + @ApiOperation("同步七牛云数据") + @PostMapping(value = "/synchronize") + public ResponseEntity synchronize(){ + qiNiuService.synchronize(qiNiuService.find()); + return new ResponseEntity<>(HttpStatus.OK); + } + + @Log("下载文件") + @ApiOperation("下载文件") + @GetMapping(value = "/download/{id}") + public ResponseEntity download(@PathVariable Long id){ + Map map = new HashMap<>(1); + map.put("url", qiNiuService.download(qiNiuService.findByContentId(id),qiNiuService.find())); + return new ResponseEntity<>(map,HttpStatus.OK); + } + + @Log("删除文件") + @ApiOperation("删除文件") + @DeleteMapping(value = "/{id}") + public ResponseEntity delete(@PathVariable Long id){ + qiNiuService.delete(qiNiuService.findByContentId(id),qiNiuService.find()); + return new ResponseEntity<>(HttpStatus.OK); + } + + @Log("删除多张图片") + @ApiOperation("删除多张图片") + @DeleteMapping + public ResponseEntity deleteAll(@RequestBody Long[] ids) { + qiNiuService.deleteAll(ids, qiNiuService.find()); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/service/AliPayService.java b/wjcy-tools/src/main/java/me/zhengjie/service/AliPayService.java new file mode 100644 index 0000000..be19c90 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/service/AliPayService.java @@ -0,0 +1,57 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service; + +import me.zhengjie.domain.vo.TradeVo; +import me.zhengjie.domain.AlipayConfig; + +/** + * @author Zheng Jie + * @date 2018-12-31 + */ +public interface AliPayService { + + /** + * 查询配置 + * @return AlipayConfig + */ + AlipayConfig find(); + + /** + * 更新配置 + * @param alipayConfig 支付宝配置 + * @return AlipayConfig + */ + AlipayConfig config(AlipayConfig alipayConfig); + + /** + * 处理来自PC的交易请求 + * @param alipay 支付宝配置 + * @param trade 交易详情 + * @return String + * @throws Exception 异常 + */ + String toPayAsPc(AlipayConfig alipay, TradeVo trade) throws Exception; + + /** + * 处理来自手机网页的交易请求 + * @param alipay 支付宝配置 + * @param trade 交易详情 + * @return String + * @throws Exception 异常 + */ + String toPayAsWeb(AlipayConfig alipay, TradeVo trade) throws Exception; +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/service/EmailService.java b/wjcy-tools/src/main/java/me/zhengjie/service/EmailService.java new file mode 100644 index 0000000..aabfcb0 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/service/EmailService.java @@ -0,0 +1,49 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service; + +import me.zhengjie.domain.vo.EmailVo; +import me.zhengjie.domain.EmailConfig; + +/** + * @author Zheng Jie + * @date 2018-12-26 + */ +public interface EmailService { + + /** + * 更新邮件配置 + * @param emailConfig 邮箱配置 + * @param old / + * @return / + * @throws Exception / + */ + EmailConfig config(EmailConfig emailConfig, EmailConfig old) throws Exception; + + /** + * 查询配置 + * @return EmailConfig 邮件配置 + */ + EmailConfig find(); + + /** + * 发送邮件 + * @param emailVo 邮件发送的内容 + * @param emailConfig 邮件配置 + * @throws Exception / + */ + void send(EmailVo emailVo, EmailConfig emailConfig); +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/service/LocalStorageService.java b/wjcy-tools/src/main/java/me/zhengjie/service/LocalStorageService.java new file mode 100644 index 0000000..6df0624 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/service/LocalStorageService.java @@ -0,0 +1,82 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service; + +import me.zhengjie.domain.LocalStorage; +import me.zhengjie.service.dto.LocalStorageDto; +import me.zhengjie.service.dto.LocalStorageQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** +* @author Zheng Jie +* @date 2019-09-05 +*/ +public interface LocalStorageService { + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(LocalStorageQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部数据 + * @param criteria 条件 + * @return / + */ + List queryAll(LocalStorageQueryCriteria criteria); + + /** + * 根据ID查询 + * @param id / + * @return / + */ + LocalStorageDto findById(Long id); + + /** + * 上传 + * @param name 文件名称 + * @param file 文件 + * @return + */ + LocalStorage create(String name, MultipartFile file); + + /** + * 编辑 + * @param resources 文件信息 + */ + void update(LocalStorage resources); + + /** + * 多选删除 + * @param ids / + */ + void deleteAll(Long[] ids); + + /** + * 导出数据 + * @param localStorageDtos 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List localStorageDtos, HttpServletResponse response) throws IOException; +} \ No newline at end of file diff --git a/wjcy-tools/src/main/java/me/zhengjie/service/QiNiuService.java b/wjcy-tools/src/main/java/me/zhengjie/service/QiNiuService.java new file mode 100644 index 0000000..09dca6a --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/service/QiNiuService.java @@ -0,0 +1,118 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service; + +import me.zhengjie.domain.QiniuConfig; +import me.zhengjie.domain.QiniuContent; +import me.zhengjie.service.dto.QiniuQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** + * @author Zheng Jie + * @date 2018-12-31 + */ +public interface QiNiuService { + + /** + * 查配置 + * @return QiniuConfig + */ + QiniuConfig find(); + + /** + * 修改配置 + * @param qiniuConfig 配置 + * @return QiniuConfig + */ + QiniuConfig config(QiniuConfig qiniuConfig); + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(QiniuQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部 + * @param criteria 条件 + * @return / + */ + List queryAll(QiniuQueryCriteria criteria); + + /** + * 上传文件 + * @param file 文件 + * @param qiniuConfig 配置 + * @return QiniuContent + */ + QiniuContent upload(MultipartFile file, QiniuConfig qiniuConfig); + + /** + * 查询文件 + * @param id 文件ID + * @return QiniuContent + */ + QiniuContent findByContentId(Long id); + + /** + * 下载文件 + * @param content 文件信息 + * @param config 配置 + * @return String + */ + String download(QiniuContent content, QiniuConfig config); + + /** + * 删除文件 + * @param content 文件 + * @param config 配置 + */ + void delete(QiniuContent content, QiniuConfig config); + + /** + * 同步数据 + * @param config 配置 + */ + void synchronize(QiniuConfig config); + + /** + * 删除文件 + * @param ids 文件ID数组 + * @param config 配置 + */ + void deleteAll(Long[] ids, QiniuConfig config); + + /** + * 更新数据 + * @param type 类型 + */ + void update(String type); + + /** + * 导出数据 + * @param queryAll / + * @param response / + * @throws IOException / + */ + void downloadList(List queryAll, HttpServletResponse response) throws IOException; +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/service/dto/LocalStorageDto.java b/wjcy-tools/src/main/java/me/zhengjie/service/dto/LocalStorageDto.java new file mode 100644 index 0000000..14221c2 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/service/dto/LocalStorageDto.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.dto; + +import lombok.Getter; +import lombok.Setter; +import me.zhengjie.base.BaseDTO; +import java.io.Serializable; + +/** +* @author Zheng Jie +* @date 2019-09-05 +*/ +@Getter +@Setter +public class LocalStorageDto extends BaseDTO implements Serializable { + + private Long id; + + private String realName; + + private String name; + + private String suffix; + + private String type; + + private String size; +} \ No newline at end of file diff --git a/wjcy-tools/src/main/java/me/zhengjie/service/dto/LocalStorageQueryCriteria.java b/wjcy-tools/src/main/java/me/zhengjie/service/dto/LocalStorageQueryCriteria.java new file mode 100644 index 0000000..bea1cc7 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/service/dto/LocalStorageQueryCriteria.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.dto; + +import lombok.Data; +import java.sql.Timestamp; +import java.util.List; + +import me.zhengjie.annotation.Query; + +/** +* @author Zheng Jie +* @date 2019-09-05 +*/ +@Data +public class LocalStorageQueryCriteria{ + + @Query(blurry = "name,suffix,type,createBy,size") + private String blurry; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} \ No newline at end of file diff --git a/wjcy-tools/src/main/java/me/zhengjie/service/dto/PictureQueryCriteria.java b/wjcy-tools/src/main/java/me/zhengjie/service/dto/PictureQueryCriteria.java new file mode 100644 index 0000000..e7d4f1b --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/service/dto/PictureQueryCriteria.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; +import java.sql.Timestamp; +import java.util.List; + +/** + * sm.ms图床 + * + * @author Zheng Jie + * @date 2019-6-4 09:52:09 + */ +@Data +public class PictureQueryCriteria{ + + @Query(type = Query.Type.INNER_LIKE) + private String filename; + + @Query(type = Query.Type.INNER_LIKE) + private String username; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/service/dto/QiniuQueryCriteria.java b/wjcy-tools/src/main/java/me/zhengjie/service/dto/QiniuQueryCriteria.java new file mode 100644 index 0000000..f5c2240 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/service/dto/QiniuQueryCriteria.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; + +import java.sql.Timestamp; +import java.util.List; + +/** + * @author Zheng Jie + * @date 2019-6-4 09:54:37 + */ +@Data +public class QiniuQueryCriteria{ + + @Query(type = Query.Type.INNER_LIKE) + private String key; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/service/impl/AliPayServiceImpl.java b/wjcy-tools/src/main/java/me/zhengjie/service/impl/AliPayServiceImpl.java new file mode 100644 index 0000000..0625ba4 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/service/impl/AliPayServiceImpl.java @@ -0,0 +1,119 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.impl; + +import com.alipay.api.AlipayClient; +import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.request.AlipayTradePagePayRequest; +import com.alipay.api.request.AlipayTradeWapPayRequest; +import lombok.RequiredArgsConstructor; +import me.zhengjie.domain.vo.TradeVo; +import me.zhengjie.domain.AlipayConfig; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.repository.AliPayRepository; +import me.zhengjie.service.AliPayService; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.Optional; + +/** + * @author Zheng Jie + * @date 2018-12-31 + */ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "aliPay") +public class AliPayServiceImpl implements AliPayService { + + private final AliPayRepository alipayRepository; + + @Override + @Cacheable(key = "'config'") + public AlipayConfig find() { + Optional alipayConfig = alipayRepository.findById(1L); + return alipayConfig.orElseGet(AlipayConfig::new); + } + + @Override + @CachePut(key = "'config'") + @Transactional(rollbackFor = Exception.class) + public AlipayConfig config(AlipayConfig alipayConfig) { + alipayConfig.setId(1L); + return alipayRepository.save(alipayConfig); + } + + @Override + public String toPayAsPc(AlipayConfig alipay, TradeVo trade) throws Exception { + + if(alipay.getId() == null){ + throw new BadRequestException("请先添加相应配置,再操作"); + } + AlipayClient alipayClient = new DefaultAlipayClient(alipay.getGatewayUrl(), alipay.getAppId(), alipay.getPrivateKey(), alipay.getFormat(), alipay.getCharset(), alipay.getPublicKey(), alipay.getSignType()); + + // 创建API对应的request(电脑网页版) + AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); + + // 订单完成后返回的页面和异步通知地址 + request.setReturnUrl(alipay.getReturnUrl()); + request.setNotifyUrl(alipay.getNotifyUrl()); + // 填充订单参数 + request.setBizContent("{" + + " \"out_trade_no\":\""+trade.getOutTradeNo()+"\"," + + " \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," + + " \"total_amount\":"+trade.getTotalAmount()+"," + + " \"subject\":\""+trade.getSubject()+"\"," + + " \"body\":\""+trade.getBody()+"\"," + + " \"extend_params\":{" + + " \"sys_service_provider_id\":\""+alipay.getSysServiceProviderId()+"\"" + + " }"+ + " }");//填充业务参数 + // 调用SDK生成表单, 通过GET方式,口可以获取url + return alipayClient.pageExecute(request, "GET").getBody(); + + } + + @Override + public String toPayAsWeb(AlipayConfig alipay, TradeVo trade) throws Exception { + if(alipay.getId() == null){ + throw new BadRequestException("请先添加相应配置,再操作"); + } + AlipayClient alipayClient = new DefaultAlipayClient(alipay.getGatewayUrl(), alipay.getAppId(), alipay.getPrivateKey(), alipay.getFormat(), alipay.getCharset(), alipay.getPublicKey(), alipay.getSignType()); + + double money = Double.parseDouble(trade.getTotalAmount()); + double maxMoney = 5000; + if(money <= 0 || money >= maxMoney){ + throw new BadRequestException("测试金额过大"); + } + // 创建API对应的request(手机网页版) + AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest(); + request.setReturnUrl(alipay.getReturnUrl()); + request.setNotifyUrl(alipay.getNotifyUrl()); + request.setBizContent("{" + + " \"out_trade_no\":\""+trade.getOutTradeNo()+"\"," + + " \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," + + " \"total_amount\":"+trade.getTotalAmount()+"," + + " \"subject\":\""+trade.getSubject()+"\"," + + " \"body\":\""+trade.getBody()+"\"," + + " \"extend_params\":{" + + " \"sys_service_provider_id\":\""+alipay.getSysServiceProviderId()+"\"" + + " }"+ + " }"); + return alipayClient.pageExecute(request, "GET").getBody(); + } +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/service/impl/EmailServiceImpl.java b/wjcy-tools/src/main/java/me/zhengjie/service/impl/EmailServiceImpl.java new file mode 100644 index 0000000..c98c76e --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/service/impl/EmailServiceImpl.java @@ -0,0 +1,105 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.impl; + +import cn.hutool.extra.mail.Mail; +import cn.hutool.extra.mail.MailAccount; +import lombok.RequiredArgsConstructor; +import me.zhengjie.domain.EmailConfig; +import me.zhengjie.domain.vo.EmailVo; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.repository.EmailRepository; +import me.zhengjie.service.EmailService; +import me.zhengjie.utils.EncryptUtils; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.Optional; + +/** + * @author Zheng Jie + * @date 2018-12-26 + */ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "email") +public class EmailServiceImpl implements EmailService { + + private final EmailRepository emailRepository; + + @Override + @CachePut(key = "'config'") + @Transactional(rollbackFor = Exception.class) + public EmailConfig config(EmailConfig emailConfig, EmailConfig old) throws Exception { + emailConfig.setId(1L); + if(!emailConfig.getPass().equals(old.getPass())){ + // 对称加密 + emailConfig.setPass(EncryptUtils.desEncrypt(emailConfig.getPass())); + } + return emailRepository.save(emailConfig); + } + + @Override + @Cacheable(key = "'config'") + public EmailConfig find() { + Optional emailConfig = emailRepository.findById(1L); + return emailConfig.orElseGet(EmailConfig::new); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void send(EmailVo emailVo, EmailConfig emailConfig){ + if(emailConfig.getId() == null){ + throw new BadRequestException("请先配置,再操作"); + } + // 封装 + MailAccount account = new MailAccount(); + // 设置用户 + String user = emailConfig.getFromUser().split("@")[0]; + account.setUser(user); + account.setHost(emailConfig.getHost()); + account.setPort(Integer.parseInt(emailConfig.getPort())); + account.setAuth(true); + try { + // 对称解密 + account.setPass(EncryptUtils.desDecrypt(emailConfig.getPass())); + } catch (Exception e) { + throw new BadRequestException(e.getMessage()); + } + account.setFrom(emailConfig.getUser()+"<"+emailConfig.getFromUser()+">"); + // ssl方式发送 + account.setSslEnable(true); + // 使用STARTTLS安全连接 + account.setStarttlsEnable(true); + String content = emailVo.getContent(); + // 发送 + try { + int size = emailVo.getTos().size(); + Mail.create(account) + .setTos(emailVo.getTos().toArray(new String[size])) + .setTitle(emailVo.getSubject()) + .setContent(content) + .setHtml(true) + //关闭session + .setUseGlobalSession(false) + .send(); + }catch (Exception e){ + throw new BadRequestException(e.getMessage()); + } + } +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/service/impl/LocalStorageServiceImpl.java b/wjcy-tools/src/main/java/me/zhengjie/service/impl/LocalStorageServiceImpl.java new file mode 100644 index 0000000..77174c4 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/service/impl/LocalStorageServiceImpl.java @@ -0,0 +1,133 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import lombok.RequiredArgsConstructor; +import me.zhengjie.config.FileProperties; +import me.zhengjie.domain.LocalStorage; +import me.zhengjie.service.dto.LocalStorageDto; +import me.zhengjie.service.dto.LocalStorageQueryCriteria; +import me.zhengjie.service.mapstruct.LocalStorageMapper; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.utils.*; +import me.zhengjie.repository.LocalStorageRepository; +import me.zhengjie.service.LocalStorageService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; + +/** +* @author Zheng Jie +* @date 2019-09-05 +*/ +@Service +@RequiredArgsConstructor +public class LocalStorageServiceImpl implements LocalStorageService { + + private final LocalStorageRepository localStorageRepository; + private final LocalStorageMapper localStorageMapper; + private final FileProperties properties; + + @Override + public Object queryAll(LocalStorageQueryCriteria criteria, Pageable pageable){ + Page page = localStorageRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(localStorageMapper::toDto)); + } + + @Override + public List queryAll(LocalStorageQueryCriteria criteria){ + return localStorageMapper.toDto(localStorageRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); + } + + @Override + public LocalStorageDto findById(Long id){ + LocalStorage localStorage = localStorageRepository.findById(id).orElseGet(LocalStorage::new); + ValidationUtil.isNull(localStorage.getId(),"LocalStorage","id",id); + return localStorageMapper.toDto(localStorage); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public LocalStorage create(String name, MultipartFile multipartFile) { + FileUtil.checkSize(properties.getMaxSize(), multipartFile.getSize()); + String suffix = FileUtil.getExtensionName(multipartFile.getOriginalFilename()); + String type = FileUtil.getFileType(suffix); + File file = FileUtil.upload(multipartFile, properties.getPath().getPath() + type + File.separator); + if(ObjectUtil.isNull(file)){ + throw new BadRequestException("上传失败"); + } + try { + name = StringUtils.isBlank(name) ? FileUtil.getFileNameNoEx(multipartFile.getOriginalFilename()) : name; + LocalStorage localStorage = new LocalStorage( + file.getName(), + name, + suffix, + file.getPath(), + type, + FileUtil.getSize(multipartFile.getSize()) + ); + return localStorageRepository.save(localStorage); + }catch (Exception e){ + FileUtil.del(file); + throw e; + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(LocalStorage resources) { + LocalStorage localStorage = localStorageRepository.findById(resources.getId()).orElseGet(LocalStorage::new); + ValidationUtil.isNull( localStorage.getId(),"LocalStorage","id",resources.getId()); + localStorage.copy(resources); + localStorageRepository.save(localStorage); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteAll(Long[] ids) { + for (Long id : ids) { + LocalStorage storage = localStorageRepository.findById(id).orElseGet(LocalStorage::new); + FileUtil.del(storage.getPath()); + localStorageRepository.delete(storage); + } + } + + @Override + public void download(List queryAll, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (LocalStorageDto localStorageDTO : queryAll) { + Map map = new LinkedHashMap<>(); + map.put("文件名", localStorageDTO.getRealName()); + map.put("备注名", localStorageDTO.getName()); + map.put("文件类型", localStorageDTO.getType()); + map.put("文件大小", localStorageDTO.getSize()); + map.put("创建者", localStorageDTO.getCreateBy()); + map.put("创建日期", localStorageDTO.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/service/impl/QiNiuServiceImpl.java b/wjcy-tools/src/main/java/me/zhengjie/service/impl/QiNiuServiceImpl.java new file mode 100644 index 0000000..942f437 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/service/impl/QiNiuServiceImpl.java @@ -0,0 +1,237 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.impl; + +import com.alibaba.fastjson.JSON; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Response; +import com.qiniu.storage.BucketManager; +import com.qiniu.storage.Configuration; +import com.qiniu.storage.UploadManager; +import com.qiniu.storage.model.DefaultPutRet; +import com.qiniu.storage.model.FileInfo; +import com.qiniu.util.Auth; +import lombok.RequiredArgsConstructor; +import me.zhengjie.domain.QiniuConfig; +import me.zhengjie.domain.QiniuContent; +import me.zhengjie.repository.QiniuContentRepository; +import me.zhengjie.service.dto.QiniuQueryCriteria; +import me.zhengjie.utils.QiNiuUtil; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.repository.QiNiuConfigRepository; +import me.zhengjie.service.QiNiuService; +import me.zhengjie.utils.FileUtil; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.QueryHelp; +import me.zhengjie.utils.ValidationUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** + * @author Zheng Jie + * @date 2018-12-31 + */ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "qiNiu") +public class QiNiuServiceImpl implements QiNiuService { + + private final QiNiuConfigRepository qiNiuConfigRepository; + private final QiniuContentRepository qiniuContentRepository; + + @Value("${qiniu.max-size}") + private Long maxSize; + + @Override + @Cacheable(key = "'config'") + public QiniuConfig find() { + Optional qiniuConfig = qiNiuConfigRepository.findById(1L); + return qiniuConfig.orElseGet(QiniuConfig::new); + } + + @Override + @CachePut(key = "'config'") + @Transactional(rollbackFor = Exception.class) + public QiniuConfig config(QiniuConfig qiniuConfig) { + qiniuConfig.setId(1L); + String http = "http://", https = "https://"; + if (!(qiniuConfig.getHost().toLowerCase().startsWith(http)||qiniuConfig.getHost().toLowerCase().startsWith(https))) { + throw new BadRequestException("外链域名必须以http://或者https://开头"); + } + return qiNiuConfigRepository.save(qiniuConfig); + } + + @Override + public Object queryAll(QiniuQueryCriteria criteria, Pageable pageable){ + return PageUtil.toPage(qiniuContentRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable)); + } + + @Override + public List queryAll(QiniuQueryCriteria criteria) { + return qiniuContentRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public QiniuContent upload(MultipartFile file, QiniuConfig qiniuConfig) { + FileUtil.checkSize(maxSize, file.getSize()); + if(qiniuConfig.getId() == null){ + throw new BadRequestException("请先添加相应配置,再操作"); + } + // 构造一个带指定Zone对象的配置类 + Configuration cfg = new Configuration(QiNiuUtil.getRegion(qiniuConfig.getZone())); + UploadManager uploadManager = new UploadManager(cfg); + Auth auth = Auth.create(qiniuConfig.getAccessKey(), qiniuConfig.getSecretKey()); + String upToken = auth.uploadToken(qiniuConfig.getBucket()); + try { + String key = file.getOriginalFilename(); + if(qiniuContentRepository.findByKey(key) != null) { + key = QiNiuUtil.getKey(key); + } + Response response = uploadManager.put(file.getBytes(), key, upToken); + //解析上传成功的结果 + + DefaultPutRet putRet = JSON.parseObject(response.bodyString(), DefaultPutRet.class); + QiniuContent content = qiniuContentRepository.findByKey(FileUtil.getFileNameNoEx(putRet.key)); + if(content == null){ + //存入数据库 + QiniuContent qiniuContent = new QiniuContent(); + qiniuContent.setSuffix(FileUtil.getExtensionName(putRet.key)); + qiniuContent.setBucket(qiniuConfig.getBucket()); + qiniuContent.setType(qiniuConfig.getType()); + qiniuContent.setKey(FileUtil.getFileNameNoEx(putRet.key)); + qiniuContent.setUrl(qiniuConfig.getHost()+"/"+putRet.key); + qiniuContent.setSize(FileUtil.getSize(Integer.parseInt(file.getSize()+""))); + return qiniuContentRepository.save(qiniuContent); + } + return content; + } catch (Exception e) { + throw new BadRequestException(e.getMessage()); + } + } + + @Override + public QiniuContent findByContentId(Long id) { + QiniuContent qiniuContent = qiniuContentRepository.findById(id).orElseGet(QiniuContent::new); + ValidationUtil.isNull(qiniuContent.getId(),"QiniuContent", "id",id); + return qiniuContent; + } + + @Override + public String download(QiniuContent content,QiniuConfig config){ + String finalUrl; + String type = "公开"; + if(type.equals(content.getType())){ + finalUrl = content.getUrl(); + } else { + Auth auth = Auth.create(config.getAccessKey(), config.getSecretKey()); + // 1小时,可以自定义链接过期时间 + long expireInSeconds = 3600; + finalUrl = auth.privateDownloadUrl(content.getUrl(), expireInSeconds); + } + return finalUrl; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(QiniuContent content, QiniuConfig config) { + //构造一个带指定Zone对象的配置类 + Configuration cfg = new Configuration(QiNiuUtil.getRegion(config.getZone())); + Auth auth = Auth.create(config.getAccessKey(), config.getSecretKey()); + BucketManager bucketManager = new BucketManager(auth, cfg); + try { + bucketManager.delete(content.getBucket(), content.getKey() + "." + content.getSuffix()); + qiniuContentRepository.delete(content); + } catch (QiniuException ex) { + qiniuContentRepository.delete(content); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void synchronize(QiniuConfig config) { + if(config.getId() == null){ + throw new BadRequestException("请先添加相应配置,再操作"); + } + //构造一个带指定Zone对象的配置类 + Configuration cfg = new Configuration(QiNiuUtil.getRegion(config.getZone())); + Auth auth = Auth.create(config.getAccessKey(), config.getSecretKey()); + BucketManager bucketManager = new BucketManager(auth, cfg); + //文件名前缀 + String prefix = ""; + //每次迭代的长度限制,最大1000,推荐值 1000 + int limit = 1000; + //指定目录分隔符,列出所有公共前缀(模拟列出目录效果)。缺省值为空字符串 + String delimiter = ""; + //列举空间文件列表 + BucketManager.FileListIterator fileListIterator = bucketManager.createFileListIterator(config.getBucket(), prefix, limit, delimiter); + while (fileListIterator.hasNext()) { + //处理获取的file list结果 + QiniuContent qiniuContent; + FileInfo[] items = fileListIterator.next(); + for (FileInfo item : items) { + if(qiniuContentRepository.findByKey(FileUtil.getFileNameNoEx(item.key)) == null){ + qiniuContent = new QiniuContent(); + qiniuContent.setSize(FileUtil.getSize(Integer.parseInt(item.fsize+""))); + qiniuContent.setSuffix(FileUtil.getExtensionName(item.key)); + qiniuContent.setKey(FileUtil.getFileNameNoEx(item.key)); + qiniuContent.setType(config.getType()); + qiniuContent.setBucket(config.getBucket()); + qiniuContent.setUrl(config.getHost()+"/"+item.key); + qiniuContentRepository.save(qiniuContent); + } + } + } + } + + @Override + public void deleteAll(Long[] ids, QiniuConfig config) { + for (Long id : ids) { + delete(findByContentId(id), config); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(String type) { + qiNiuConfigRepository.update(type); + } + + @Override + public void downloadList(List queryAll, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (QiniuContent content : queryAll) { + Map map = new LinkedHashMap<>(); + map.put("文件名", content.getKey()); + map.put("文件类型", content.getSuffix()); + map.put("空间名称", content.getBucket()); + map.put("文件大小", content.getSize()); + map.put("空间类型", content.getType()); + map.put("创建日期", content.getUpdateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/service/mapstruct/LocalStorageMapper.java b/wjcy-tools/src/main/java/me/zhengjie/service/mapstruct/LocalStorageMapper.java new file mode 100644 index 0000000..4c6d955 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/service/mapstruct/LocalStorageMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.service.dto.LocalStorageDto; +import me.zhengjie.domain.LocalStorage; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-09-05 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface LocalStorageMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/wjcy-tools/src/main/java/me/zhengjie/utils/AliPayStatusEnum.java b/wjcy-tools/src/main/java/me/zhengjie/utils/AliPayStatusEnum.java new file mode 100644 index 0000000..c114fd1 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/utils/AliPayStatusEnum.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +/** + * 支付状态 + * @author zhengjie + * @date 2018/08/01 16:45:43 + */ +public enum AliPayStatusEnum { + + /** 交易成功 */ + FINISHED("TRADE_FINISHED"), + + /** 支付成功 */ + SUCCESS("TRADE_SUCCESS"), + + /** 交易创建 */ + BUYER_PAY("WAIT_BUYER_PAY"), + + /** 交易关闭 */ + CLOSED("TRADE_CLOSED"); + + private final String value; + + AliPayStatusEnum(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/utils/AlipayUtils.java b/wjcy-tools/src/main/java/me/zhengjie/utils/AlipayUtils.java new file mode 100644 index 0000000..203f7db --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/utils/AlipayUtils.java @@ -0,0 +1,85 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import com.alipay.api.AlipayApiException; +import com.alipay.api.internal.util.AlipaySignature; +import me.zhengjie.domain.AlipayConfig; +import org.springframework.stereotype.Component; +import javax.servlet.http.HttpServletRequest; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * 支付宝工具类 + * @author zhengjie + * @date 2018/09/30 14:04:35 + */ +@Component +public class AlipayUtils { + + /** + * 生成订单号 + * @return String + */ + public String getOrderCode() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + int a = (int)(Math.random() * 9000.0D) + 1000; + System.out.println(a); + Date date = new Date(); + String str = sdf.format(date); + String[] split = str.split("-"); + String s = split[0] + split[1] + split[2]; + String[] split1 = s.split(" "); + String s1 = split1[0] + split1[1]; + String[] split2 = s1.split(":"); + return split2[0] + split2[1] + split2[2] + a; + } + + /** + * 校验签名 + * @param request HttpServletRequest + * @param alipay 阿里云配置 + * @return boolean + */ + public boolean rsaCheck(HttpServletRequest request, AlipayConfig alipay){ + + // 获取支付宝POST过来反馈信息 + Map params = new HashMap<>(1); + Map requestParams = request.getParameterMap(); + for (Object o : requestParams.keySet()) { + String name = (String) o; + String[] values = requestParams.get(name); + String valueStr = ""; + for (int i = 0; i < values.length; i++) { + valueStr = (i == values.length - 1) ? valueStr + values[i] + : valueStr + values[i] + ","; + } + params.put(name, valueStr); + } + + try { + return AlipaySignature.rsaCheckV1(params, + alipay.getPublicKey(), + alipay.getCharset(), + alipay.getSignType()); + } catch (AlipayApiException e) { + return false; + } + } +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/utils/QiNiuUtil.java b/wjcy-tools/src/main/java/me/zhengjie/utils/QiNiuUtil.java new file mode 100644 index 0000000..8091a95 --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/utils/QiNiuUtil.java @@ -0,0 +1,71 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import com.qiniu.storage.Region; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 七牛云存储工具类 + * @author Zheng Jie + * @date 2018-12-31 + */ +public class QiNiuUtil { + + private static final String HUAD = "华东"; + + private static final String HUAB = "华北"; + + private static final String HUAN = "华南"; + + private static final String BEIM = "北美"; + + /** + * 得到机房的对应关系 + * @param zone 机房名称 + * @return Region + */ + public static Region getRegion(String zone){ + + if(HUAD.equals(zone)){ + return Region.huadong(); + } else if(HUAB.equals(zone)){ + return Region.huabei(); + } else if(HUAN.equals(zone)){ + return Region.huanan(); + } else if (BEIM.equals(zone)){ + return Region.beimei(); + // 否则就是东南亚 + } else { + return Region.qvmHuadong(); + } + } + + /** + * 默认不指定key的情况下,以文件内容的hash值作为文件名 + * @param file 文件名 + * @return String + */ + public static String getKey(String file){ + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + Date date = new Date(); + return FileUtil.getFileNameNoEx(file) + "-" + + sdf.format(date) + + "." + + FileUtil.getExtensionName(file); + } +} diff --git a/wjcy-tools/src/main/java/me/zhengjie/utils/RSACoderUtil.java b/wjcy-tools/src/main/java/me/zhengjie/utils/RSACoderUtil.java new file mode 100644 index 0000000..12fb60f --- /dev/null +++ b/wjcy-tools/src/main/java/me/zhengjie/utils/RSACoderUtil.java @@ -0,0 +1,234 @@ +package me.zhengjie.utils; + +import org.apache.commons.codec.binary.Base64; + +import javax.crypto.Cipher; +import java.security.*; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * 非对称加密算法RSA算法组件 + * 非对称算法一般是用来传送对称加密算法的密钥来使用的,相对于DH算法,RSA算法只需要一方构造密钥,不需要 + * 大费周章的构造各自本地的密钥对了。DH算法只能算法非对称算法的底层实现。而RSA算法算法实现起来较为简单 + *

+ * + * @author: rch + * @date: 2021-09-25 + */ +public class RSACoderUtil { + //非对称密钥算法 + public static final String KEY_ALGORITHM = "RSA"; + + + /** + * 密钥长度,DH算法的默认密钥长度是1024 + * 密钥长度必须是64的倍数,在512到65536位之间 + */ + private static final int KEY_SIZE = 512; + //公钥 + private static final String PUBLIC_KEY = "RSAPublicKey"; + + //私钥 + private static final String PRIVATE_KEY = "RSAPrivateKey"; + + /** + * 初始化密钥对 + * + * @return Map 甲方密钥的Map + */ + public static Map initKey() throws Exception { + //实例化密钥生成器 + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM); + //初始化密钥生成器 + keyPairGenerator.initialize(KEY_SIZE); + //生成密钥对 + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + //甲方公钥 + RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + //甲方私钥 + RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); + //将密钥存储在map中 + Map keyMap = new HashMap(16); + keyMap.put(PUBLIC_KEY, publicKey); + keyMap.put(PRIVATE_KEY, privateKey); + return keyMap; + + } + + + /** + * 私钥加密 + * + * @param data 待加密数据 + * @param key 密钥 + * @return byte[] 加密数据 + */ + public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception { + + //取得私钥 + PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + //生成私钥 + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); + //数据加密 + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + return cipher.doFinal(data); + } + + /** + * 公钥加密 + * + * @param data 待加密数据 + * @param key 密钥 + * @return byte[] 加密数据 + */ + public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception { + + //实例化密钥工厂 + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + //初始化公钥 + //密钥材料转换 + X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); + //产生公钥 + PublicKey pubKey = keyFactory.generatePublic(x509KeySpec); + + //数据加密 + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.ENCRYPT_MODE, pubKey); + return cipher.doFinal(data); + } + + /** + * 私钥解密 + * + * @param data 待解密数据 + * @param key 密钥 + * @return byte[] 解密数据 + */ + public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception { + //取得私钥 + PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + //生成私钥 + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); + //数据解密 + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + return cipher.doFinal(data); + } + + /** + * 公钥解密 + * + * @param data 待解密数据 + * @param key 密钥 + * @return byte[] 解密数据 + */ + public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception { + + //实例化密钥工厂 + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + //初始化公钥 + //密钥材料转换 + X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); + //产生公钥 + PublicKey pubKey = keyFactory.generatePublic(x509KeySpec); + //数据解密 + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.DECRYPT_MODE, pubKey); + return cipher.doFinal(data); + } + + /** + * 取得私钥 + * + * @param keyMap 密钥map + * @return byte[] 私钥 + */ + public static byte[] getPrivateKey(Map keyMap) { + Key key = (Key) keyMap.get(PRIVATE_KEY); + return key.getEncoded(); + } + + /** + * 取得公钥 + * + * @param keyMap 密钥map + * @return byte[] 公钥 + */ + public static byte[] getPublicKey(Map keyMap) throws Exception { + Key key = (Key) keyMap.get(PUBLIC_KEY); + return key.getEncoded(); + } + + /** + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + //初始化密钥 + //生成密钥对 + Map keyMap = RSACoderUtil.initKey(); + //公钥 + byte[] publicKey = RSACoderUtil.getPublicKey(keyMap); + + //私钥 + byte[] privateKey = RSACoderUtil.getPrivateKey(keyMap); + System.out.println("公钥:/n" + Base64.encodeBase64String(publicKey)); + System.out.println("私钥:/n" + Base64.encodeBase64String(privateKey)); + +// System.out.println("================密钥对构造完毕,甲方将公钥公布给乙方,开始进行加密数据的传输============="); +// String str = "RSA密码交换算法"; +// System.out.println("/n===========甲方向乙方发送加密数据=============="); +// System.out.println("原文:" + str); +// //甲方进行数据的加密 +// byte[] code1 = RSACoderUtil.encryptByPrivateKey(str.getBytes(), privateKey); +// System.out.println("加密后的数据:" + Base64.encodeBase64String(code1)); +// System.out.println("===========乙方使用甲方提供的公钥对数据进行解密=============="); +// //乙方进行数据的解密 +// byte[] decode1 = RSACoderUtil.decryptByPublicKey(code1, publicKey); +// System.out.println("乙方解密后的数据:" + new String(decode1) + "/n/n"); +// +// System.out.println("===========反向进行操作,乙方向甲方发送数据==============/n/n"); + + String str = "乙方向甲方发送数据RSA算法"; + + System.out.println("原文:" + str); + + //乙方使用公钥对数据进行加密 + byte[] code2 = RSACoderUtil.encryptByPublicKey(str.getBytes(), publicKey); + System.out.println("===========乙方使用公钥对数据进行加密=============="); + System.out.println("加密后的数据:" + Base64.encodeBase64String(code2)); + + System.out.println("=============乙方将数据传送给甲方======================"); + System.out.println("===========甲方使用私钥对数据进行解密=============="); + + //甲方使用私钥对数据进行解密 + byte[] decode2 = RSACoderUtil.decryptByPrivateKey(code2, privateKey); + + System.out.println("甲方解密后的数据:" + new String(decode2)); + + System.out.println("------------------------------------"); + + //私钥对数据进行加密 + str = "我丢你老母====你是个小可爱"; + byte[] code5 = RSACoderUtil.encryptByPrivateKey(str.getBytes(), privateKey); + System.out.println("===========乙方使用私钥对数据进行加密=============="); + System.out.println("加密后的数据:" + Base64.encodeBase64String(code5)); + + System.out.println("=============乙方将数据传送给甲方======================"); + System.out.println("===========甲方使用私钥对数据进行解密=============="); + + //公钥对数据进行解密 + byte[] decode5 = RSACoderUtil.decryptByPublicKey(code5, publicKey); + + System.out.println("甲方解密后的数据:" + new String(decode5)); + } +}