Merge branch 'master' into vip

pull/9/head
3y 2 years ago
commit cf8828502f

@ -56,7 +56,11 @@ austin项目**核心流程**`austin-api`接收到发送消息请求,直接
目前引用的中间件教程的安装姿势均基于`Centos 7.6`(**完全部署所有的服务大概8G内存**)austin项目**强依赖**`MySQL`/`Redis`/`Kafka`/`apollo`**弱依赖**`prometheus`/`graylog`/`flink`/`xxl-job`。如果缺少相关的组件可戳:[安装相关组件教程](INSTALL.md)。
实在想要拉下clone项目后不部署环境直接启动我这提供了[会员服务](https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247505577&idx=1&sn=5114f8f583755899c2946fbea0b22e4b&chksm=ebd497a8dca31ebe8f98344483a00c860863dfc3586e51eed95b25988151427fee8101311f4f&token=735778370&lang=zh_CN#rd)
> 实在想要`clone`项目后不用自己部署环境直接在本地启动`debug`,我这提供了[会员服务](https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247505577&idx=1&sn=5114f8f583755899c2946fbea0b22e4b&chksm=ebd497a8dca31ebe8f98344483a00c860863dfc3586e51eed95b25988151427fee8101311f4f&token=735778370&lang=zh_CN#rd)**直连**部署好的服务器
**1**、austin使用的MySQL版本**5.7x**。如果目前使用的MySQL版本8.0,注意改变`pom.xml`所依赖的版本
@ -100,6 +104,22 @@ curl -XPOST "127.0.0.1:8080/send" -H 'Content-Type: application/json' -d '{"co
**14**、正常使用**系统监控**需要部署`promethus`和`grafana`,根据[部署文档](INSTALL.md)配置`grafana`图表
## 会员服务
收费课程是以**项目**为主代码在Gitee和GitHub上都是开源的项目没有商业版后面也不会有。那么付费跟我自己去拉Git仓库拉代码下来看有什么区别
1、有很多人的自学能力和基础确实不太行不知道怎么开始学习从哪开始看起学习项目的过程中会走很多弯路很容易就迷茫了。付费最跟自学最主要的区别就是**我的服务会更周到**。
我会告诉你怎么开始学这个开源项目,哪些是重点需要掌握的,如何利用最短的时间把握整个系统架构和编码的设计,把时间节省下来去做其他事情。
2、一个生产环境的系统肯定会依赖各种中间件《消息推送平台-Austin》也是一样的。我专门买了两台服务器已经搭建好必要的依赖付费的可以**使用我的远程服务器**,在**本地就可以直接启动运行体验和学习**
3、项目在编写的过程中也经历多次的重构迭代迭代的内容我是不会将以往文章内容重新修正发布但语雀的文档内容一定是**及时同步**,文档跟代码是保持一致的
4、除了项目还可以问我些学习经验、学习路线、简历编写、面试经验等等问题技术和学习上的知识**知无不言**
详情可以看戳:[我开通了付费渠道](https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247505577&idx=1&sn=5114f8f583755899c2946fbea0b22e4b&chksm=ebd497a8dca31ebe8f98344483a00c860863dfc3586e51eed95b25988151427fee8101311f4f&token=319992632&lang=zh_CN#rd)
## 里程碑
- [x] Maven+SpringBoot项目搭建
@ -142,22 +162,12 @@ curl -XPOST "127.0.0.1:8080/send" -H 'Content-Type: application/json' -d '{"co
<img align="center" src='https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5eae548196934599a7cb3637aedf381d~tplv-k3u1fbpfcp-zoom-1.image' width=300px height=300px />
**Java3y**公众号在持续更新austin系列文章**保姆级**讲解搭建项目的过程(包括技术选型以及一些业务的探讨)以及相关环境的搭建。**扫下面的码直接关注,带你了解整个项目**
如果你需要用这个项目写在简历上,**强烈建议关注公众号看实现细节的思路**。如果⽂档中有任何的不懂的问题,都可以直接来找我询问,我乐意帮助你们!公众号下有我的联系方式
[会员服务](https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247505577&idx=1&sn=5114f8f583755899c2946fbea0b22e4b&chksm=ebd497a8dca31ebe8f98344483a00c860863dfc3586e51eed95b25988151427fee8101311f4f&token=735778370&lang=zh_CN#rd)
<img align="center" src='https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4e109cdb8d064c1e87541d7b6c17957d~tplv-k3u1fbpfcp-zoom-1.image' width=300px height=300px />
## 如何准备面试?
**对线面试官**公众号持续更新**面试系列**文章对线面试官系列深受各大开发的好评已有不少的同学通过对线面试官系列得到BATTMD等一线大厂的的offer。一个**讲人话的面试系列**,八股文不再是背诵。
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f48cee2bbd44476f93dfcdd8aaf8a4eb~tplv-k3u1fbpfcp-watermark.image?)
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c4a6cae132244355b9da6bd74d38d1ee~tplv-k3u1fbpfcp-zoom-1.image)
想要获取这份电子书,**点击关注**下方公众号,回复「**对线**」得到我的联系方式即可进群获取电子书

@ -26,6 +26,7 @@ public enum RespStatusEnum {
*/
CLIENT_BAD_PARAMETERS("A0001", "客户端参数错误"),
TEMPLATE_NOT_FOUND("A0002", "找不到模板或模板已被删除"),
TOO_MANY_RECEIVER("A0003", "传入的接收者大于100个"),
/**
*

@ -21,4 +21,19 @@ public enum SmsStatus {
private String description;
/**
*
* @param code
* @return
*/
public static String getDescriptionByStatus(Integer code) {
for (SmsStatus value : SmsStatus.values()) {
if (value.getCode().equals(code)) {
return value.getDescription();
}
}
return "";
}
}

@ -0,0 +1,115 @@
package com.java3y.austin.handler.receipt;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Throwables;
import com.java3y.austin.common.constant.SendAccountConstant;
import com.java3y.austin.common.dto.account.TencentSmsAccount;
import com.java3y.austin.common.enums.SmsStatus;
import com.java3y.austin.support.config.SupportThreadPoolConfig;
import com.java3y.austin.support.dao.SmsRecordDao;
import com.java3y.austin.support.domain.SmsRecord;
import com.java3y.austin.support.utils.AccountUtils;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.*;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
*
*
* @author 3y
*/
@Component
@Slf4j
public class TencentSmsReceipt {
@Autowired
private AccountUtils accountUtils;
@Autowired
private SmsRecordDao smsRecordDao;
@PostConstruct
private void init() {
// 获取腾讯云账号信息
TencentSmsAccount account = accountUtils.getAccount(10, SendAccountConstant.SMS_ACCOUNT_KEY, SendAccountConstant.SMS_PREFIX, TencentSmsAccount.class);
SupportThreadPoolConfig.getPendingSingleThreadPool().execute(() -> {
while (true) {
try {
SmsClient client = getSmsClient(account);
// 每次拉取10条
PullSmsSendStatusRequest req = new PullSmsSendStatusRequest();
req.setLimit(10L);
req.setSmsSdkAppId(account.getSmsSdkAppId());
PullSmsSendStatusResponse resp = client.PullSmsSendStatus(req);
List<SmsRecord> smsRecordList = new ArrayList<>();
if (resp != null && resp.getPullSmsSendStatusSet() != null && resp.getPullSmsSendStatusSet().length > 0) {
log.debug("receipt sms:{}", JSON.toJSONString(resp.getPullSmsSendStatusSet()));
for (PullSmsSendStatus pullSmsSendStatus : resp.getPullSmsSendStatusSet()) {
SmsRecord smsRecord = SmsRecord.builder()
.sendDate(Integer.valueOf(DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN)))
.messageTemplateId(0L)
.phone(Long.valueOf(pullSmsSendStatus.getSubscriberNumber()))
.supplierId(account.getSupplierId())
.supplierName(account.getSupplierName())
.msgContent("")
.seriesId(pullSmsSendStatus.getSerialNo())
.chargingNum(0)
.status("SUCCESS".equals(pullSmsSendStatus.getReportStatus()) ? SmsStatus.RECEIVE_SUCCESS.getCode() : SmsStatus.RECEIVE_FAIL.getCode())
.reportContent(pullSmsSendStatus.getDescription())
.updated(Math.toIntExact(pullSmsSendStatus.getUserReceiveTime()))
.created(Math.toIntExact(DateUtil.currentSeconds()))
.build();
smsRecordList.add(smsRecord);
}
}
if (!CollUtil.isEmpty(smsRecordList)) {
smsRecordDao.saveAll(smsRecordList);
}
Thread.sleep(200);
} catch (Exception e) {
log.error("TencentSmsReceipt#init fail!{}", Throwables.getStackTraceAsString(e));
}
}
});
}
/**
* smsClient
* @param account
* @return
*/
private SmsClient getSmsClient(TencentSmsAccount account) {
Credential cred = new Credential(account.getSecretId(), account.getSecretKey());
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint(account.getUrl());
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
return new SmsClient(cred, account.getRegion(), clientProfile);
}
}

@ -4,12 +4,21 @@ package com.java3y.austin.support.dao;
import com.java3y.austin.support.domain.SmsRecord;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
/**
* Dao
* @author 3y
*
* @author 3y
*/
public interface SmsRecordDao extends CrudRepository<SmsRecord, Long> {
/**
*
*
* @param phone
* @param sendDate
* @return
*/
List<SmsRecord> findByPhoneAndSendDate(Long phone, Integer sendDate);
}

@ -1,12 +1,12 @@
package com.java3y.austin.web.controller;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.java3y.austin.common.enums.RespStatusEnum;
import com.java3y.austin.common.vo.BasicResultVO;
import com.java3y.austin.web.service.DataService;
import com.java3y.austin.web.vo.DataParam;
import com.java3y.austin.web.vo.amis.EchartsVo;
import com.java3y.austin.web.vo.amis.SmsTimeLineVo;
import com.java3y.austin.web.vo.amis.UserTimeLineVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -46,10 +46,16 @@ public class DataController {
return new BasicResultVO<>(RespStatusEnum.SUCCESS, echartsVo);
}
public static void main(String[] args) {
EchartsVo.TitleVO titleVO = EchartsVo.TitleVO.builder().text("销售情况").build();
EchartsVo echartsVo = EchartsVo.builder().title(titleVO).build();
@PostMapping("/sms")
@ApiOperation("/获取短信下发数据")
public BasicResultVO getSmsData(@RequestBody DataParam dataParam) {
if (dataParam == null || dataParam.getDateTime() == null || dataParam.getReceiver() == null) {
return new BasicResultVO<>(RespStatusEnum.SUCCESS, new SmsTimeLineVo());
}
SmsTimeLineVo smsTimeLineVo = dataService.getTraceSmsInfo(dataParam);
System.out.println(JSON.toJSONString(echartsVo));
return new BasicResultVO<>(RespStatusEnum.SUCCESS, smsTimeLineVo);
}
}

@ -1,6 +1,8 @@
package com.java3y.austin.web.service;
import com.java3y.austin.web.vo.DataParam;
import com.java3y.austin.web.vo.amis.EchartsVo;
import com.java3y.austin.web.vo.amis.SmsTimeLineVo;
import com.java3y.austin.web.vo.amis.UserTimeLineVo;
/**
@ -28,4 +30,12 @@ public interface DataService {
EchartsVo getTraceMessageTemplateInfo(String businessId);
/**
*
*
* @param dataParam
* @return
*/
SmsTimeLineVo getTraceSmsInfo(DataParam dataParam);
}

