Initial commit
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
||||||
|
/.idea/
|
||||||
|
**/.flattened-pom.xml
|
||||||
|
**/src/main/resources/bootstrap-local.yml
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
# digital-human-server
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
|
||||||
|
|
||||||
|
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
|
||||||
|
|
||||||
|
## Add your files
|
||||||
|
|
||||||
|
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
|
||||||
|
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd existing_repo
|
||||||
|
git remote add origin http://c64d5b467d10/shi_liangyi/digital-human-server.git
|
||||||
|
git branch -M main
|
||||||
|
git push -uf origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integrate with your tools
|
||||||
|
|
||||||
|
- [ ] [Set up project integrations](http://c64d5b467d10/shi_liangyi/digital-human-server/-/settings/integrations)
|
||||||
|
|
||||||
|
## Collaborate with your team
|
||||||
|
|
||||||
|
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
|
||||||
|
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
|
||||||
|
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
|
||||||
|
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
|
||||||
|
- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
|
||||||
|
|
||||||
|
## Test and Deploy
|
||||||
|
|
||||||
|
Use the built-in continuous integration in GitLab.
|
||||||
|
|
||||||
|
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
|
||||||
|
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
|
||||||
|
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
|
||||||
|
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
|
||||||
|
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
# Editing this README
|
||||||
|
|
||||||
|
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template.
|
||||||
|
|
||||||
|
## Suggestions for a good README
|
||||||
|
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
|
||||||
|
|
||||||
|
## Name
|
||||||
|
Choose a self-explaining name for your project.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
|
||||||
|
|
||||||
|
## Badges
|
||||||
|
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
|
||||||
|
|
||||||
|
## Visuals
|
||||||
|
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
|
||||||
|
|
||||||
|
## Support
|
||||||
|
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
If you have ideas for releases in the future, it is a good idea to list them in the README.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
State if you are open to contributions and what your requirements are for accepting them.
|
||||||
|
|
||||||
|
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
|
||||||
|
|
||||||
|
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
|
||||||
|
|
||||||
|
## Authors and acknowledgment
|
||||||
|
Show your appreciation to those who have contributed to the project.
|
||||||
|
|
||||||
|
## License
|
||||||
|
For open source projects, say how it is licensed.
|
||||||
|
|
||||||
|
## Project status
|
||||||
|
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
config.stopBubbling = true
|
||||||
|
lombok.tostring.callsuper=CALL
|
||||||
|
lombok.equalsandhashcode.callsuper=CALL
|
||||||
|
lombok.accessors.chain=true
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>oneone-alert</artifactId>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>alert-api</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<artifactId>common-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<artifactId>common-web</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Web 相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springdoc</groupId>
|
||||||
|
<artifactId>springdoc-openapi-ui</artifactId>
|
||||||
|
<scope>provided</scope> <!-- 设置为 provided,主要是 PageParam 使用到 -->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 参数校验 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- RPC 远程调用相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.oneone.alert.api.client;
|
||||||
|
|
||||||
|
import com.oneone.alert.api.feign.AlertFeignClient;
|
||||||
|
import com.oneone.alert.api.param.ActionDataParam;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2023-05-30 16:34
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class ActionClient {
|
||||||
|
@Resource
|
||||||
|
private AlertFeignClient alertFeignClient;
|
||||||
|
|
||||||
|
@Async("asyncExecutor")
|
||||||
|
public void push(ActionDataParam actionDataParam) {
|
||||||
|
try {
|
||||||
|
// alertFeignClient.pushActionData(actionDataParam);
|
||||||
|
}catch (Exception e){
|
||||||
|
log.error("pushActionData error",e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package com.oneone.alert.api.common;
|
||||||
|
|
||||||
|
|
||||||
|
public class AlterConstant {
|
||||||
|
public enum BusyCode {
|
||||||
|
UNKNOWN("-1", "未知"),
|
||||||
|
SEND_REWARD("send_reward", "奖励发放"),
|
||||||
|
SEND_BOOK_BACKPACK("send_book_backpack", "发送图书到背包"),
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
BusyCode(String code, String name) {
|
||||||
|
this.code = code;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum BusinessType {
|
||||||
|
LOGIN("login", "登录"),
|
||||||
|
BEGINNER_GUIDE("beginner_guide", "新手指引"),
|
||||||
|
GAME_PERFORMANCE_ISSUES("game_performance_issues", "游戏性能问题"),
|
||||||
|
MALL("mall", "商城"),
|
||||||
|
ELEVATOR("elevator", "电梯"),
|
||||||
|
GAME("game", "游戏"),
|
||||||
|
RACING_CAR("racing_car", "赛车"),
|
||||||
|
ENTERTAINMENT_SPACE("entertainment_space", "娱乐空间"),
|
||||||
|
SQUARE_BIG_SCREEN("square_big_screen", "广场大屏"),
|
||||||
|
STAR_ENERGY_COLLECTOR("star_energy_collector", "星能收集器"),
|
||||||
|
VIRTUAL_STORE("virtual_store", "虚拟店铺"),
|
||||||
|
ART_GALLERY("art_gallery", "艺术馆"),
|
||||||
|
CLICK_ON_ROLE("click_on_role", "点击角色"),
|
||||||
|
CHANGE_ROLE("change_role", "更换角色"),
|
||||||
|
TRANSMIT("transmit", "传送"),
|
||||||
|
ENTER_SCENE("enter_scene", "进入场景"),
|
||||||
|
CHANGE_DECORATION("change_decoration", "更换摆件"),
|
||||||
|
AI_TRAVEL("ai_travel", "AI出行"),
|
||||||
|
;
|
||||||
|
|
||||||
|
BusinessType(String code, String name) {
|
||||||
|
this.code = code;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.oneone.alert.api.event;
|
||||||
|
|
||||||
|
import com.oneone.alert.api.param.EventParam;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AlertEvent extends ApplicationEvent {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public AlertEvent(EventParam source) {
|
||||||
|
super(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
package com.oneone.alert.api.event;
|
||||||
|
|
||||||
|
import com.oneone.alert.api.feign.AlertFeignClient;
|
||||||
|
import com.oneone.alert.api.param.EventParam;
|
||||||
|
import com.oneone.alert.api.util.AlterEventUtil;
|
||||||
|
import com.oneone.common.server.ServerInfo;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class AlertEventListener {
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private AlertFeignClient alertFeignClient;
|
||||||
|
@Autowired
|
||||||
|
private ServerInfo serverInfo;
|
||||||
|
|
||||||
|
@Async("asyncExecutor")
|
||||||
|
@Order
|
||||||
|
@EventListener(AlertEvent.class)
|
||||||
|
public void pushAlertEvent(AlertEvent event) {
|
||||||
|
// Map<String, Object> source = (Map<String, Object>) event.getSource();
|
||||||
|
// EventParam param = (EventParam) source.get(CommonConstant.EVENT_LOG);
|
||||||
|
// AlterEventUtil.addOtherInfo(param, serverInfo);
|
||||||
|
// alertFeignClient.pushEvent(param);
|
||||||
|
try {
|
||||||
|
EventParam param = (EventParam) event.getSource();
|
||||||
|
AlterEventUtil.addOtherInfo(param, serverInfo);
|
||||||
|
alertFeignClient.pushEvent(param);
|
||||||
|
}catch (Exception e){
|
||||||
|
log.error("pushAlertEvent error",e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.oneone.alert.api.feign;
|
||||||
|
|
||||||
|
import com.oneone.alert.api.param.ActionDataParam;
|
||||||
|
import com.oneone.alert.api.param.EventParam;
|
||||||
|
import com.oneone.common.result.Result;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
|
@FeignClient(name = "oneone-alert", contextId = "alert")
|
||||||
|
public interface AlertFeignClient {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 推送事件
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("api/v1/event/pushEvent")
|
||||||
|
Result pushEvent(@RequestBody EventParam param);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 推送行为数据
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("api/v1/actiondata/save")
|
||||||
|
Result pushActionData(@RequestBody ActionDataParam param);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package com.oneone.alert.api.param;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 数据收集表
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-05-09 16:58:58
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "数据收集表")
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class ActionDataParam {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
@Schema
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务类型
|
||||||
|
*/
|
||||||
|
@Schema(description="业务类型")
|
||||||
|
private String businessType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
@Schema(description="用户id",hidden = true)
|
||||||
|
private Long memberId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField6;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField7;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField9;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField10;
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package com.oneone.alert.api.param;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 事件
|
||||||
|
* @author mice
|
||||||
|
* @date 2022-04-20 12:10:02
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "事件")
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class EventParam extends EventParamAbstract{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标题
|
||||||
|
*/
|
||||||
|
@Schema(description="标题")
|
||||||
|
@Length(max = 8)
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 告警等级
|
||||||
|
*/
|
||||||
|
@Schema(description="告警等级")
|
||||||
|
private Integer level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用
|
||||||
|
*/
|
||||||
|
@Schema(description="应用")
|
||||||
|
private String app;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定通知人"183xxxxx,132xxxxxx"
|
||||||
|
*/
|
||||||
|
@Schema(description="通知人手机号,不为空则不走策略 直接推送。")
|
||||||
|
@Length(max = 200)
|
||||||
|
private String notifyUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容
|
||||||
|
*/
|
||||||
|
@Schema(description="内容")
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 告警等级
|
||||||
|
*/
|
||||||
|
@Schema(description="业务编码")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
public EventParam(String code, String content) {
|
||||||
|
this.code = code;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EventParam(String title, Integer level, String app, String notifyUser, String content) {
|
||||||
|
this.title = title;
|
||||||
|
this.level = level;
|
||||||
|
this.app = app;
|
||||||
|
this.notifyUser = notifyUser;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
}
|
||||||
+103
@@ -0,0 +1,103 @@
|
|||||||
|
package com.oneone.alert.api.param;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logApi、logError、logUsual的父类,拥有相同的属性值
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class EventParamAbstract implements Serializable {
|
||||||
|
|
||||||
|
protected static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务ID
|
||||||
|
*/
|
||||||
|
protected String serviceId;
|
||||||
|
/**
|
||||||
|
* 服务器 ip
|
||||||
|
*/
|
||||||
|
protected String serverIp;
|
||||||
|
/**
|
||||||
|
* 服务器名
|
||||||
|
*/
|
||||||
|
protected String serverHost;
|
||||||
|
/**
|
||||||
|
* 操作IP地址
|
||||||
|
*/
|
||||||
|
protected String remoteIp;
|
||||||
|
/**
|
||||||
|
* 用户代理
|
||||||
|
*/
|
||||||
|
protected String userAgent;
|
||||||
|
/**
|
||||||
|
* 请求URI
|
||||||
|
*/
|
||||||
|
protected String requestUri;
|
||||||
|
/**
|
||||||
|
* 操作方式
|
||||||
|
*/
|
||||||
|
protected String method;
|
||||||
|
/**
|
||||||
|
* 方法类
|
||||||
|
*/
|
||||||
|
protected String methodClass;
|
||||||
|
/**
|
||||||
|
* 方法名
|
||||||
|
*/
|
||||||
|
protected String methodName;
|
||||||
|
/**
|
||||||
|
* 操作提交的数据
|
||||||
|
*/
|
||||||
|
protected String params;
|
||||||
|
/**
|
||||||
|
* 执行时间
|
||||||
|
*/
|
||||||
|
protected String time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人
|
||||||
|
*/
|
||||||
|
protected String createBy;
|
||||||
|
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
protected Date createTime;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件名
|
||||||
|
*/
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代码行数
|
||||||
|
*/
|
||||||
|
private Integer lineNumber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 堆栈信息
|
||||||
|
*/
|
||||||
|
private String stackTrace;
|
||||||
|
/**
|
||||||
|
* 异常名
|
||||||
|
*/
|
||||||
|
private String exceptionName;
|
||||||
|
/**
|
||||||
|
* 异常消息
|
||||||
|
*/
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 告警等级
|
||||||
|
*/
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
}
|
||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
package com.oneone.alert.api.publisher;
|
||||||
|
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
|
import com.oneone.alert.api.event.AlertEvent;
|
||||||
|
import com.oneone.alert.api.param.EventParam;
|
||||||
|
import com.oneone.alert.api.util.AlterEventUtil;
|
||||||
|
import com.oneone.common.util.Exceptions;
|
||||||
|
import com.oneone.common.util.Func;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AlertEventPublisher {
|
||||||
|
public static void publishEvent(Throwable error, EventParam eventParam) {
|
||||||
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||||
|
if (eventParam == null) {
|
||||||
|
eventParam = new EventParam();
|
||||||
|
}
|
||||||
|
if (Func.isNotEmpty(error)) {
|
||||||
|
eventParam.setStackTrace(Exceptions.getStackTraceAsString(error));
|
||||||
|
eventParam.setExceptionName(error.getClass().getName());
|
||||||
|
eventParam.setMessage(error.getMessage());
|
||||||
|
StackTraceElement[] elements = error.getStackTrace();
|
||||||
|
if (Func.isNotEmpty(elements)) {
|
||||||
|
StackTraceElement element = elements[0];
|
||||||
|
eventParam.setMethodName(element.getMethodName());
|
||||||
|
eventParam.setMethodClass(element.getClassName());
|
||||||
|
eventParam.setFileName(element.getFileName());
|
||||||
|
eventParam.setLineNumber(element.getLineNumber());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AlterEventUtil.addRequestInfo(request, eventParam);
|
||||||
|
SpringUtil.publishEvent(new AlertEvent(eventParam));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void publishEvent(EventParam eventParam) {
|
||||||
|
SpringUtil.publishEvent(new AlertEvent(eventParam));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.oneone.alert.api.util;
|
||||||
|
|
||||||
|
import com.oneone.alert.api.param.EventParam;
|
||||||
|
import com.oneone.common.server.ServerInfo;
|
||||||
|
import com.oneone.common.util.Func;
|
||||||
|
import com.oneone.common.web.util.UserContext;
|
||||||
|
import com.oneone.common.web.util.WebUtil;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class AlterEventUtil {
|
||||||
|
public static void addOtherInfo(EventParam param, ServerInfo serverInfo) {
|
||||||
|
|
||||||
|
param.setServiceId(serverInfo.getApplicationName());
|
||||||
|
param.setApp(serverInfo.getApplicationName());
|
||||||
|
param.setServerHost(serverInfo.getHostName());
|
||||||
|
param.setServerIp(serverInfo.getIpWithPort());
|
||||||
|
param.setCreateTime(new Date());
|
||||||
|
//这里判断一下params为null的情况,否则blade-log服务在解析该字段的时候,可能会报出NPE
|
||||||
|
if (param.getParams() == null) {
|
||||||
|
param.setParams("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addRequestInfo(HttpServletRequest request, EventParam eventParam) {
|
||||||
|
eventParam.setRemoteIp(WebUtil.getIP(request));
|
||||||
|
eventParam.setUserAgent(request.getHeader(WebUtil.USER_AGENT_HEADER));
|
||||||
|
eventParam.setRequestUri(WebUtil.getPath(request.getRequestURI()));
|
||||||
|
eventParam.setMethod(request.getMethod());
|
||||||
|
if(Func.isEmpty(eventParam.getParams())){
|
||||||
|
eventParam.setParams(WebUtil.getRequestParamString(request));
|
||||||
|
}
|
||||||
|
eventParam.setCreateBy(UserContext.getUserId()+"");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||||
|
com.oneone.common.server.ServerInfo,\
|
||||||
|
com.oneone.alert.api.event.AlertEventListener,\
|
||||||
|
com.oneone.alert.api.client.ActionClient
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>oneone-alert</artifactId>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>alert-boot</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!--Spring Cloud & Alibaba -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 注册中心 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 配置中心 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<artifactId>common-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<artifactId>common-mybatis-plus</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<artifactId>velocity</artifactId>
|
||||||
|
<groupId>org.apache.velocity</groupId>
|
||||||
|
<version>1.7</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<artifactId>alert-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.kafka</groupId>
|
||||||
|
<artifactId>spring-kafka</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.oneone.alert;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||||
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
|
@EnableFeignClients(basePackages = {"com.oneone.alert.api.feign"})
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableDiscoveryClient
|
||||||
|
@EnableScheduling
|
||||||
|
@EnableAsync
|
||||||
|
public class AlertApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(AlertApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.oneone.alert.common;
|
||||||
|
|
||||||
|
|
||||||
|
public class AlertConstant {
|
||||||
|
public static final String ACTION_DATA_TOPIC="actionDataLog";
|
||||||
|
public static final String ACTION_DATA_GROUP="actionDataGroup";
|
||||||
|
public static final String USER_BEHAVIOR_TOPIC="user-behavior";
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.oneone.alert.common;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-03-24 19:13
|
||||||
|
*/
|
||||||
|
public enum EventStatusEnum {
|
||||||
|
NO_SEND(0,"未发送"),
|
||||||
|
SENT(1,"已经发送"),
|
||||||
|
DEAL(2,"已处理"),
|
||||||
|
;
|
||||||
|
|
||||||
|
EventStatusEnum(Integer code, String desc) {
|
||||||
|
this.code = code;
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Integer code;
|
||||||
|
@Getter
|
||||||
|
private String desc;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.oneone.alert.common;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-04-20 13:51
|
||||||
|
*/
|
||||||
|
public interface FeishuConstants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录
|
||||||
|
*/
|
||||||
|
String LOGIN_URL = "https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送消息
|
||||||
|
*/
|
||||||
|
String MESSAGES = "https://open.feishu.cn/open-apis/im/v1/messages";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群发
|
||||||
|
*/
|
||||||
|
String BATCH_SEND = "https://open.feishu.cn/open-apis/message/v4/batch_send/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群发
|
||||||
|
*/
|
||||||
|
String QUERY_UID = "https://open.feishu.cn/open-apis/contact/v3/users/batch_get_id";
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package com.oneone.alert.config;
|
||||||
|
|
||||||
|
import com.oneone.alert.common.AlertConstant;
|
||||||
|
import org.apache.kafka.clients.admin.NewTopic;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class KafkaInitialConfiguration {
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public NewTopic initialTopic() {
|
||||||
|
return new NewTopic(AlertConstant.ACTION_DATA_TOPIC,8, (short) 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.oneone.alert.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2023-02-20 18:09
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ConfigurationProperties(prefix = "sender-config")
|
||||||
|
@Configuration
|
||||||
|
public class SenderProperties {
|
||||||
|
private String appId="cli_a4859ac07439500d";
|
||||||
|
private String appSecret="fjMoNtzKU7VOlaJR5psPAhWH2bzzz6Dz";
|
||||||
|
|
||||||
|
}
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
package com.oneone.alert.controller;
|
||||||
|
|
||||||
|
import com.oneone.alert.common.AlertConstant;
|
||||||
|
import com.oneone.alert.pojo.entity.ActionData;
|
||||||
|
import com.oneone.alert.service.ActionDataService;
|
||||||
|
import com.oneone.common.result.Result;
|
||||||
|
import com.oneone.common.util.JsonUtils;
|
||||||
|
import com.oneone.common.web.util.UserContext;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.kafka.core.KafkaTemplate;
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据收集表
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-05-09 16:58:58
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("app-api/v1/actiondata")
|
||||||
|
@Tag(name = "数据收集表管理")
|
||||||
|
public class ActionDataController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ActionDataService actionDataService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private KafkaTemplate<String, Object> kafkaTemplate;
|
||||||
|
|
||||||
|
|
||||||
|
@Operation(summary = "新增数据收集表")
|
||||||
|
@PostMapping("/save")
|
||||||
|
public Result<Boolean> save(@RequestBody ActionData actionData) {
|
||||||
|
actionData.setMemberId(UserContext.getUserIdIfPresentDefault());
|
||||||
|
|
||||||
|
kafkaTemplate.send(AlertConstant.ACTION_DATA_TOPIC, JsonUtils.toJSONString(actionData));
|
||||||
|
// actionDataService.save(actionData)
|
||||||
|
return Result.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
package com.oneone.alert.controller;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.oneone.alert.common.AlertConstant;
|
||||||
|
import com.oneone.alert.pojo.entity.ActionData;
|
||||||
|
import com.oneone.alert.service.ActionDataService;
|
||||||
|
import com.oneone.common.result.Result;
|
||||||
|
import com.oneone.common.util.JsonUtils;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.kafka.core.KafkaTemplate;
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据收集表
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-05-09 16:58:58
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("api/v1/actiondata")
|
||||||
|
@Tag(name = "admin-数据收集表管理")
|
||||||
|
public class AdminActionDataController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ActionDataService actionDataService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private KafkaTemplate<String, Object> kafkaTemplate;
|
||||||
|
|
||||||
|
|
||||||
|
@Operation(summary = "新增数据收集表")
|
||||||
|
@PostMapping("/save")
|
||||||
|
public Result<Boolean> save(@RequestBody ActionData actionData) {
|
||||||
|
kafkaTemplate.send(AlertConstant.ACTION_DATA_TOPIC, JsonUtils.toJSONString(actionData));
|
||||||
|
kafkaTemplate.send("user-behavior", JsonUtils.toJSONString(ImmutableMap.of("action", actionData.getBusinessType())));
|
||||||
|
return Result.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+93
@@ -0,0 +1,93 @@
|
|||||||
|
package com.oneone.alert.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.oneone.alert.pojo.entity.AlertStage;
|
||||||
|
import com.oneone.alert.service.AlertStageService;
|
||||||
|
import com.oneone.common.result.Result;
|
||||||
|
import com.oneone.common.web.security.annotation.RequiresPermissions;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通知策略
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-03-13 12:03:18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("api/v1/alertstage")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Tag(name = "通知策略管理")
|
||||||
|
public class AlertStageController {
|
||||||
|
|
||||||
|
private final AlertStageService alertStageService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询
|
||||||
|
* @param page 分页对象
|
||||||
|
* @param alertStage 通知策略
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary = "分页查询")
|
||||||
|
@GetMapping("/page" )
|
||||||
|
@RequiresPermissions("alert:alertstage:list")
|
||||||
|
public Result<IPage<AlertStage>> getAlertStagePage(Page page, AlertStage alertStage) {
|
||||||
|
return Result.success(alertStageService.page(page, Wrappers.query(alertStage)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询通知策略
|
||||||
|
* @param id id
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "通过id查询")
|
||||||
|
@GetMapping("/{id}" )
|
||||||
|
@RequiresPermissions("alert:alertstage:getById")
|
||||||
|
public Result<AlertStage> getById(@PathVariable("id" ) Long id) {
|
||||||
|
return Result.success(alertStageService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增通知策略
|
||||||
|
* @param alertStage 通知策略
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "新增通知策略")
|
||||||
|
@PostMapping
|
||||||
|
@RequiresPermissions("alert:alertstage:add")
|
||||||
|
public Result<Boolean> save(@RequestBody AlertStage alertStage) {
|
||||||
|
return Result.success(alertStageService.save(alertStage));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改通知策略
|
||||||
|
* @param alertStage 通知策略
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "修改通知策略")
|
||||||
|
@PutMapping
|
||||||
|
@RequiresPermissions("alert:alertstage:edit")
|
||||||
|
public Result<Boolean> updateById(@RequestBody AlertStage alertStage) {
|
||||||
|
return Result.success(alertStageService.updateById(alertStage));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除通知策略
|
||||||
|
* @param id id
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "通过id删除通知策略")
|
||||||
|
@DeleteMapping("/{id}" )
|
||||||
|
@RequiresPermissions("alert:alertstage:delete")
|
||||||
|
public Result<Boolean> removeById(@PathVariable Long id) {
|
||||||
|
return Result.success(alertStageService.removeById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+93
@@ -0,0 +1,93 @@
|
|||||||
|
package com.oneone.alert.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.oneone.alert.pojo.entity.CodeStageRel;
|
||||||
|
import com.oneone.alert.service.CodeStageRelService;
|
||||||
|
import com.oneone.common.result.Result;
|
||||||
|
import com.oneone.common.web.security.annotation.RequiresPermissions;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通知策略-事件
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-03-13 12:03:18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("alert/codestagerel")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Tag(name = "通知策略-事件管理")
|
||||||
|
public class CodeStageRelController {
|
||||||
|
|
||||||
|
private final CodeStageRelService codeStageRelService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询
|
||||||
|
* @param page 分页对象
|
||||||
|
* @param codeStageRel 通知策略-事件
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary = "分页查询")
|
||||||
|
@GetMapping("/page" )
|
||||||
|
@RequiresPermissions("alert:codestagerel:list")
|
||||||
|
public Result<IPage<CodeStageRel>> getCodeStageRelPage(Page page, CodeStageRel codeStageRel) {
|
||||||
|
return Result.success(codeStageRelService.page(page, Wrappers.query(codeStageRel)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询通知策略-事件
|
||||||
|
* @param id id
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "通过id查询")
|
||||||
|
@GetMapping("/{id}" )
|
||||||
|
@RequiresPermissions("alert:codestagerel:getById")
|
||||||
|
public Result<CodeStageRel> getById(@PathVariable("id" ) Long id) {
|
||||||
|
return Result.success(codeStageRelService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增通知策略-事件
|
||||||
|
* @param codeStageRel 通知策略-事件
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "新增通知策略-事件")
|
||||||
|
@PostMapping
|
||||||
|
@RequiresPermissions("alert:codestagerel:add")
|
||||||
|
public Result<Boolean> save(@RequestBody CodeStageRel codeStageRel) {
|
||||||
|
return Result.success(codeStageRelService.save(codeStageRel));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改通知策略-事件
|
||||||
|
* @param codeStageRel 通知策略-事件
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "修改通知策略-事件")
|
||||||
|
@PutMapping
|
||||||
|
@RequiresPermissions("alert:codestagerel:edit")
|
||||||
|
public Result<Boolean> updateById(@RequestBody CodeStageRel codeStageRel) {
|
||||||
|
return Result.success(codeStageRelService.updateById(codeStageRel));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除通知策略-事件
|
||||||
|
* @param id id
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "通过id删除通知策略-事件")
|
||||||
|
@DeleteMapping("/{id}" )
|
||||||
|
@RequiresPermissions("alert:codestagerel:delete")
|
||||||
|
public Result<Boolean> removeById(@PathVariable Long id) {
|
||||||
|
return Result.success(codeStageRelService.removeById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+121
@@ -0,0 +1,121 @@
|
|||||||
|
package com.oneone.alert.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.oneone.alert.api.common.AlterConstant;
|
||||||
|
import com.oneone.alert.api.param.EventParam;
|
||||||
|
import com.oneone.alert.pojo.entity.Event;
|
||||||
|
import com.oneone.alert.service.EventLogService;
|
||||||
|
import com.oneone.alert.service.EventService;
|
||||||
|
import com.oneone.common.result.Result;
|
||||||
|
import com.oneone.common.util.Func;
|
||||||
|
import com.oneone.common.web.security.annotation.RequiresPermissions;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件
|
||||||
|
* @author mice
|
||||||
|
* @date 2022-04-20 12:10:02
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("api/v1/event")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Tag(name = "事件管理")
|
||||||
|
public class EventController {
|
||||||
|
|
||||||
|
private final EventService eventService;
|
||||||
|
|
||||||
|
private final EventLogService eventLogService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询
|
||||||
|
* @param page 分页对象
|
||||||
|
* @param event 事件
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary = "分页查询")
|
||||||
|
@GetMapping("/page" )
|
||||||
|
@RequiresPermissions("alert:event:list")
|
||||||
|
public Result<IPage<Event>> getEventPage(Page page, Event event) {
|
||||||
|
return Result.success(eventService.page(page, Wrappers.query(event)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询事件
|
||||||
|
* @param id id
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "通过id查询")
|
||||||
|
@GetMapping("/{id}" )
|
||||||
|
@RequiresPermissions("alert:event:getById")
|
||||||
|
public Result<Event> getById(@PathVariable("id" ) Long id) {
|
||||||
|
return Result.success(eventService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增事件
|
||||||
|
* @param event 事件
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "新增事件")
|
||||||
|
@PostMapping
|
||||||
|
@RequiresPermissions("alert:event:add")
|
||||||
|
public Result<Boolean> save(@RequestBody Event event) {
|
||||||
|
return Result.success(eventService.save(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改事件
|
||||||
|
* @param event 事件
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "修改事件")
|
||||||
|
@PutMapping
|
||||||
|
@RequiresPermissions("alert:event:edit")
|
||||||
|
public Result<Boolean> updateById(@RequestBody Event event) {
|
||||||
|
return Result.success(eventService.updateById(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除事件
|
||||||
|
* @param id id
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "通过id删除事件")
|
||||||
|
@DeleteMapping("/{id}" )
|
||||||
|
@RequiresPermissions("alert:event:delete")
|
||||||
|
public Result<Boolean> removeById(@PathVariable Long id) {
|
||||||
|
return Result.success(eventService.removeById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Operation(summary = "事件推送")
|
||||||
|
@PostMapping("pushEvent")
|
||||||
|
@RequiresPermissions("alert:event:pushEvent")
|
||||||
|
public Result<Boolean> pushEvent(@RequestBody EventParam param) {
|
||||||
|
// eventService.pushEvent(param);
|
||||||
|
if(Func.isEmpty(param.getCode())){
|
||||||
|
param.setCode(AlterConstant.BusyCode.UNKNOWN.getCode());
|
||||||
|
}
|
||||||
|
eventLogService.saveLog(param);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Operation(summary = "事件推送")
|
||||||
|
@PostMapping("pushEventLog")
|
||||||
|
@RequiresPermissions("alert:event:pushEventLog")
|
||||||
|
public Result<Boolean> pushEventLog(@RequestBody EventParam param) {
|
||||||
|
eventLogService.saveLog(param);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+93
@@ -0,0 +1,93 @@
|
|||||||
|
package com.oneone.alert.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.oneone.alert.pojo.entity.EventLog;
|
||||||
|
import com.oneone.alert.service.EventLogService;
|
||||||
|
import com.oneone.common.result.Result;
|
||||||
|
import com.oneone.common.web.security.annotation.RequiresPermissions;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-03-13 12:03:18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("alert/eventlog")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Tag(name = "事件管理")
|
||||||
|
public class EventLogController {
|
||||||
|
|
||||||
|
private final EventLogService eventLogService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询
|
||||||
|
* @param page 分页对象
|
||||||
|
* @param eventLog 事件
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary = "分页查询")
|
||||||
|
@GetMapping("/page" )
|
||||||
|
@RequiresPermissions("alert:eventlog:list")
|
||||||
|
public Result<IPage<EventLog>> getEventLogPage(Page page, EventLog eventLog) {
|
||||||
|
return Result.success(eventLogService.page(page, Wrappers.query(eventLog)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询事件
|
||||||
|
* @param id id
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "通过id查询")
|
||||||
|
@GetMapping("/{id}" )
|
||||||
|
@RequiresPermissions("alert:eventlog:getById")
|
||||||
|
public Result<EventLog> getById(@PathVariable("id" ) Long id) {
|
||||||
|
return Result.success(eventLogService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增事件
|
||||||
|
* @param eventLog 事件
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "新增事件")
|
||||||
|
@PostMapping
|
||||||
|
@RequiresPermissions("alert:eventlog:add")
|
||||||
|
public Result<Boolean> save(@RequestBody EventLog eventLog) {
|
||||||
|
return Result.success(eventLogService.save(eventLog));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改事件
|
||||||
|
* @param eventLog 事件
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "修改事件")
|
||||||
|
@PutMapping
|
||||||
|
@RequiresPermissions("alert:eventlog:edit")
|
||||||
|
public Result<Boolean> updateById(@RequestBody EventLog eventLog) {
|
||||||
|
return Result.success(eventLogService.updateById(eventLog));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除事件
|
||||||
|
* @param id id
|
||||||
|
* @return Result
|
||||||
|
*/
|
||||||
|
@Operation(summary = "通过id删除事件")
|
||||||
|
@DeleteMapping("/{id}" )
|
||||||
|
@RequiresPermissions("alert:eventlog:delete")
|
||||||
|
public Result<Boolean> removeById(@PathVariable Long id) {
|
||||||
|
return Result.success(eventLogService.removeById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.oneone.alert.handler;
|
||||||
|
|
||||||
|
import com.oneone.alert.common.AlertConstant;
|
||||||
|
import com.oneone.alert.pojo.dto.UserBehaviorEvent;
|
||||||
|
import com.oneone.alert.pojo.entity.ActionData;
|
||||||
|
import com.oneone.alert.service.ActionDataService;
|
||||||
|
import com.oneone.common.util.JsonUtils;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.kafka.annotation.KafkaListener;
|
||||||
|
import org.springframework.kafka.core.KafkaTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class KafkaHandler {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ActionDataService actionDataService;
|
||||||
|
@Autowired
|
||||||
|
private KafkaTemplate<String, Object> kafkaTemplate;
|
||||||
|
// 消费监听
|
||||||
|
@KafkaListener(topics = {AlertConstant.ACTION_DATA_TOPIC}
|
||||||
|
,groupId = AlertConstant.ACTION_DATA_GROUP)
|
||||||
|
public void onMessage1(ConsumerRecord<?, ?> record) {
|
||||||
|
// 消费的哪个topic、partition的消息,打印出消息内容
|
||||||
|
// System.out.println("简单消费:" + record.topic() + "-" + record.partition() + "-" + record.value());
|
||||||
|
String value = (String) record.value();
|
||||||
|
ActionData actionData = JsonUtils.strToClass(value, ActionData.class);
|
||||||
|
actionDataService.save(actionData);
|
||||||
|
|
||||||
|
UserBehaviorEvent userBehaviorEvent = new UserBehaviorEvent(actionData.getMemberId().intValue(),actionData.getBusinessType(),System.currentTimeMillis(),actionData.getDataField1());
|
||||||
|
String userBehaviorEventStr = JsonUtils.toJSONString(userBehaviorEvent);
|
||||||
|
kafkaTemplate.send(AlertConstant.USER_BEHAVIOR_TOPIC,userBehaviorEventStr);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.oneone.alert.mapper;
|
||||||
|
|
||||||
|
import com.oneone.alert.pojo.entity.ActionData;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 数据收集表
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-05-09 16:58:58
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface ActionDataMapper extends BaseMapper<ActionData> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.oneone.alert.mapper;
|
||||||
|
|
||||||
|
import com.oneone.alert.pojo.entity.AlertStage;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 通知策略
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-03-13 12:03:18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface AlertStageMapper extends BaseMapper<AlertStage> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.oneone.alert.mapper;
|
||||||
|
|
||||||
|
import com.oneone.alert.pojo.entity.CodeStageRel;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 通知策略-事件
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-03-13 12:03:18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface CodeStageRelMapper extends BaseMapper<CodeStageRel> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.oneone.alert.mapper;
|
||||||
|
|
||||||
|
import com.oneone.alert.pojo.entity.EventLog;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 事件
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-03-13 12:03:18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface EventLogMapper extends BaseMapper<EventLog> {
|
||||||
|
|
||||||
|
@Select(" select count(1) from t_event_log t where t.`code`=#{code} and \n" +
|
||||||
|
" t.gmt_create> date_add(now(), interval -#{timeMinute} minute);")
|
||||||
|
int getInTimeCount(Integer timeMinute, String code);
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.oneone.alert.mapper;
|
||||||
|
|
||||||
|
import com.oneone.alert.pojo.entity.Event;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 事件
|
||||||
|
* @author mice
|
||||||
|
* @date 2022-04-20 12:10:02
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface EventMapper extends BaseMapper<Event> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.oneone.alert.pojo.dto;
|
||||||
|
|
||||||
|
import com.oneone.alert.pojo.entity.AlertStage;
|
||||||
|
import com.oneone.alert.pojo.entity.CodeStageRel;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class CodeStageRelDTO extends CodeStageRel {
|
||||||
|
private AlertStage stage;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.oneone.alert.pojo.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-04-20 14:56
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class Message {
|
||||||
|
private String msgType;
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package com.oneone.alert.pojo.dto;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class UserBehaviorEvent {
|
||||||
|
private int userId;
|
||||||
|
private String action;
|
||||||
|
private long timestamp;
|
||||||
|
private String filed1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
package com.oneone.alert.pojo.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 数据收集表
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-05-09 16:58:58
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("t_action_data")
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Schema(description = "数据收集表")
|
||||||
|
public class ActionData extends Model<ActionData> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
@Schema(description="",hidden = true)
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务类型
|
||||||
|
*/
|
||||||
|
@Schema(description="业务类型")
|
||||||
|
private String businessType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
@Schema(description="用户id",hidden = true)
|
||||||
|
private Long memberId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField6;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField7;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField9;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字段节点
|
||||||
|
*/
|
||||||
|
@Schema(description="数据字段节点")
|
||||||
|
private String dataField10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@Schema(description="创建时间",hidden = true)
|
||||||
|
private LocalDateTime gmtCreate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@Schema(description="更新时间",hidden = true)
|
||||||
|
private LocalDateTime gmtModified;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package com.oneone.alert.pojo.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 通知策略
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-03-13 12:03:18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("t_alert_stage")
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Schema(description = "通知策略")
|
||||||
|
public class AlertStage extends Model<AlertStage> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
@Schema(description="")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分钟
|
||||||
|
*/
|
||||||
|
@Schema(description="分钟")
|
||||||
|
private Integer timeMinute;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 条数
|
||||||
|
*/
|
||||||
|
@Schema(description="条数")
|
||||||
|
private Integer num;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通知类型0飞书
|
||||||
|
*/
|
||||||
|
@Schema(description="通知类型0飞书")
|
||||||
|
private Integer notifyType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通知手机号
|
||||||
|
*/
|
||||||
|
@Schema(description="通知手机号")
|
||||||
|
private String notifyPhone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认策略
|
||||||
|
*/
|
||||||
|
@Schema(description="默认策略")
|
||||||
|
private Integer isDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 告警等级
|
||||||
|
*/
|
||||||
|
@Schema(description="告警等级")
|
||||||
|
private Integer level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@Schema(description="创建时间")
|
||||||
|
private LocalDateTime gmtCreate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@Schema(description="更新时间")
|
||||||
|
private LocalDateTime gmtModified;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package com.oneone.alert.pojo.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 通知策略-事件
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-03-13 12:03:18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("t_code_stage_rel")
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Schema(description = "通知策略-事件")
|
||||||
|
public class CodeStageRel extends Model<CodeStageRel> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
@Schema(description="")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务code
|
||||||
|
*/
|
||||||
|
@Schema(description="业务code")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 策略id
|
||||||
|
*/
|
||||||
|
@Schema(description="策略id")
|
||||||
|
private Long stageId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通知标题
|
||||||
|
*/
|
||||||
|
@Schema(description="通知标题")
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Schema(description="应用")
|
||||||
|
private String app;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@Schema(description="创建时间")
|
||||||
|
private LocalDateTime gmtCreate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@Schema(description="更新时间")
|
||||||
|
private LocalDateTime gmtModified;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
package com.oneone.alert.pojo.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 事件
|
||||||
|
* @author mice
|
||||||
|
* @date 2022-04-20 12:10:02
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("t_event")
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Schema(description = "事件")
|
||||||
|
public class Event extends Model<Event> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
@Schema(description="")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日志id
|
||||||
|
*/
|
||||||
|
@Schema(description="日志id")
|
||||||
|
private Long logId;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务code
|
||||||
|
*/
|
||||||
|
@Schema(description="业务code")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标题
|
||||||
|
*/
|
||||||
|
@Schema(description="标题")
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 告警等级
|
||||||
|
*/
|
||||||
|
@Schema(description="告警等级")
|
||||||
|
private Integer level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用
|
||||||
|
*/
|
||||||
|
@Schema(description="应用")
|
||||||
|
private String app;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通知人id [userId:userName,1:陈浩]
|
||||||
|
*/
|
||||||
|
@Schema(description="通知人id")
|
||||||
|
private String notifyUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容
|
||||||
|
*/
|
||||||
|
@Schema(description="内容")
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件状态
|
||||||
|
*/
|
||||||
|
@Schema(description="事件状态")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@Schema(description="创建时间")
|
||||||
|
private LocalDateTime gmtCreate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@Schema(description="更新时间")
|
||||||
|
private LocalDateTime gmtModified;
|
||||||
|
|
||||||
|
@Schema(description="策略id")
|
||||||
|
private Long stageId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
package com.oneone.alert.pojo.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 事件
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-03-13 12:03:18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("t_event_log")
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Schema(description = "事件")
|
||||||
|
public class EventLog extends Model<EventLog> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
@Schema(description="")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务code
|
||||||
|
*/
|
||||||
|
@Schema(description="业务code")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务ID
|
||||||
|
*/
|
||||||
|
@Schema(description="服务ID")
|
||||||
|
private String serviceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务器名
|
||||||
|
*/
|
||||||
|
@Schema(description="服务器名")
|
||||||
|
private String serverHost;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务器IP地址
|
||||||
|
*/
|
||||||
|
@Schema(description="服务器IP地址")
|
||||||
|
private String serverIp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作方式
|
||||||
|
*/
|
||||||
|
@Schema(description="操作方式")
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求URI
|
||||||
|
*/
|
||||||
|
@Schema(description="请求URI")
|
||||||
|
private String requestUri;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户代理
|
||||||
|
*/
|
||||||
|
@Schema(description="用户代理")
|
||||||
|
private String userAgent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 堆栈
|
||||||
|
*/
|
||||||
|
@Schema(description="堆栈")
|
||||||
|
private String stackTrace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常名
|
||||||
|
*/
|
||||||
|
@Schema(description="异常名")
|
||||||
|
private String exceptionName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常信息
|
||||||
|
*/
|
||||||
|
@Schema(description="异常信息")
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误行数
|
||||||
|
*/
|
||||||
|
@Schema(description="错误行数")
|
||||||
|
private Integer lineNumber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作IP地址
|
||||||
|
*/
|
||||||
|
@Schema(description="操作IP地址")
|
||||||
|
private String remoteIp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 方法类
|
||||||
|
*/
|
||||||
|
@Schema(description="方法类")
|
||||||
|
private String methodClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件名
|
||||||
|
*/
|
||||||
|
@Schema(description="文件名")
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 方法名
|
||||||
|
*/
|
||||||
|
@Schema(description="方法名")
|
||||||
|
private String methodName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作提交的数据
|
||||||
|
*/
|
||||||
|
@Schema(description="操作提交的数据")
|
||||||
|
private String params;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件状态
|
||||||
|
*/
|
||||||
|
@Schema(description="事件状态")
|
||||||
|
private Boolean status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@Schema(description="创建时间")
|
||||||
|
private LocalDateTime gmtCreate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@Schema(description="更新时间")
|
||||||
|
private LocalDateTime gmtModified;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定通知内容
|
||||||
|
*/
|
||||||
|
@Schema(description="指定通知内容")
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定通知标题
|
||||||
|
*/
|
||||||
|
@Schema(description="指定通知标题")
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定通知手机号
|
||||||
|
*/
|
||||||
|
@Schema(description="指定通知手机号")
|
||||||
|
private String notifyUser;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.oneone.alert.sender;
|
||||||
|
|
||||||
|
import com.oneone.alert.pojo.entity.Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-04-20 13:43
|
||||||
|
*/
|
||||||
|
public interface BaseSender {
|
||||||
|
|
||||||
|
void send(Event event);
|
||||||
|
|
||||||
|
void refreshToken();
|
||||||
|
}
|
||||||
@@ -0,0 +1,256 @@
|
|||||||
|
package com.oneone.alert.sender;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.http.HttpResponse;
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.TypeReference;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
import com.google.common.cache.LoadingCache;
|
||||||
|
import com.oneone.alert.common.EventStatusEnum;
|
||||||
|
import com.oneone.alert.config.SenderProperties;
|
||||||
|
import com.oneone.alert.pojo.entity.Event;
|
||||||
|
import com.oneone.alert.sender.resp.FSUser;
|
||||||
|
import com.oneone.alert.sender.resp.FSUserResp;
|
||||||
|
import com.oneone.alert.service.EventService;
|
||||||
|
import com.oneone.common.result.Result;
|
||||||
|
import com.oneone.common.util.Func;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.velocity.Template;
|
||||||
|
import org.apache.velocity.VelocityContext;
|
||||||
|
import org.apache.velocity.app.Velocity;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static com.oneone.alert.common.FeishuConstants.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-04-20 12:20
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class FeishuSender implements BaseSender {
|
||||||
|
// @Value("${feishu.config.app_id:cli_a2d5cb988439500b}")
|
||||||
|
// private String app_id;
|
||||||
|
// @Value("${feishu.config.app_secret:G3WIWRns1BD5HyxJyfWpy6Sqo4LMyVYY}")
|
||||||
|
// private String app_secret;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
SenderProperties senderProperties;
|
||||||
|
|
||||||
|
private final String BEARER = "Bearer ";
|
||||||
|
|
||||||
|
private String accessToken;
|
||||||
|
|
||||||
|
private final LoadingCache<String, String> LOCAL_CACHE = CacheBuilder.newBuilder()
|
||||||
|
.maximumSize(20)
|
||||||
|
.expireAfterAccess(30, TimeUnit.MINUTES)
|
||||||
|
.build(
|
||||||
|
new CacheLoader<String,String>() {
|
||||||
|
@Override
|
||||||
|
public String load(String phone) {
|
||||||
|
return getUserIdByPhone(phone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private EventService eventService;
|
||||||
|
|
||||||
|
{
|
||||||
|
//设置velocity资源加载器
|
||||||
|
Properties prop = new Properties();
|
||||||
|
prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
|
||||||
|
Velocity.init(prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Async("asyncExecutor")
|
||||||
|
@Override
|
||||||
|
public void send(Event event) {
|
||||||
|
HttpRequest post = HttpUtil.createPost(BATCH_SEND);
|
||||||
|
post.header("Authorization", BEARER + accessToken);
|
||||||
|
String content = interactive(event);
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("msg_type", "interactive");
|
||||||
|
params.put("card", JSONObject.parseObject(content));
|
||||||
|
|
||||||
|
String users = event.getNotifyUser();
|
||||||
|
List<String> notifyUsers = new ArrayList<>();
|
||||||
|
List<String> phones=Arrays.asList(users.split(","));
|
||||||
|
for(String phone:phones){
|
||||||
|
String uid=LOCAL_CACHE.getUnchecked(phone);
|
||||||
|
if(Func.isEmpty(uid)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
notifyUsers.add(uid);
|
||||||
|
}
|
||||||
|
if(Func.isEmpty(notifyUsers)){
|
||||||
|
log.error("消息推送失败,未找到用户:{}",event.getNotifyUser());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
params.put("open_ids", notifyUsers);
|
||||||
|
post.body(JSONObject.toJSONString(params));
|
||||||
|
HttpResponse httpResponse = post.execute();
|
||||||
|
log.info("消息推送结果:{}",httpResponse.body());
|
||||||
|
Event update = new Event();
|
||||||
|
update.setId(event.getId());
|
||||||
|
update.setStatus(EventStatusEnum.SENT.getCode());
|
||||||
|
eventService.updateById(update);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FSUser> getUserIdByPhoneList(List<String> phones) {
|
||||||
|
HttpRequest post = HttpUtil.createPost(QUERY_UID);
|
||||||
|
post.header("Authorization", BEARER + accessToken);
|
||||||
|
if(Func.isEmpty(phones)){
|
||||||
|
return Collections.EMPTY_LIST;
|
||||||
|
}
|
||||||
|
HashMap params=new HashMap();
|
||||||
|
params.put("mobiles",phones);
|
||||||
|
post.body(JSONObject.toJSONString(params));
|
||||||
|
HttpResponse httpResponse = post.execute();
|
||||||
|
String result=httpResponse.body();
|
||||||
|
log.info("uid查询结果:{}",result);
|
||||||
|
Result<FSUserResp> r=JSONObject.parseObject(result,new TypeReference<Result<FSUserResp>>(){});
|
||||||
|
log.info(JSONObject.toJSONString(r));
|
||||||
|
if(!Result.isSuccess(r)){
|
||||||
|
log.info("uid查询失败");
|
||||||
|
return Collections.EMPTY_LIST;
|
||||||
|
}
|
||||||
|
return r.getData().getUser_list().stream().filter(s->!Func.isEmpty(s.getUser_id())).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserIdByPhone(String phone) {
|
||||||
|
HttpRequest post = HttpUtil.createPost(QUERY_UID);
|
||||||
|
post.header("Authorization", BEARER + accessToken);
|
||||||
|
if(Func.isEmpty(phone)){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
HashMap params=new HashMap();
|
||||||
|
params.put("mobiles",Arrays.asList(phone));
|
||||||
|
post.body(JSONObject.toJSONString(params));
|
||||||
|
HttpResponse httpResponse = post.execute();
|
||||||
|
String result=httpResponse.body();
|
||||||
|
log.info("uid查询结果:{}",result);
|
||||||
|
Result<FSUserResp> r=JSONObject.parseObject(result,new TypeReference<Result<FSUserResp>>(){});
|
||||||
|
log.info(JSONObject.toJSONString(r));
|
||||||
|
if(!Result.isSuccess(r)){
|
||||||
|
log.info("uid查询失败");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
List<FSUser> user_list=r.getData().getUser_list().stream().filter(s->Func.isNotEmpty(s.getUser_id())).collect(Collectors.toList());
|
||||||
|
if(Func.isEmpty(user_list)){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return user_list.get(0).getUser_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Scheduled(fixedDelay = 10000)
|
||||||
|
public void test() {
|
||||||
|
Event event = new Event();
|
||||||
|
event.setId(1l);
|
||||||
|
event.setApp("藏品服务");
|
||||||
|
event.setGmtCreate(LocalDateTime.now());
|
||||||
|
event.setLevel(1);
|
||||||
|
event.setTitle("库存不足");
|
||||||
|
event.setContent("藏品1库存不足");
|
||||||
|
event.setNotifyUser("[\"f622a54a:陈浩\"]");
|
||||||
|
HttpRequest post = HttpUtil.createPost(BATCH_SEND);
|
||||||
|
post.header("Authorization", BEARER + accessToken);
|
||||||
|
|
||||||
|
String content = interactive(event);
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("msg_type", "interactive");
|
||||||
|
params.put("card", JSONObject.parseObject(content));
|
||||||
|
|
||||||
|
String users = event.getNotifyUser();
|
||||||
|
List<String> notifyUsers = new ArrayList<>();
|
||||||
|
JSONArray.parseArray(users, String.class).forEach(s -> {
|
||||||
|
String[] userInfo = s.split(":");
|
||||||
|
String userId = userInfo[0];
|
||||||
|
notifyUsers.add(userId);
|
||||||
|
});
|
||||||
|
params.put("user_ids", notifyUsers);
|
||||||
|
|
||||||
|
post.body(JSONObject.toJSONString(params));
|
||||||
|
HttpResponse httpResponse = post.execute();
|
||||||
|
log.info(httpResponse.body());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String interactive(Event event) {
|
||||||
|
Map<String, Object> param = new HashMap<>();
|
||||||
|
param.put("title", event.getTitle());
|
||||||
|
param.put("app", event.getApp());
|
||||||
|
param.put("level", event.getLevel());
|
||||||
|
param.put("gmtCreate", LocalDateTimeUtil.formatNormal(event.getGmtCreate()));
|
||||||
|
param.put("id", event.getId());
|
||||||
|
|
||||||
|
String content = event.getContent().replaceAll("\"","\\\\\\\"");
|
||||||
|
param.put("content",content);
|
||||||
|
|
||||||
|
// String users = event.getNotifyUser();
|
||||||
|
// List<String> notifyUsers = new ArrayList<>();
|
||||||
|
// JSONArray.parseArray(users, String.class).forEach(s -> {
|
||||||
|
// String[] userInfo = s.split(":");
|
||||||
|
// String username = userInfo[1];
|
||||||
|
// notifyUsers.add(username);
|
||||||
|
// });
|
||||||
|
// param.put("notifyUsers", StringUtils.join(notifyUsers,','));
|
||||||
|
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
VelocityContext context = new VelocityContext(param);
|
||||||
|
Template tpl = Velocity.getTemplate("template/alert.json", "UTF-8");
|
||||||
|
tpl.merge(context, sw);
|
||||||
|
return sw.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scheduled(fixedDelay = 600000)
|
||||||
|
public void refreshToken() {
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
params.put("app_id", senderProperties.getAppId());
|
||||||
|
params.put("app_secret", senderProperties.getAppSecret());
|
||||||
|
String result = HttpUtil.post(LOGIN_URL, JSONObject.toJSONString(params));
|
||||||
|
log.info("飞书app_access_token:" + result);
|
||||||
|
JSONObject tokenObj = JSONObject.parseObject(result);
|
||||||
|
accessToken = tokenObj.getString("app_access_token");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
FeishuSender send=new FeishuSender();
|
||||||
|
|
||||||
|
Event event=new Event();
|
||||||
|
event.setTitle("Feishu");
|
||||||
|
event.setContent("ceshi");
|
||||||
|
event.setNotifyUser("18381357800");
|
||||||
|
event.setApp("app");
|
||||||
|
event.setLevel(1);
|
||||||
|
send.send(event);
|
||||||
|
// Map<String, Object> param = new HashMap<>();
|
||||||
|
// param.put("app", "test");
|
||||||
|
// param.put("level", 1);
|
||||||
|
// param.put("gmtCreate", LocalDateTime.now());
|
||||||
|
//
|
||||||
|
// StringWriter sw = new StringWriter();
|
||||||
|
// VelocityContext context = new VelocityContext(param);
|
||||||
|
// Template tpl = Velocity.getTemplate("template/alert.json", "UTF-8");
|
||||||
|
// tpl.merge(context, sw);
|
||||||
|
// System.out.println("模板文件渲染结果==> " + sw.toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.oneone.alert.sender.resp;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FSUser implements Serializable {
|
||||||
|
private String mobile;
|
||||||
|
private String user_id;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.oneone.alert.sender.resp;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FSUserResp implements Serializable {
|
||||||
|
private List<FSUser> user_list;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.oneone.alert.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.oneone.alert.pojo.entity.ActionData;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 数据收集表
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-05-09 16:58:58
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public interface ActionDataService extends IService<ActionData> {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.oneone.alert.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.oneone.alert.pojo.entity.AlertStage;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 通知策略
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-03-13 12:03:18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public interface AlertStageService extends IService<AlertStage> {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
package com.oneone.alert.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
import com.google.common.cache.LoadingCache;
|
||||||
|
import com.oneone.alert.pojo.dto.CodeStageRelDTO;
|
||||||
|
import com.oneone.alert.pojo.entity.CodeStageRel;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 通知策略-事件
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-03-13 12:03:18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public interface CodeStageRelService extends IService<CodeStageRel> {
|
||||||
|
|
||||||
|
|
||||||
|
CodeStageRelDTO getByCodeWithCache(String code);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.oneone.alert.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.oneone.alert.api.param.EventParam;
|
||||||
|
import com.oneone.alert.pojo.entity.EventLog;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 事件
|
||||||
|
* @author mice
|
||||||
|
* @date 2023-03-13 12:03:18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public interface EventLogService extends IService<EventLog> {
|
||||||
|
|
||||||
|
|
||||||
|
void saveLog(EventParam param);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.oneone.alert.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.oneone.alert.api.param.EventParam;
|
||||||
|
import com.oneone.alert.pojo.entity.Event;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 事件
|
||||||
|
* @author mice
|
||||||
|
* @date 2022-04-20 12:10:02
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public interface EventService extends IService<Event> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 推送事件
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
void pushEvent(EventParam event);
|
||||||
|
|
||||||
|
void saveAndPush(Event event);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
package com.oneone.alert.service.impl;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import java.util.Map;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
|
||||||
|
import com.oneone.alert.mapper.ActionDataMapper;
|
||||||
|
import com.oneone.alert.pojo.entity.ActionData;
|
||||||
|
import com.oneone.alert.service.ActionDataService;
|
||||||
|
|
||||||
|
|
||||||
|
@Service("actionDataService")
|
||||||
|
public class ActionDataServiceImpl extends ServiceImpl<ActionDataMapper, ActionData> implements ActionDataService {
|
||||||
|
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
package com.oneone.alert.service.impl;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import java.util.Map;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
|
||||||
|
import com.oneone.alert.mapper.AlertStageMapper;
|
||||||
|
import com.oneone.alert.pojo.entity.AlertStage;
|
||||||
|
import com.oneone.alert.service.AlertStageService;
|
||||||
|
|
||||||
|
|
||||||
|
@Service("alertStageService")
|
||||||
|
public class AlertStageServiceImpl extends ServiceImpl<AlertStageMapper, AlertStage> implements AlertStageService {
|
||||||
|
|
||||||
|
}
|
||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
package com.oneone.alert.service.impl;
|
||||||
|
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
import com.google.common.cache.LoadingCache;
|
||||||
|
import com.oneone.alert.api.common.AlterConstant;
|
||||||
|
import com.oneone.alert.pojo.dto.CodeStageRelDTO;
|
||||||
|
import com.oneone.alert.pojo.entity.AlertStage;
|
||||||
|
import com.oneone.alert.service.AlertStageService;
|
||||||
|
import com.oneone.common.constant.GlobalConstants;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
|
||||||
|
import com.oneone.alert.mapper.CodeStageRelMapper;
|
||||||
|
import com.oneone.alert.pojo.entity.CodeStageRel;
|
||||||
|
import com.oneone.alert.service.CodeStageRelService;
|
||||||
|
|
||||||
|
|
||||||
|
@Service("codeStageRelService")
|
||||||
|
public class CodeStageRelServiceImpl extends ServiceImpl<CodeStageRelMapper, CodeStageRel> implements CodeStageRelService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
AlertStageService alertStageService;
|
||||||
|
|
||||||
|
|
||||||
|
private final LoadingCache<String, CodeStageRelDTO> LOCAL_CACHE = CacheBuilder.newBuilder()
|
||||||
|
.maximumSize(512)
|
||||||
|
.expireAfterAccess(30, TimeUnit.MINUTES)
|
||||||
|
.build(
|
||||||
|
new CacheLoader<String, CodeStageRelDTO>() {
|
||||||
|
@Override
|
||||||
|
public CodeStageRelDTO load(String code) {
|
||||||
|
return getByCode(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
private CodeStageRelDTO getByCode(String code){
|
||||||
|
CodeStageRel one = this.lambdaQuery().eq(CodeStageRel::getCode, code).one();
|
||||||
|
if(one==null){
|
||||||
|
AlertStage stage = alertStageService.lambdaQuery().eq(AlertStage::getIsDefault, GlobalConstants.STATUS_YES )
|
||||||
|
.one();
|
||||||
|
if(stage==null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
CodeStageRelDTO dto=new CodeStageRelDTO();
|
||||||
|
dto.setStage(stage);
|
||||||
|
dto.setCode(code);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
CodeStageRelDTO dto=new CodeStageRelDTO();
|
||||||
|
BeanUtils.copyProperties(one, dto);
|
||||||
|
AlertStage stage = alertStageService.getById(dto.getStageId());
|
||||||
|
|
||||||
|
|
||||||
|
if(stage==null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
dto.setStage(stage);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodeStageRelDTO getByCodeWithCache(String code) {
|
||||||
|
return LOCAL_CACHE.getUnchecked(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
package com.oneone.alert.service.impl;
|
||||||
|
|
||||||
|
import com.oneone.alert.api.common.AlterConstant;
|
||||||
|
import com.oneone.alert.api.param.EventParam;
|
||||||
|
import com.oneone.alert.pojo.dto.CodeStageRelDTO;
|
||||||
|
import com.oneone.alert.pojo.entity.AlertStage;
|
||||||
|
import com.oneone.alert.pojo.entity.Event;
|
||||||
|
import com.oneone.alert.service.CodeStageRelService;
|
||||||
|
import com.oneone.alert.service.EventService;
|
||||||
|
import com.oneone.common.util.Func;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import java.util.Map;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
|
||||||
|
import com.oneone.alert.mapper.EventLogMapper;
|
||||||
|
import com.oneone.alert.pojo.entity.EventLog;
|
||||||
|
import com.oneone.alert.service.EventLogService;
|
||||||
|
|
||||||
|
|
||||||
|
@Service("eventLogService")
|
||||||
|
public class EventLogServiceImpl extends ServiceImpl<EventLogMapper, EventLog> implements EventLogService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
EventService eventService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
CodeStageRelService codeStageRelService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveLog(EventParam param) {
|
||||||
|
EventLog log =new EventLog();
|
||||||
|
BeanUtils.copyProperties(param,log);
|
||||||
|
this.save(log);
|
||||||
|
if(Func.isNotEmpty(param.getNotifyUser())){
|
||||||
|
Event event=new Event();
|
||||||
|
BeanUtils.copyProperties(param,event);
|
||||||
|
event.setLogId(log.getId());
|
||||||
|
eventService.saveAndPush(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
saveAndPushWithStage(log,param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Async("asyncExecutor")
|
||||||
|
public void saveAndPushWithStage(EventLog log,EventParam param){
|
||||||
|
String code=log.getCode();
|
||||||
|
if(Func.isEmpty(code)){
|
||||||
|
code= AlterConstant.BusyCode.UNKNOWN.getCode();
|
||||||
|
}
|
||||||
|
CodeStageRelDTO codeState = codeStageRelService.getByCodeWithCache(code);
|
||||||
|
if(codeState==null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AlertStage stage=codeState.getStage();
|
||||||
|
if(stage.getNum()>0){
|
||||||
|
int count=baseMapper.getInTimeCount(stage.getTimeMinute(),code);
|
||||||
|
if(count<stage.getNum()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event event=new Event();
|
||||||
|
BeanUtils.copyProperties(param,event);
|
||||||
|
event.setLogId(log.getId());
|
||||||
|
event.setNotifyUser(stage.getNotifyPhone());
|
||||||
|
event.setStageId(stage.getId());
|
||||||
|
if(Func.isEmpty(param.getTitle()) ){
|
||||||
|
event.setTitle(codeState.getTitle());
|
||||||
|
}
|
||||||
|
if(Func.isEmpty(param.getApp()) ) {
|
||||||
|
event.setApp(codeState.getApp());
|
||||||
|
}
|
||||||
|
event.setLevel(stage.getLevel());
|
||||||
|
eventService.saveAndPush(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
package com.oneone.alert.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.oneone.alert.api.param.EventParam;
|
||||||
|
import com.oneone.alert.mapper.EventMapper;
|
||||||
|
import com.oneone.alert.pojo.entity.Event;
|
||||||
|
import com.oneone.alert.sender.BaseSender;
|
||||||
|
import com.oneone.alert.service.EventService;
|
||||||
|
import com.oneone.common.util.JsonUtils;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
|
||||||
|
@Service("eventService")
|
||||||
|
@Slf4j
|
||||||
|
public class EventServiceImpl extends ServiceImpl<EventMapper, Event> implements EventService {
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private BaseSender sender;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pushEvent(EventParam eventParam){
|
||||||
|
Event event = new Event();
|
||||||
|
BeanUtils.copyProperties(eventParam,event);
|
||||||
|
// TODO 告警人配置
|
||||||
|
event.setNotifyUser("[\"f622a54a:陈浩\"]");
|
||||||
|
event.setGmtCreate(LocalDateTime.now());
|
||||||
|
baseMapper.insert(event);
|
||||||
|
log.info("接收到推送消息:{}", JsonUtils.toJSONString(eventParam));
|
||||||
|
sender.send(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Async("asyncExecutor")
|
||||||
|
@Override
|
||||||
|
public void saveAndPush(Event event) {
|
||||||
|
baseMapper.insert(event);
|
||||||
|
if(event.getGmtCreate()==null){
|
||||||
|
event.setGmtCreate(LocalDateTime.now());
|
||||||
|
}
|
||||||
|
sender.send(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"template": "red",
|
||||||
|
"title": {
|
||||||
|
"content": "${level}级报警 - 告警平台",
|
||||||
|
"tag": "plain_text"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"is_short": false,
|
||||||
|
"text": {
|
||||||
|
"content": "📋 项目:${app}",
|
||||||
|
"tag": "lark_md"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_short": false,
|
||||||
|
"text": {
|
||||||
|
"content": "🕐 时间:${gmtCreate}",
|
||||||
|
"tag": "lark_md"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_short": false,
|
||||||
|
"text": {
|
||||||
|
"content": "🔢 事件 ID:${id}",
|
||||||
|
"tag": "lark_md"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"is_short": false,
|
||||||
|
"text": {
|
||||||
|
"content": "告警内容:",
|
||||||
|
"tag": "lark_md"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tag": "div"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"tag": "div",
|
||||||
|
"text": {
|
||||||
|
"content": "**${content}**",
|
||||||
|
"tag": "lark_md"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tag": "note"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"tag": "button",
|
||||||
|
"text": {
|
||||||
|
"content": "跟进处理",
|
||||||
|
"tag": "plain_text"
|
||||||
|
},
|
||||||
|
"type": "primary",
|
||||||
|
"value": {
|
||||||
|
"key1": "value1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"text": {
|
||||||
|
"content": "屏蔽10分钟",
|
||||||
|
"tag": "plain_text"
|
||||||
|
},
|
||||||
|
"value": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": {
|
||||||
|
"content": "屏蔽30分钟",
|
||||||
|
"tag": "plain_text"
|
||||||
|
},
|
||||||
|
"value": "2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": {
|
||||||
|
"content": "屏蔽1小时",
|
||||||
|
"tag": "plain_text"
|
||||||
|
},
|
||||||
|
"value": "3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": {
|
||||||
|
"content": "屏蔽24小时",
|
||||||
|
"tag": "plain_text"
|
||||||
|
},
|
||||||
|
"value": "4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"placeholder": {
|
||||||
|
"content": "暂时屏蔽报警",
|
||||||
|
"tag": "plain_text"
|
||||||
|
},
|
||||||
|
"tag": "select_static",
|
||||||
|
"value": {
|
||||||
|
"key": "value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tag": "action"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
server:
|
||||||
|
port: 8901
|
||||||
|
|
||||||
|
spring:
|
||||||
|
mvc:
|
||||||
|
pathmatch:
|
||||||
|
matching-strategy: ant_path_matcher
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
# 注册中心
|
||||||
|
discovery:
|
||||||
|
server-addr: http://192.168.100.151:8848
|
||||||
|
namespace: d2010a44-0999-4b45-9af8-2a0f028a97c3
|
||||||
|
# 配置中心
|
||||||
|
config:
|
||||||
|
server-addr: http://192.168.100.151:8848
|
||||||
|
file-extension: yaml
|
||||||
|
shared-configs[0]:
|
||||||
|
data-id: oneone-common.yaml
|
||||||
|
refresh: true
|
||||||
|
namespace: d2010a44-0999-4b45-9af8-2a0f028a97c3
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
server:
|
||||||
|
port: 8901
|
||||||
|
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
# 注册中心
|
||||||
|
discovery:
|
||||||
|
server-addr: ${spring.cloud.nacos.discovery.server-addr}
|
||||||
|
# 配置中心
|
||||||
|
config:
|
||||||
|
server-addr: ${spring.cloud.nacos.discovery.server-addr}
|
||||||
|
file-extension: yaml
|
||||||
|
shared-configs[0]:
|
||||||
|
data-id: oneone-common.yaml
|
||||||
|
refresh: true
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
server:
|
||||||
|
port: 8901
|
||||||
|
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
# 注册中心
|
||||||
|
discovery:
|
||||||
|
server-addr: ${spring.cloud.nacos.discovery.server-addr}
|
||||||
|
# 配置中心
|
||||||
|
config:
|
||||||
|
server-addr: ${spring.cloud.nacos.discovery.server-addr}
|
||||||
|
file-extension: yaml
|
||||||
|
shared-configs[0]:
|
||||||
|
data-id: oneone-common.yaml
|
||||||
|
refresh: true
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: oneone-alert
|
||||||
|
profiles:
|
||||||
|
active: dev
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"template": "red",
|
||||||
|
"title": {
|
||||||
|
"content": "${level}级-${title}",
|
||||||
|
"tag": "plain_text"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"is_short": false,
|
||||||
|
"text": {
|
||||||
|
"content": "📋 项目:${app}",
|
||||||
|
"tag": "lark_md"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_short": false,
|
||||||
|
"text": {
|
||||||
|
"content": "🕐 时间:${gmtCreate}",
|
||||||
|
"tag": "lark_md"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_short": false,
|
||||||
|
"text": {
|
||||||
|
"content": "🔢 事件 ID:${id}",
|
||||||
|
"tag": "lark_md"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_short": false,
|
||||||
|
"text": {
|
||||||
|
"content": "**告警内容:**\n**${content}**",
|
||||||
|
"tag": "lark_md"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tag": "div"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"tag": "button",
|
||||||
|
"text": {
|
||||||
|
"content": "跟进处理",
|
||||||
|
"tag": "plain_text"
|
||||||
|
},
|
||||||
|
"type": "primary",
|
||||||
|
"value": {
|
||||||
|
"key1": "value1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"text": {
|
||||||
|
"content": "屏蔽10分钟",
|
||||||
|
"tag": "plain_text"
|
||||||
|
},
|
||||||
|
"value": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": {
|
||||||
|
"content": "屏蔽30分钟",
|
||||||
|
"tag": "plain_text"
|
||||||
|
},
|
||||||
|
"value": "2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": {
|
||||||
|
"content": "屏蔽1小时",
|
||||||
|
"tag": "plain_text"
|
||||||
|
},
|
||||||
|
"value": "3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": {
|
||||||
|
"content": "屏蔽24小时",
|
||||||
|
"tag": "plain_text"
|
||||||
|
},
|
||||||
|
"value": "4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"placeholder": {
|
||||||
|
"content": "暂时屏蔽报警",
|
||||||
|
"tag": "plain_text"
|
||||||
|
},
|
||||||
|
"tag": "select_static",
|
||||||
|
"value": {
|
||||||
|
"key": "value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tag": "action"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>oneone-cloud</artifactId>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>oneone-alert</artifactId>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
|
||||||
|
<module>alert-api</module>
|
||||||
|
<module>alert-boot</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
FROM openjdk:8-jre
|
||||||
|
MAINTAINER oneone oneonetech@163.com
|
||||||
|
|
||||||
|
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \&& echo 'Asia/Shanghai' >/etc/timezone
|
||||||
|
|
||||||
|
# /tmp 目录作为容器数据卷目录,SpringBoot内嵌Tomcat容器默认使用/tmp作为工作目录,任何向 /tmp 中写入的信息不会记录进容器存储层,从而保证容器存储层的无状态化
|
||||||
|
# 在宿主机的/var/lib/docker目录下创建一个临时文件并把它链接到容器中的/tmp目录
|
||||||
|
VOLUME /tmp
|
||||||
|
|
||||||
|
# 复制jar到镜像
|
||||||
|
ADD target/oneone-auth.jar app.jar
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "-Xmx128m", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"]
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>oneone-cloud</artifactId>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>oneone-auth</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!--Spring Cloud & Alibaba -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 注册中心 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 配置中心 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<artifactId>common-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<artifactId>common-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.binarywang</groupId>
|
||||||
|
<artifactId>weixin-java-miniapp</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>me.zhyd.oauth</groupId>
|
||||||
|
<artifactId>JustAuth</artifactId>
|
||||||
|
<version>1.16.5</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<artifactId>common-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Web 相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springdoc</groupId>
|
||||||
|
<artifactId>springdoc-openapi-ui</artifactId>
|
||||||
|
<scope>provided</scope> <!-- 设置为 provided,主要是 PageParam 使用到 -->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- fegin api 相关 -->
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<artifactId>common-sms</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.auth0</groupId>
|
||||||
|
<artifactId>jwks-rsa</artifactId>
|
||||||
|
<version>0.9.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt</artifactId>
|
||||||
|
<version>0.9.1</version>
|
||||||
|
</dependency>
|
||||||
|
<!--kafka-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.kafka</groupId>
|
||||||
|
<artifactId>spring-kafka</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alipay.sdk</groupId>
|
||||||
|
<artifactId>alipay-sdk-java</artifactId>
|
||||||
|
<version>4.22.113.ALL</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<artifactId>alert-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oneone.cloud</groupId>
|
||||||
|
<artifactId>oneone-pms-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<!-- 设置构建的 jar 包名 -->
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<!-- 打包 -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<version>${spring.boot.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.oneone.auth;
|
||||||
|
|
||||||
|
import com.oneone.alert.api.feign.AlertFeignClient;
|
||||||
|
import com.oneone.pms.api.account.IPlatformAccountApi;
|
||||||
|
import com.oneone.pms.api.loginconfig.IThirdLoginConfigApi;
|
||||||
|
import com.oneone.upms.api.permission.PermissionApi;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||||
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
|
|
||||||
|
@EnableFeignClients(basePackageClasses = {IPlatformAccountApi.class, AlertFeignClient.class
|
||||||
|
, IThirdLoginConfigApi.class , PermissionApi.class})
|
||||||
|
@EnableDiscoveryClient
|
||||||
|
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
|
||||||
|
public class AuthApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(AuthApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package com.oneone.auth.common;
|
||||||
|
|
||||||
|
import com.oneone.common.exception.BusinessException;
|
||||||
|
import com.oneone.common.result.Result;
|
||||||
|
import com.oneone.pms.api.loginconfig.IThirdLoginConfigApi;
|
||||||
|
import com.oneone.pms.api.loginconfig.dto.AppThirdLoginDTO;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class AppThirdLoginConfigInfo {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IThirdLoginConfigApi thirdLoginConfigApi;
|
||||||
|
|
||||||
|
private static final String SEPARATOR="!-_-!";
|
||||||
|
|
||||||
|
private HashMap<String, AppThirdLoginDTO> LOCAL_CACHE_DOWN = new HashMap();
|
||||||
|
|
||||||
|
private Long minute=1000*60L;
|
||||||
|
|
||||||
|
public AppThirdLoginDTO getLoginConfigWithCache( String type){
|
||||||
|
AppThirdLoginDTO dto=LOCAL_CACHE_DOWN.get(type);
|
||||||
|
if(dto==null|| dto.getLastUpdateTime()+5*minute<System.currentTimeMillis()){
|
||||||
|
dto=getConfig(type);
|
||||||
|
if(dto==null){
|
||||||
|
dto=new AppThirdLoginDTO();
|
||||||
|
dto.setLastUpdateTime(System.currentTimeMillis());
|
||||||
|
LOCAL_CACHE_DOWN.put(type,dto);
|
||||||
|
throw new BusinessException("登录失败,请稍后再试");
|
||||||
|
}else{
|
||||||
|
dto.setLastUpdateTime(System.currentTimeMillis());
|
||||||
|
LOCAL_CACHE_DOWN.put(type,dto);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(dto.getThirdAppId()==null){
|
||||||
|
throw new BusinessException("登录失败,请稍后再试");
|
||||||
|
}
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
public AppThirdLoginDTO getLoginConfig(String type){
|
||||||
|
AppThirdLoginDTO dto=getConfig(type);
|
||||||
|
if(dto==null){
|
||||||
|
throw new BusinessException("登录失败,请稍后再试");
|
||||||
|
}
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AppThirdLoginDTO getConfig(String type){
|
||||||
|
Result<AppThirdLoginDTO> result = thirdLoginConfigApi.thirdLoginConfig(type);
|
||||||
|
if ( result == null || !Result.isSuccess(result) ) {
|
||||||
|
throw new BusinessException("登录失败,请稍后再试");
|
||||||
|
}
|
||||||
|
AppThirdLoginDTO dto=result.getData();
|
||||||
|
if(dto==null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void freshCache() {
|
||||||
|
LOCAL_CACHE_DOWN.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.oneone.auth.common;
|
||||||
|
|
||||||
|
import com.google.common.hash.Hashing;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密
|
||||||
|
*/
|
||||||
|
public class CryptalUtil {
|
||||||
|
|
||||||
|
private static final String MAC_NAME = "HmacSHA1";
|
||||||
|
private static final String ENCODING = "UTF-8";
|
||||||
|
|
||||||
|
public static byte[] HmacSHA1Encrypt(String encryptText,String encryptKey) throws Exception {
|
||||||
|
byte[] data = encryptKey.getBytes(ENCODING);
|
||||||
|
//根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
|
||||||
|
SecretKey secretKey = new SecretKeySpec(data,MAC_NAME);
|
||||||
|
//生成一个指定 Mac 算法 的 Mac 对象
|
||||||
|
Mac mac =Mac.getInstance(MAC_NAME);
|
||||||
|
//用给定密钥初始化 Mac 对象
|
||||||
|
mac.init(secretKey);
|
||||||
|
byte[] text = encryptText.getBytes(ENCODING);
|
||||||
|
return mac.doFinal(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String hash_hmac(String encryptText,String encryptKey) throws Exception{
|
||||||
|
byte[] bytes = HmacSHA1Encrypt(encryptText,encryptKey);
|
||||||
|
return Base64.getEncoder().encodeToString(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String md5(String str){
|
||||||
|
return Hashing.md5().hashString(str, Charset.forName("UTF-8")).toString().toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.oneone.auth.common.ali;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2023-03-15 11:44
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "alipay")
|
||||||
|
public class AliProperty {
|
||||||
|
private String appId;
|
||||||
|
private String privateKey;
|
||||||
|
private String publicKey;
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package com.oneone.auth.common.ali;
|
||||||
|
|
||||||
|
import com.alipay.api.AlipayApiException;
|
||||||
|
import com.alipay.api.AlipayClient;
|
||||||
|
import com.alipay.api.DefaultAlipayClient;
|
||||||
|
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
|
||||||
|
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
|
||||||
|
import com.oneone.auth.common.AppThirdLoginConfigInfo;
|
||||||
|
import com.oneone.auth.common.enums.GrantTypeEnum;
|
||||||
|
import com.oneone.common.exception.BusinessException;
|
||||||
|
import com.oneone.pms.api.loginconfig.dto.AppThirdLoginDTO;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2023-03-15 11:43
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class AliUtil {
|
||||||
|
|
||||||
|
// private final AliProperty aliProperty;
|
||||||
|
@Autowired
|
||||||
|
private AppThirdLoginConfigInfo appThirdLoginConfigInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 授权码登录
|
||||||
|
* @param code
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public AlipaySystemOauthTokenResponse login(String code){
|
||||||
|
|
||||||
|
AppThirdLoginDTO aliProperty=appThirdLoginConfigInfo.getLoginConfigWithCache( GrantTypeEnum.ALIPAY.getCode());
|
||||||
|
|
||||||
|
|
||||||
|
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",aliProperty.getThirdAppId(),aliProperty.getPrivateKey(),"json","GBK",aliProperty.getPublicKey(),"RSA2");
|
||||||
|
|
||||||
|
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
|
||||||
|
request.setGrantType("authorization_code");
|
||||||
|
request.setCode(code);
|
||||||
|
AlipaySystemOauthTokenResponse response = null;
|
||||||
|
try {
|
||||||
|
response = alipayClient.execute(request);
|
||||||
|
} catch (AlipayApiException e) {
|
||||||
|
log.error("调用阿里授权API失败:{},{}",e.getErrCode(),e.getErrMsg());
|
||||||
|
throw new BusinessException("登录失败,请稍后再试");
|
||||||
|
}
|
||||||
|
if(response.isSuccess()){
|
||||||
|
return response;
|
||||||
|
} else {
|
||||||
|
log.error("调用阿里授权API失败:{},{}",response.getCode());
|
||||||
|
throw new BusinessException("登录失败,请稍后再试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
package com.oneone.auth.common.apple;
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import cn.hutool.jwt.JWT;
|
||||||
|
import cn.hutool.jwt.JWTUtil;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.auth0.jwk.Jwk;
|
||||||
|
import io.jsonwebtoken.*;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.security.PublicKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-06-13 11:44
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Slf4j
|
||||||
|
public class AppleUtil {
|
||||||
|
|
||||||
|
private static final String AUTH_KEYS_URL = "https://appleid.apple.com/auth/keys";
|
||||||
|
private static final String APPLE_ID_URL = "https://appleid.apple.com";
|
||||||
|
|
||||||
|
|
||||||
|
public static String validateToken(String token){
|
||||||
|
JWT jwt = JWTUtil.parseToken(token);
|
||||||
|
String kid = jwt.getHeader().getClaimsJson().get("kid").toString();
|
||||||
|
cn.hutool.json.JSONObject jsonObject = jwt.getPayload().getClaimsJson();
|
||||||
|
String aud = jsonObject.get("aud").toString();
|
||||||
|
String sub = jsonObject.get("sub").toString();
|
||||||
|
boolean isSuccess = verifyToken(token , kid, aud, sub);
|
||||||
|
if (isSuccess){
|
||||||
|
return sub;
|
||||||
|
}else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean verifyToken(String identityToken, String kid, String aud, String sub) {
|
||||||
|
PublicKey publicKey = getPublicKey(kid);
|
||||||
|
JwtParser jwtParser = Jwts.parser().setSigningKey(publicKey);
|
||||||
|
jwtParser.requireIssuer(APPLE_ID_URL);
|
||||||
|
jwtParser.requireAudience(aud);
|
||||||
|
jwtParser.requireSubject(sub);
|
||||||
|
try {
|
||||||
|
Jws<Claims> claim = jwtParser.parseClaimsJws(identityToken);
|
||||||
|
if (claim != null && claim.getBody().containsKey("auth_time")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} catch (ExpiredJwtException e) {
|
||||||
|
log.error("苹果登陆授权 idToken 已过期", e);
|
||||||
|
return false;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("非法的苹果登陆授权 idToken", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过kid查找苹果中获取对应的PublicKey
|
||||||
|
* @param kid
|
||||||
|
* @return 构造好的公钥
|
||||||
|
*/
|
||||||
|
private static PublicKey getPublicKey(String kid) {
|
||||||
|
try {
|
||||||
|
JSONArray jsonArray = getAuthKeys();
|
||||||
|
if (jsonArray.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (Object object : jsonArray) {
|
||||||
|
JSONObject json= (JSONObject) JSONObject.toJSON(object);
|
||||||
|
if (json.getString("kid").equals(kid)) {
|
||||||
|
json= (JSONObject) JSONObject.toJSON(object);
|
||||||
|
Jwk jwa = Jwk.fromValues(json);
|
||||||
|
return jwa.getPublicKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("apple getPublicKey error", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取苹果的公钥
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static JSONArray getAuthKeys() {
|
||||||
|
String result = HttpUtil.get(AUTH_KEYS_URL);
|
||||||
|
JSONObject json = JSONObject.parseObject(result);
|
||||||
|
return json != null ? json.getJSONArray("keys") : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.oneone.auth.common.enums;
|
||||||
|
|
||||||
|
|
||||||
|
import com.oneone.common.exception.ErrorCode;
|
||||||
|
|
||||||
|
public interface ErrorCodeConstants {
|
||||||
|
ErrorCode USER_LOGIN_ERROR = new ErrorCode(1_004_001_001, "用户登录异常");
|
||||||
|
ErrorCode USER_NOT_EXIST = new ErrorCode(1_004_001_002, "用户不存在");
|
||||||
|
ErrorCode USER_ACCOUNT_LOCKED = new ErrorCode(1_004_001_003, "用户账户被冻结");
|
||||||
|
ErrorCode USER_ACCOUNT_INVALID = new ErrorCode(1_004_001_004, "用户账户已作废");
|
||||||
|
ErrorCode USER_EXIST = new ErrorCode(1_004_001_005, "账号已存在");
|
||||||
|
|
||||||
|
ErrorCode USERNAME_OR_PASSWORD_ERROR = new ErrorCode(1_004_001_006, "用户名或密码错误");
|
||||||
|
ErrorCode PASSWORD_ENTER_EXCEED_LIMIT = new ErrorCode(1_004_001_007, "用户输入密码次数超限");
|
||||||
|
ErrorCode CLIENT_AUTHENTICATION_FAILED = new ErrorCode(1_004_001_008, "客户端认证失败");
|
||||||
|
ErrorCode TOKEN_INVALID_OR_EXPIRED = new ErrorCode(1_004_001_009, "token无效或已过期");
|
||||||
|
ErrorCode TOKEN_ACCESS_FORBIDDEN = new ErrorCode(1_004_001_010, "token已被禁止访问");
|
||||||
|
ErrorCode AUTHORIZED_ERROR = new ErrorCode(1_004_001_011, "访问权限异常");
|
||||||
|
|
||||||
|
ErrorCode USER_HAS_BAND_ERROR = new ErrorCode(1_004_001_002, "用户已绑定该登录方式");
|
||||||
|
|
||||||
|
ErrorCode GRANT_TYPE_HAS_BAND_ERROR = new ErrorCode(1_004_001_003, "登录方式已被其他账号绑定");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.oneone.auth.common.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author oneone
|
||||||
|
* @description
|
||||||
|
* @createTime 2021/6/5 17:57
|
||||||
|
*/
|
||||||
|
|
||||||
|
public enum GrantTypeEnum {
|
||||||
|
|
||||||
|
REFRESH("refresh","刷新token"),
|
||||||
|
SMS_CODE("sms_code","短信验证码登录"),
|
||||||
|
WECHAT("wechat","微信登录"),
|
||||||
|
WECHAT_CODE("wechatCode","微信登录授权码"),
|
||||||
|
MINI_APP("mini_app","微信小程序"),
|
||||||
|
OFFICIAL_ACCOUNT("official_account","公众号"),
|
||||||
|
APPLE_JWT("apple","苹果jwt"),
|
||||||
|
USERNAME("username","账号"),
|
||||||
|
EMAIL("email","邮件"),
|
||||||
|
TWITTER("twitter","twitter"),
|
||||||
|
ALIPAY("alipay","支付吧"),
|
||||||
|
DEVICE("device","设备号,游客登录"),
|
||||||
|
FACEBOOK("facebook","脸书登录"),
|
||||||
|
GOOGLE("google","谷歌登录"),
|
||||||
|
;
|
||||||
|
|
||||||
|
public static GrantTypeEnum getByCode(String code){
|
||||||
|
for (GrantTypeEnum value : values()) {
|
||||||
|
if (value.getCode().equals(code)){
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private String code;
|
||||||
|
@Getter
|
||||||
|
private String desc;
|
||||||
|
|
||||||
|
GrantTypeEnum(String code, String desc){
|
||||||
|
this.code = code;
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.oneone.auth.common.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author oneone
|
||||||
|
* @description TODO
|
||||||
|
* @createTime 2021/6/5 17:57
|
||||||
|
*/
|
||||||
|
|
||||||
|
public enum PasswordEncoderTypeEnum {
|
||||||
|
|
||||||
|
BCRYPT("{bcrypt}","BCRYPT加密"),
|
||||||
|
NOOP("{noop}","无加密明文");
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private String prefix;
|
||||||
|
|
||||||
|
PasswordEncoderTypeEnum(String prefix, String desc){
|
||||||
|
this.prefix=prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.oneone.auth.common.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author oneone
|
||||||
|
* @description
|
||||||
|
* @createTime 2021/6/5 17:57
|
||||||
|
*/
|
||||||
|
|
||||||
|
public enum WechatLoginTypeEnum {
|
||||||
|
|
||||||
|
CLIENT_CREDENTIAL("client_credential","客户端凭证"),
|
||||||
|
AUTHORIZATION_CODE("authorization_code","授权码");
|
||||||
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private String code;
|
||||||
|
@Getter
|
||||||
|
private String desc;
|
||||||
|
|
||||||
|
WechatLoginTypeEnum(String code,String desc){
|
||||||
|
this.code = code;
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
package com.oneone.auth.common.twitter;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.RandomUtil;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.oneone.auth.common.AppThirdLoginConfigInfo;
|
||||||
|
import com.oneone.auth.common.CryptalUtil;
|
||||||
|
import com.oneone.auth.common.enums.GrantTypeEnum;
|
||||||
|
import com.oneone.common.web.util.HttpClientUtil;
|
||||||
|
import com.oneone.pms.api.loginconfig.dto.AppThirdLoginDTO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-10-06 20:47
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@ConditionalOnProperty(name = "login.twitter.enabled")
|
||||||
|
public class TwitterUtil {
|
||||||
|
// @Value("${login.twitter.consumer-key}")
|
||||||
|
// private String consumerKey;
|
||||||
|
// @Value("${login.twitter.consumer-secret}")
|
||||||
|
// private String consumerSecret;
|
||||||
|
@Autowired
|
||||||
|
private HttpClientUtil httpClientUtil;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AppThirdLoginConfigInfo appThirdLoginConfigInfo;
|
||||||
|
|
||||||
|
private final String TW_URL = "https://api.twitter.com/1.1/account/verify_credentials.json";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测twitter的登录
|
||||||
|
* @param accessToken
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String checkTwitterToken(String accessToken,String accessTokenSecret){
|
||||||
|
AppThirdLoginDTO configDTO=appThirdLoginConfigInfo.getLoginConfigWithCache(GrantTypeEnum.TWITTER.getCode());
|
||||||
|
String consumerKey=configDTO.getThirdAppId();
|
||||||
|
String consumerSecret=configDTO.getPrivateKey();
|
||||||
|
|
||||||
|
String oauth_nonce = RandomUtil.randomString(42);
|
||||||
|
long oauth_timestamp = System.currentTimeMillis() / 1000;
|
||||||
|
String signingKey = consumerSecret + "&" + accessTokenSecret;
|
||||||
|
StringBuilder signatrueBaseStr = new StringBuilder();
|
||||||
|
String oauth_signature = null;
|
||||||
|
StringBuilder paramStr = new StringBuilder();
|
||||||
|
paramStr.append("oauth_consumer_key=").append(consumerKey)
|
||||||
|
.append("&oauth_nonce=").append(oauth_nonce)
|
||||||
|
.append("&oauth_signature_method=HMAC-SHA1")
|
||||||
|
.append("&oauth_timestamp=").append(oauth_timestamp)
|
||||||
|
.append("&oauth_token=").append(accessToken)
|
||||||
|
.append("&oauth_version=1.0");
|
||||||
|
try {
|
||||||
|
signatrueBaseStr.append("GET&").append(URLEncoder.encode(TW_URL,"UTF-8"))
|
||||||
|
.append("&").append(URLEncoder.encode(paramStr.toString(),"UTF-8"));
|
||||||
|
oauth_signature = CryptalUtil.hash_hmac(signatrueBaseStr.toString(), signingKey);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Map<String,Object> headMap = Maps.newHashMap();
|
||||||
|
StringBuilder headParam = new StringBuilder();
|
||||||
|
headParam.append("OAuth oauth_consumer_key=\"").append(consumerKey).append("\", ")
|
||||||
|
.append("oauth_nonce=\"").append(oauth_nonce).append("\", ")
|
||||||
|
.append("oauth_signature=\"").append(URLEncoder.encode(oauth_signature,"UTF-8")).append("\", ")
|
||||||
|
.append("oauth_signature_method=\"HMAC-SHA1\", ")
|
||||||
|
.append("oauth_timestamp=\"").append(oauth_timestamp).append("\", ")
|
||||||
|
.append("oauth_token=\"").append(accessToken).append("\", ")
|
||||||
|
.append("oauth_version=\"1.0\"");
|
||||||
|
headMap.put("Authorization",headParam.toString());
|
||||||
|
Map<String,Object> paramMap = Maps.newHashMap();
|
||||||
|
String result = httpClientUtil.doGet(TW_URL, headMap,paramMap);
|
||||||
|
if(!Strings.isNullOrEmpty(result)){
|
||||||
|
JSONObject jsonObject = JSON.parseObject(result);
|
||||||
|
String id = jsonObject.getString("id");
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("checkTwitterToken is error : ",e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.oneone.auth.common.wechat;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class MiniAppParam implements Serializable {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String encryptedData;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String iv;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.oneone.auth.common.wechat;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class OfficialAccountParam implements Serializable {
|
||||||
|
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
private String validateCode;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
private String openId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.oneone.auth.common.wechat;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2023-03-15 11:44
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "wechat.app")
|
||||||
|
public class WechatProperty {
|
||||||
|
private String appId;
|
||||||
|
private String appSecret;
|
||||||
|
private String miniAppId;
|
||||||
|
private String miniAppSecret;
|
||||||
|
private String officialAccountAppId;
|
||||||
|
private String officialAccountAppSecret;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.oneone.auth.common.wechat;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2023-03-15 13:59
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class WechatToken {
|
||||||
|
//{
|
||||||
|
//
|
||||||
|
// "access_token":"ACCESS_TOKEN",
|
||||||
|
//
|
||||||
|
// "expires_in":7200,
|
||||||
|
//
|
||||||
|
// "refresh_token":"REFRESH_TOKEN",
|
||||||
|
//
|
||||||
|
// "openid":"OPENID",
|
||||||
|
//
|
||||||
|
// "scope":"SCOPE"
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
private String accessToken;
|
||||||
|
private String openId;
|
||||||
|
private String sessionKey;
|
||||||
|
private String unionId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
package com.oneone.auth.common.wechat;
|
||||||
|
|
||||||
|
import cn.binarywang.wx.miniapp.api.WxMaService;
|
||||||
|
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
|
||||||
|
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
|
||||||
|
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
|
||||||
|
import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils;
|
||||||
|
import cn.hutool.core.codec.Base64;
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.oneone.auth.common.AppThirdLoginConfigInfo;
|
||||||
|
import com.oneone.auth.common.enums.GrantTypeEnum;
|
||||||
|
import com.oneone.auth.config.WechatUserInfo;
|
||||||
|
import com.oneone.pms.api.loginconfig.dto.AppThirdLoginDTO;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.spec.AlgorithmParameterSpec;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class WechatUtil {
|
||||||
|
// @Autowired
|
||||||
|
// private WechatProperty wechatProperty;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AppThirdLoginConfigInfo appThirdLoginConfigInfo;
|
||||||
|
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(WechatUtil.class);
|
||||||
|
|
||||||
|
public WechatUserInfo getUserInfo(String code) {
|
||||||
|
try {
|
||||||
|
WechatToken wechatToken = getOauth2AccessToken( code);
|
||||||
|
|
||||||
|
// 拼接请求地址
|
||||||
|
String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
|
||||||
|
logger.info("微信用户信息接口返回:{}",requestUrl);
|
||||||
|
|
||||||
|
requestUrl = requestUrl.replace("ACCESS_TOKEN", wechatToken.getAccessToken()).replace("OPENID", wechatToken.getOpenId());
|
||||||
|
// 通过网页授权获取用户信息
|
||||||
|
|
||||||
|
String s = HttpUtil.get(requestUrl);
|
||||||
|
WechatUserInfo wechatUserInfo = JSONObject.parseObject(s,WechatUserInfo.class);
|
||||||
|
return wechatUserInfo;
|
||||||
|
}catch (Exception e){
|
||||||
|
logger.error("获取用户信息失败",e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取网页授权凭证
|
||||||
|
*
|
||||||
|
* @param code
|
||||||
|
* @return WeixinAouth2Token
|
||||||
|
*/
|
||||||
|
public WechatToken getOauth2AccessToken(String code) {
|
||||||
|
|
||||||
|
AppThirdLoginDTO wechatProperty=appThirdLoginConfigInfo.getLoginConfigWithCache(GrantTypeEnum.WECHAT_CODE.getCode());
|
||||||
|
|
||||||
|
|
||||||
|
WechatUserInfo wat = null;
|
||||||
|
// 拼接请求地址
|
||||||
|
String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
|
||||||
|
requestUrl = requestUrl.replace("APPID", wechatProperty.getThirdAppId());
|
||||||
|
requestUrl = requestUrl.replace("SECRET", wechatProperty.getPrivateKey());
|
||||||
|
requestUrl = requestUrl.replace("CODE", code);
|
||||||
|
// 获取网页授权凭证
|
||||||
|
String result = HttpUtil.get(requestUrl);
|
||||||
|
logger.info("微信授权码接口返回:{}",result);
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(result);
|
||||||
|
String access_token = jsonObject.getString("access_token");
|
||||||
|
String openid = jsonObject.getString("openid");
|
||||||
|
WechatToken wechatToken = new WechatToken(access_token,openid,null,null);
|
||||||
|
return wechatToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WechatToken getOauth2AccessTokenByJsCode(String code) {
|
||||||
|
|
||||||
|
AppThirdLoginDTO wechatProperty=appThirdLoginConfigInfo.getLoginConfigWithCache(GrantTypeEnum.MINI_APP.getCode());
|
||||||
|
|
||||||
|
String requestUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=CODE&grant_type=authorization_code";
|
||||||
|
requestUrl = requestUrl.replace("APPID", wechatProperty.getThirdAppId());
|
||||||
|
requestUrl = requestUrl.replace("SECRET", wechatProperty.getPrivateKey());
|
||||||
|
requestUrl = requestUrl.replace("CODE", code);
|
||||||
|
String result = HttpUtil.get(requestUrl);
|
||||||
|
logger.info("微信授权码接口返回:{}",result);
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(result);
|
||||||
|
String access_token = jsonObject.getString("access_token");
|
||||||
|
String openid = jsonObject.getString("openid");
|
||||||
|
String sessionKey = jsonObject.getString("session_key");
|
||||||
|
String unionid = jsonObject.getString("unionid");
|
||||||
|
WechatToken wechatToken = new WechatToken(access_token,openid,sessionKey,unionid);
|
||||||
|
return wechatToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WxMaPhoneNumberInfo getPhoneNumber(String sessionKey, MiniAppParam miniAppParam) {
|
||||||
|
String result =null;
|
||||||
|
try {
|
||||||
|
byte[] encData = Base64.decode(miniAppParam.getEncryptedData());
|
||||||
|
byte[] iv = Base64.decode(miniAppParam.getIv());
|
||||||
|
byte[] key = Base64.decode(sessionKey);
|
||||||
|
AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||||
|
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
|
||||||
|
result = new String(cipher.doFinal(encData), "UTF-8");
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchPaddingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidAlgorithmParameterException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalBlockSizeException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (BadPaddingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if(result==null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return JSONObject.parseObject(result,WxMaPhoneNumberInfo.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取网页授权凭证
|
||||||
|
*
|
||||||
|
* @param code
|
||||||
|
* @return WeixinAouth2Token
|
||||||
|
*/
|
||||||
|
public WechatToken getOauth2AccessTokenByOfficialAccount(String code) {
|
||||||
|
|
||||||
|
AppThirdLoginDTO wechatProperty=appThirdLoginConfigInfo.getLoginConfigWithCache(GrantTypeEnum.MINI_APP.getCode());
|
||||||
|
|
||||||
|
WechatUserInfo wat = null;
|
||||||
|
// 拼接请求地址
|
||||||
|
String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
|
||||||
|
requestUrl = requestUrl.replace("APPID", wechatProperty.getThirdAppId());
|
||||||
|
requestUrl = requestUrl.replace("SECRET", wechatProperty.getPrivateKey());
|
||||||
|
requestUrl = requestUrl.replace("CODE", code);
|
||||||
|
// 获取网页授权凭证
|
||||||
|
String result = HttpUtil.get(requestUrl);
|
||||||
|
logger.info("微信授权码接口返回:{}",result);
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(result);
|
||||||
|
String access_token = jsonObject.getString("access_token");
|
||||||
|
String openid = jsonObject.getString("openid");
|
||||||
|
WechatToken wechatToken = new WechatToken(access_token,openid,null,null);
|
||||||
|
return wechatToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.oneone.auth.config;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.servlet.*;
|
||||||
|
import javax.servlet.annotation.WebFilter;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@WebFilter(filterName = "ApiAccessFilter", urlPatterns = "/*")
|
||||||
|
public class ApiAccessFilter implements Filter {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) {
|
||||||
|
log.info("过滤器名称:ApiAccessFilter");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
|
||||||
|
FilterChain filterChain) throws IOException, ServletException {
|
||||||
|
|
||||||
|
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||||
|
|
||||||
|
long start = System.currentTimeMillis(); // 请求进入时间
|
||||||
|
|
||||||
|
filterChain.doFilter(servletRequest, servletResponse);
|
||||||
|
log.info("请求地址: {}, 耗时: {}", request.getRequestURI(), System.currentTimeMillis()-start);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.oneone.auth.config;
|
||||||
|
|
||||||
|
import com.oneone.common.redis.utils.LocalRedisTokenStore;
|
||||||
|
import com.oneone.common.redis.utils.RedisUtils;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-04-07 16:44
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class RedisStoreConfig {
|
||||||
|
|
||||||
|
@Bean(value = "appRedisTokenStore")
|
||||||
|
public LocalRedisTokenStore appRedisTokenStore(RedisUtils redisUtils){
|
||||||
|
LocalRedisTokenStore appRedisTokenStore = new LocalRedisTokenStore(redisUtils);
|
||||||
|
appRedisTokenStore.setPrefix("app_token:");
|
||||||
|
return appRedisTokenStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Bean(value = "miniAppRedisTokenStore")
|
||||||
|
// public LocalRedisTokenStore sysRedisTokenStore(RedisUtils redisUtils){
|
||||||
|
// LocalRedisTokenStore sysRedisTokenStore = new LocalRedisTokenStore(redisUtils);
|
||||||
|
// sysRedisTokenStore.setPrefix("mini_app_token:");
|
||||||
|
// return sysRedisTokenStore;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Bean(value = "officialAccountRedisTokenStore")
|
||||||
|
// public LocalRedisTokenStore officialAccountRedisTokenStore(RedisUtils redisUtils){
|
||||||
|
// LocalRedisTokenStore appRedisTokenStore = new LocalRedisTokenStore(redisUtils);
|
||||||
|
// appRedisTokenStore.setPrefix("official_account_token:");
|
||||||
|
// return appRedisTokenStore;
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.oneone.auth.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信用户信息
|
||||||
|
*
|
||||||
|
* @author oneone
|
||||||
|
* @date 2021/10/4
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class WechatUserInfo {
|
||||||
|
private String headimgurl;
|
||||||
|
|
||||||
|
private String city;
|
||||||
|
|
||||||
|
private String country;
|
||||||
|
|
||||||
|
private Integer gender;
|
||||||
|
|
||||||
|
private String language;
|
||||||
|
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
private String province;
|
||||||
|
|
||||||
|
private String openid;
|
||||||
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
package com.oneone.auth.controller.admin;
|
||||||
|
|
||||||
|
import com.oneone.auth.common.wechat.WechatProperty;
|
||||||
|
import com.oneone.auth.entity.dto.OfficialAccountDTO;
|
||||||
|
import com.oneone.common.result.Result;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@Tag(name = "app - 公众号")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("oauth/officialAccount")
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class OfficialAccountController {
|
||||||
|
private final WechatProperty wechatProperty;
|
||||||
|
|
||||||
|
@Operation(summary = "获取appid", description = "获取appid")
|
||||||
|
@GetMapping("/getAppid")
|
||||||
|
public Result<OfficialAccountDTO> getAppid() {
|
||||||
|
OfficialAccountDTO officialAccountDTO = new OfficialAccountDTO();
|
||||||
|
officialAccountDTO.setAppId(wechatProperty.getOfficialAccountAppId());
|
||||||
|
return Result.success(officialAccountDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package com.oneone.auth.controller.app;
|
||||||
|
|
||||||
|
import com.oneone.auth.entity.TokenParam;
|
||||||
|
import com.oneone.auth.entity.ValidateTokenParam;
|
||||||
|
import com.oneone.auth.controller.app.vo.LocalTokenVO;
|
||||||
|
import com.oneone.auth.service.SsoService;
|
||||||
|
import com.oneone.common.base.LocalToken;
|
||||||
|
import com.oneone.common.result.Result;
|
||||||
|
import com.oneone.common.web.util.UserContext;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@Tag(name = "app - 认证中心")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/oauth/app")
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class AppSsoController {
|
||||||
|
private final SsoService appSsoService;
|
||||||
|
|
||||||
|
@Operation(summary = "登录")
|
||||||
|
@PostMapping("/login")
|
||||||
|
public Result<LocalToken> login(@RequestBody TokenParam param) {
|
||||||
|
param.setPlatformUserId(null);
|
||||||
|
return Result.success(appSsoService.login(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "注册")
|
||||||
|
@PostMapping("/register")
|
||||||
|
public Result<LocalTokenVO> register(@RequestBody TokenParam param) {
|
||||||
|
return Result.success(LocalTokenVO.getLocalTokenDTO(appSsoService.register(param)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "登出")
|
||||||
|
@PostMapping("/logout")
|
||||||
|
public Result logout(@RequestHeader("Authorization") String authorization) {
|
||||||
|
appSsoService.logout(authorization);
|
||||||
|
return Result.success("退出成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "验证token")
|
||||||
|
@PostMapping("/validateToken")
|
||||||
|
public Result<LocalToken> validateToken(@RequestBody ValidateTokenParam param) {
|
||||||
|
return Result.success(appSsoService.validate(param.getAccessToken()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "账号绑定")
|
||||||
|
@PostMapping("/bind")
|
||||||
|
public Result<Boolean> bind(@RequestBody TokenParam param) {
|
||||||
|
|
||||||
|
param.setPlatformUserId(UserContext.getMemberId());
|
||||||
|
|
||||||
|
return Result.success(appSsoService.bind(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.oneone.auth.controller.app;
|
||||||
|
|
||||||
|
import com.oneone.auth.entity.LoginSmsCodeParam;
|
||||||
|
import com.oneone.auth.entity.SendSmsCodeParam;
|
||||||
|
import com.oneone.common.result.Result;
|
||||||
|
import com.oneone.common.sms.service.SmsService;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Tag(name = "短信验证码")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/oauth/sms-code")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SmsCodeController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private SmsService smsService;
|
||||||
|
|
||||||
|
@Operation(summary = "发送登录验证码")
|
||||||
|
@PostMapping("/login")
|
||||||
|
public Result loginSmsCode(@Validated @RequestBody LoginSmsCodeParam param) {
|
||||||
|
//smsService.imageValidate(param.getKey(), param.getValidateCode());
|
||||||
|
smsService.sendSmsCode(param.getPhoneNumber(), param.getType());
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "发送短信验证码")
|
||||||
|
@PostMapping("/common")
|
||||||
|
public Result sendSmsCode(@Validated @RequestBody SendSmsCodeParam param) {
|
||||||
|
smsService.sendSmsCode(param.getPhoneNumber(), param.getType());
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Operation(summary = "发送短信验证码-已登录场景")
|
||||||
|
// @PostMapping("/auth")
|
||||||
|
// public Result sendAuthSmsCode(@Validated @RequestBody SendAuthSmsCodeParam param) {
|
||||||
|
// Result<MemberInfoDTO> memberInfoDTOResult = memberFeignClient.getMemberInfo(UserContext.getUserId());
|
||||||
|
// String phone = null;
|
||||||
|
// if (Result.isSuccess(memberInfoDTOResult)) {
|
||||||
|
// phone = memberInfoDTOResult.getData().getMobile();
|
||||||
|
// } else {
|
||||||
|
// throw new BusinessException("发送短信失败");
|
||||||
|
// }
|
||||||
|
// smsService.sendSmsCode(phone, param.getType());
|
||||||
|
// return Result.success();
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.oneone.auth.controller.app;
|
||||||
|
|
||||||
|
import com.oneone.auth.entity.TokenParam;
|
||||||
|
import com.oneone.auth.service.SsoService;
|
||||||
|
import com.oneone.common.base.LocalToken;
|
||||||
|
import com.oneone.common.result.Result;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
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.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
@Tag(name = "sys - 认证中心")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/oauth/sys")
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class SysSsoController {
|
||||||
|
private final SsoService sysSsoService;
|
||||||
|
|
||||||
|
@Operation(summary = "登录", description = "登录")
|
||||||
|
@PostMapping("/login")
|
||||||
|
public Result<LocalToken> login(@RequestBody TokenParam param) {
|
||||||
|
return Result.success(sysSsoService.login(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "登出")
|
||||||
|
@PostMapping("/logout")
|
||||||
|
public Result logout(HttpServletRequest request ) {
|
||||||
|
String authorization = request.getHeader("Authorization");
|
||||||
|
sysSsoService.logout(authorization);
|
||||||
|
return Result.success("注销成功");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.oneone.auth.controller.app;
|
||||||
|
|
||||||
|
import com.oneone.auth.controller.app.vo.GameLoginResp;
|
||||||
|
import com.oneone.auth.controller.app.vo.LocalTokenVO;
|
||||||
|
import com.oneone.auth.entity.TokenParam;
|
||||||
|
import com.oneone.auth.entity.ValidateTokenParam;
|
||||||
|
import com.oneone.auth.service.SsoService;
|
||||||
|
import com.oneone.common.base.LocalToken;
|
||||||
|
import com.oneone.common.redis.utils.LocalRedisTokenStore;
|
||||||
|
import com.oneone.common.result.Result;
|
||||||
|
import com.oneone.common.web.util.UserContext;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-06-15 21:15
|
||||||
|
*/
|
||||||
|
@Tag(name = "sys - token管理")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/oauth/token")
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class TokenAdminController {
|
||||||
|
private final LocalRedisTokenStore appRedisTokenStore;
|
||||||
|
private final SsoService appSsoService;
|
||||||
|
|
||||||
|
@Operation(summary = "移除appToken", description = "移除appToken")
|
||||||
|
@PostMapping("/removeAppToken/{memberId}")
|
||||||
|
public Result removeAppToken(@PathVariable Long memberId) {
|
||||||
|
appRedisTokenStore.removeToken(memberId);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "移除sysToken", description = "移除sysToken")
|
||||||
|
@PostMapping("/removeSysToken/{userId}")
|
||||||
|
public Result removeSysToken(@PathVariable Long userId) {
|
||||||
|
appRedisTokenStore.removeToken(userId);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.oneone.auth.controller.app.vo;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class GameLoginResp implements Serializable {
|
||||||
|
private Long id;
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.oneone.auth.controller.app.vo;
|
||||||
|
|
||||||
|
import com.oneone.common.base.LocalToken;
|
||||||
|
import com.oneone.common.enums.ChannelEnum;
|
||||||
|
import com.oneone.common.util.BeanUtil;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class LocalTokenVO implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String accessToken;
|
||||||
|
private String refreshToken;
|
||||||
|
@Schema(description = "有效期")
|
||||||
|
private Long expiresIn;
|
||||||
|
@Schema(description = "授权方式: refresh, sms_code, wechat")
|
||||||
|
private String grantType;
|
||||||
|
@Schema(description = "用户id")
|
||||||
|
private Long platformUserId;
|
||||||
|
@Schema(description = "账号")
|
||||||
|
private String account;
|
||||||
|
@Schema(description = "账号类型")
|
||||||
|
private String accountType;
|
||||||
|
@Schema(description = "用户类型")
|
||||||
|
private Integer userType;
|
||||||
|
@Schema(description = "渠道")
|
||||||
|
private ChannelEnum channel = ChannelEnum.LOCAL;
|
||||||
|
|
||||||
|
public static LocalTokenVO getLocalTokenDTO(LocalToken localToken){
|
||||||
|
if(localToken == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
LocalTokenVO copy = BeanUtil.copy(localToken, LocalTokenVO.class);
|
||||||
|
copy.setPlatformUserId(localToken.getMemberId());
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.oneone.auth.entity;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@ApiModel
|
||||||
|
@Data
|
||||||
|
public class ImageValidateCodeParam {
|
||||||
|
@Schema(description="key: 手机端传设备号")
|
||||||
|
@NotNull
|
||||||
|
private String key;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.oneone.auth.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-12-12 10:35
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class ImageValidateCodeVO {
|
||||||
|
private String key;
|
||||||
|
private String imageBase64;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.oneone.auth.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-04-02 15:47
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class LoginSmsCodeParam {
|
||||||
|
@NotBlank
|
||||||
|
private String phoneNumber;
|
||||||
|
@NotBlank
|
||||||
|
private String type;
|
||||||
|
@NotBlank
|
||||||
|
private String validateCode;
|
||||||
|
@NotBlank
|
||||||
|
private String key;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.oneone.auth.entity;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-04-02 15:47
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SendAuthSmsCodeParam {
|
||||||
|
@NotBlank
|
||||||
|
@Schema(description = "LOGIN(\"login\",\"登录\"),\n" +
|
||||||
|
" SET_OPERATE_PWD(\"setOperatePwd\",\"设置操作密码\"),\n" +
|
||||||
|
" CONFIRM_MOBILE(\"confirmMobile\",\"确认手机号\"),\n" +
|
||||||
|
" SET_MOBILE(\"setMobile\",\"设置手机号\")")
|
||||||
|
private String type;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.oneone.auth.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-04-02 15:47
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SendSmsCodeParam {
|
||||||
|
@NotBlank
|
||||||
|
private String phoneNumber;
|
||||||
|
@NotBlank
|
||||||
|
private String type;
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.oneone.auth.entity;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-04-02 11:33
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode
|
||||||
|
public class TokenParam {
|
||||||
|
@Schema(description = "账号")
|
||||||
|
private String account;
|
||||||
|
@Schema(description = "密码")
|
||||||
|
private String password;
|
||||||
|
@Schema(description = "授权方式: REFRESH(\"refresh\",\"刷新token\"),\n" +
|
||||||
|
" SMS_CODE(\"sms_code\",\"短信验证码登录\"),\n" +
|
||||||
|
" WECHAT(\"wechat\",\"微信登录\"),\n" +
|
||||||
|
" WECHAT_CODE(\"wechatCode\",\"微信登录授权码\"),\n" +
|
||||||
|
" PASSWORD(\"password\",\"密码登录\"),\n" +
|
||||||
|
" APPLE_JWT(\"apple\",\"苹果jwt\"),\n" +
|
||||||
|
" USERNAME(\"username\",\"账号\"),\n" +
|
||||||
|
" MINI_APP(\"mini_app\",\"微信小程序\")," +
|
||||||
|
" ALIPAY(\"alipay\",\"支付宝登录\")," +
|
||||||
|
" DEVICE(\"device\",\"设备号登录\")," +
|
||||||
|
" FACEBOOK(\"facebook\",\"facebook登录\")," +
|
||||||
|
" GOOGLE(\"google\",\"google登录\")," +
|
||||||
|
" EMAIL(\"email\",\"邮件\"),")
|
||||||
|
private String grantType;
|
||||||
|
@Schema(description = "refreshToken")
|
||||||
|
private String refreshToken;
|
||||||
|
|
||||||
|
private String others;
|
||||||
|
|
||||||
|
@Schema(description = "",hidden = true)
|
||||||
|
private Long platformUserId;
|
||||||
|
|
||||||
|
@Schema(description = "渠道")
|
||||||
|
private String channel;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.oneone.auth.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2023-02-24 19:49
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ValidateTokenParam {
|
||||||
|
@NotEmpty(message = "accessToken不能为空")
|
||||||
|
private String accessToken;
|
||||||
|
@NotEmpty(message = "playerId不能为空")
|
||||||
|
private Long playerId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.oneone.auth.entity.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mice
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2022-09-21 10:36
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AccountInfo {
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
@Schema(description="用户id")
|
||||||
|
private Long platformUserId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账号类型
|
||||||
|
*/
|
||||||
|
@Schema(description="账号类型")
|
||||||
|
private String accountType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账号
|
||||||
|
*/
|
||||||
|
@Schema(description="账号")
|
||||||
|
private String account;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密码
|
||||||
|
*/
|
||||||
|
@Schema(description="密码")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1:启用 0:禁用
|
||||||
|
*/
|
||||||
|
@Schema(description="1:启用 0:禁用")
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user