@ -11,13 +11,18 @@ import com.java3y.austin.common.constant.AustinConstant;
import com.java3y.austin.common.domain.SimpleAnchorInfo;
import com.java3y.austin.common.enums.AnchorState;
import com.java3y.austin.common.enums.ChannelType;
import com.java3y.austin.common.enums.SmsStatus;
import com.java3y.austin.support.dao.MessageTemplateDao;
import com.java3y.austin.support.dao.SmsRecordDao;
import com.java3y.austin.support.domain.MessageTemplate;
import com.java3y.austin.support.domain.SmsRecord;
import com.java3y.austin.support.utils.RedisUtils;
import com.java3y.austin.support.utils.TaskInfoUtils;
import com.java3y.austin.web.constants.AmisVoConstant;
import com.java3y.austin.web.service.DataService;
import com.java3y.austin.web.vo.DataParam;
import com.java3y.austin.web.vo.amis.EchartsVo;
import com.java3y.austin.web.vo.amis.SmsTimeLineVo;
import com.java3y.austin.web.vo.amis.UserTimeLineVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -39,6 +44,10 @@ public class DataServiceImpl implements DataService {
@Autowired
private MessageTemplateDao messageTemplateDao;
@Autowired
private SmsRecordDao smsRecordDao;
@Override
public UserTimeLineVo getTraceUserInfo(String receiver) {
List<String> userInfoList = redisUtils.lRange(receiver, 0, -1);
@ -134,6 +143,44 @@ public class DataServiceImpl implements DataService {
}
@Override
public SmsTimeLineVo getTraceSmsInfo(DataParam dataParam) {
ArrayList<SmsTimeLineVo.ItemsVO> itemsVOS = new ArrayList<>();
SmsTimeLineVo smsTimeLineVo = SmsTimeLineVo.builder().items(itemsVOS).build();
Integer sendDate = Integer.valueOf(DateUtil.format(new Date(dataParam.getDateTime() * 1000L)
, DatePattern.PURE_DATE_PATTERN));
List<SmsRecord> smsRecordList = smsRecordDao.findByPhoneAndSendDate(Long.valueOf(dataParam.getReceiver()), sendDate);
if (CollUtil.isEmpty(smsRecordList)) {
return smsTimeLineVo;
}
Map<String, List<SmsRecord>> maps = smsRecordList.stream().collect(Collectors.groupingBy((o) -> o.getPhone() + o.getSeriesId()));
for (Map.Entry<String, List<SmsRecord>> entry : maps.entrySet()) {
SmsTimeLineVo.ItemsVO itemsVO = SmsTimeLineVo.ItemsVO.builder().build();
for (SmsRecord smsRecord : entry.getValue()) {
// 发送记录 messageTemplateId >0 ,回执记录 messageTemplateId =0
if (smsRecord.getMessageTemplateId() > 0) {
itemsVO.setBusinessId(String.valueOf(smsRecord.getMessageTemplateId()));
itemsVO.setContent(smsRecord.getMsgContent());
itemsVO.setSendType(SmsStatus.getDescriptionByStatus(smsRecord.getStatus()));
itemsVO.setSendTime(DateUtil.format(new Date(Long.valueOf(smsRecord.getCreated()*1000L)), DatePattern.NORM_DATETIME_PATTERN));
} else {
itemsVO.setReceiveType(SmsStatus.getDescriptionByStatus(smsRecord.getStatus()));
itemsVO.setReceiveContent(smsRecord.getReportContent());
itemsVO.setReceiveTime(DateUtil.format(new Date(Long.valueOf(smsRecord.getUpdated()*1000L)), DatePattern.NORM_DATETIME_PATTERN));
}
}
itemsVOS.add(itemsVO);
}
return smsTimeLineVo;
}
/**
* IDbusinessId
* businessIdbusinessId
@ -150,4 +197,14 @@ public class DataServiceImpl implements DataService {
}
return businessId;
}
public static void main(String[] args) {
Long time = 1653140847 * 1000L;
String format = DateUtil.format(new Date(time), DatePattern.NORM_DATETIME_PATTERN);
System.out.println(format
);
}
}

@ -16,8 +16,9 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
public class DataParam {
/**
* userId
*
*/
private String receiver;
@ -30,4 +31,12 @@ public class DataParam {
private String businessId;
/**
* (使)
*/
private Long dateTime;
}

@ -0,0 +1,67 @@
package com.java3y.austin.web.vo.amis;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author 3y
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class SmsTimeLineVo {
/**
* items
*/
private List<SmsTimeLineVo.ItemsVO> items;
/**
* ItemsVO
*/
@Data
@Builder
public static class ItemsVO {
/**
* ID
*/
private String businessId;
/**
* detail
*/
private String content;
/**
*
*/
private String sendType;
/**
*
*/
private String receiveType;
/**
*
*/
private String receiveContent;
/**
*
*/
private String sendTime;
/**
*
*/
private String receiveTime;
}
}

@ -81,7 +81,7 @@
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>3.1.390</version>
<version>3.1.510</version>
</dependency>
<!--apollo-->

Loading…
Cancel
Save