新增消息发送统计图表

This commit is contained in:
wanggeng 2021-10-25 00:08:01 +08:00
parent 0faa4e3dd8
commit 9f05383de0
5 changed files with 643 additions and 0 deletions

View File

@ -0,0 +1,72 @@
package cn.com.tenlion.usercenter.controller.api.versualreport;
import cn.com.tenlion.usercenter.service.visualreport.IUnifiedMessagingService;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.pojo.result.ErrorResult;
import ink.wgink.pojo.result.SuccessResultData;
import ink.wgink.util.RegexUtil;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* @ClassName: UnifiedMessagingCountroller
* @Description: 统一消息统计可视化
* @Author: wanggeng
* @Date: 2021/10/24 4:04 下午
* @Version: 1.0
*/
@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "统一消息统计可视化接口")
@RestController
@RequestMapping(ISystemConstant.API_PREFIX + "/visual-report/unified-messaging")
public class UnifiedMessagingController {
@Autowired
private IUnifiedMessagingService unifiedMessagingService;
@ApiOperation(value = "日发送统计", notes = "日发送统计接口")
@ApiImplicitParams({
@ApiImplicitParam(name = "date", value = "当天", paramType = "path")
})
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
@GetMapping("day-send-count/{date}")
public SuccessResultData<Map<String, Object>> daySendCount(@PathVariable("date") String date) {
if (!RegexUtil.isDate(date)) {
throw new ParamsException("日期格式错误");
}
return new SuccessResultData<>(unifiedMessagingService.daySendCount(date));
}
@ApiOperation(value = "周发送统计", notes = "周发送统计接口")
@ApiImplicitParams({
@ApiImplicitParam(name = "day", value = "当天", paramType = "path")
})
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
@GetMapping("week-send-count/{day}")
public SuccessResultData<Map<String, Object>> weekSendCount(@PathVariable("day") String day) {
if (!RegexUtil.isDate(day)) {
throw new ParamsException("日期格式错误");
}
return new SuccessResultData<>(unifiedMessagingService.weekSendCount(day));
}
@ApiOperation(value = "月发送统计", notes = "月发送统计接口")
@ApiImplicitParams({
@ApiImplicitParam(name = "day", value = "当天", paramType = "path")
})
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
@GetMapping("month-send-count/{day}")
public SuccessResultData<Map<String, Object>> monthSendCount(@PathVariable("day") String day) {
if (!RegexUtil.isDate(day)) {
throw new ParamsException("日期格式错误");
}
return new SuccessResultData<>(unifiedMessagingService.monthSendCount(day));
}
}

View File

@ -0,0 +1,27 @@
package cn.com.tenlion.usercenter.controller.route.visualreport;
import ink.wgink.interfaces.consts.ISystemConstant;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
/**
* @ClassName: UnifiedMessagingRouteController
* @Description: 统一消息统计可视化路由
* @Author: wanggeng
* @Date: 2021/10/24 3:30 下午
* @Version: 1.0
*/
@Api(tags = ISystemConstant.ROUTE_TAGS_PREFIX + "统一消息统计可视化路由")
@RestController
@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/visual-report/unified-messaging")
public class UnifiedMessagingRouteController {
@GetMapping("report")
public ModelAndView report() {
return new ModelAndView("visual-report/report");
}
}

View File

@ -0,0 +1,37 @@
package cn.com.tenlion.usercenter.service.visualreport;
import java.util.Map;
/**
* @ClassName: IUnifiedMessagingService
* @Description: 统一消息可视化统计
* @Author: wanggeng
* @Date: 2021/10/24 4:05 下午
* @Version: 1.0
*/
public interface IUnifiedMessagingService {
/**
* 日发送统计
*
* @param date
* @return
*/
Map<String, Object> daySendCount(String date);
/**
* 周发送统计
*
* @param date
* @return
*/
Map<String, Object> weekSendCount(String date);
/**
* 月发送统计
*
* @param date
* @return
*/
Map<String, Object> monthSendCount(String date);
}

View File

@ -0,0 +1,184 @@
package cn.com.tenlion.usercenter.service.visualreport.service;
import cn.com.tenlion.usercenter.service.visualreport.IUnifiedMessagingService;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.module.instantmessage.pojo.pos.NoticePO;
import ink.wgink.module.instantmessage.service.INoticeService;
import ink.wgink.module.sms.pojo.pos.sms.SmsPO;
import ink.wgink.module.sms.service.sms.ISmsService;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @ClassName: UnifiedMessagingServiceImpl
* @Description: 统一消息统计
* @Author: wanggeng
* @Date: 2021/10/24 4:06 下午
* @Version: 1.0
*/
@Service
public class UnifiedMessagingServiceImpl extends DefaultBaseService implements IUnifiedMessagingService {
@Autowired
private ISmsService smsService;
@Autowired
private INoticeService noticeService;
@Override
public Map<String, Object> daySendCount(String date) {
List<SmsPO> smsPOs = smsService.listPOByDate(date);
List<NoticePO> noticePOs = noticeService.listPOByDate(date);
int smsSendCount = smsPOs.size();
int smsSendSuccessCount = 0;
int noticeSendCount = noticePOs.size();
int noticeSendSuccessCount = 0;
for (SmsPO smsPO : smsPOs) {
if (smsPO.getSendStatus() == 1) {
smsSendSuccessCount++;
}
}
for (NoticePO noticePO : noticePOs) {
if (noticePO.getIsSend() == 1) {
noticeSendSuccessCount++;
}
}
Map<String, Object> resultJsonMap = getHashMap(12);
resultJsonMap.put("smsSendCount", smsSendCount);
resultJsonMap.put("smsSendSuccessCount", smsSendSuccessCount);
resultJsonMap.put("smsSendSuccessPercent", smsSendCount > 0 ? String.format("%.2f", (smsSendSuccessCount / (double) smsSendCount * 100)) : "0.00");
resultJsonMap.put("noticeSendCount", noticeSendCount);
resultJsonMap.put("noticeSendSuccessCount", noticeSendSuccessCount);
resultJsonMap.put("noticeSendSuccessPercent", noticeSendCount > 0 ? String.format("%.2f", (noticeSendSuccessCount / (double) noticeSendCount * 100)) : "0.00");
return resultJsonMap;
}
@Override
public Map<String, Object> weekSendCount(String date) {
DateTime dateDateTime = DateTime.parse(date, DateTimeFormat.forPattern(ISystemConstant.DATE_FORMATTER_YYYY_MM_DD));
DateTime firstDateTime = dateDateTime.dayOfWeek().withMinimumValue();
String startTime = firstDateTime.toString(DateTimeFormat.forPattern(ISystemConstant.DATE_FORMATTER_YYYY_MM_DD));
DateTime endDateTime = dateDateTime.dayOfWeek().withMaximumValue();
String endTime = endDateTime.toString(DateTimeFormat.forPattern(ISystemConstant.DATE_FORMATTER_YYYY_MM_DD));
List<SmsPO> smsPOs = smsService.listPOByStartTimeAndEndTime(startTime, endTime);
List<NoticePO> noticePOs = noticeService.listPOByStartTimeAndEndTime(startTime, endTime);
List<String> xDatas = new ArrayList<>();
List<Integer> ySmsSendDatas = new ArrayList<>();
List<Integer> ySmsSendSuccessDatas = new ArrayList<>();
List<Integer> yNoticeSendDatas = new ArrayList<>();
List<Integer> yNoticeSendSuccessDatas = new ArrayList<>();
for (int i = 0; i < 7; i++) {
int smsSendCount = 0;
int smsSendSuccessCount = 0;
int noticeSendCount = 0;
int noticeSendSuccessCount = 0;
DateTime dayOfWeek = dateDateTime.withDayOfWeek(i + 1);
String dayOfWeekDate = dayOfWeek.toString(DateTimeFormat.forPattern(ISystemConstant.DATE_FORMATTER_YYYY_MM_DD));
xDatas.add(dayOfWeekDate);
for (SmsPO smsPO : smsPOs) {
if (!smsPO.getGmtCreate().startsWith(dayOfWeekDate)) {
continue;
}
smsSendCount++;
if (smsPO.getSendStatus() == 1) {
smsSendSuccessCount++;
}
}
for (NoticePO noticePO : noticePOs) {
if (!noticePO.getGmtCreate().startsWith(dayOfWeekDate)) {
continue;
}
noticeSendCount++;
if (noticePO.getIsSend() == 1) {
noticeSendSuccessCount++;
}
}
ySmsSendDatas.add(smsSendCount);
ySmsSendSuccessDatas.add(smsSendSuccessCount);
yNoticeSendDatas.add(noticeSendCount);
yNoticeSendSuccessDatas.add(noticeSendSuccessCount);
}
Map<String, Object> result = new HashMap<>();
result.put("xDatas", xDatas);
result.put("ySmsSendDatas", ySmsSendDatas);
result.put("ySmsSendSuccessDatas", ySmsSendSuccessDatas);
result.put("yNoticeSendDatas", yNoticeSendDatas);
result.put("yNoticeSendSuccessDatas", yNoticeSendSuccessDatas);
return result;
}
@Override
public Map<String, Object> monthSendCount(String date) {
DateTime dateDateTime = DateTime.parse(date, DateTimeFormat.forPattern(ISystemConstant.DATE_FORMATTER_YYYY_MM_DD));
DateTime firstDateTime = dateDateTime.dayOfMonth().withMinimumValue();
String startTime = firstDateTime.toString(DateTimeFormat.forPattern(ISystemConstant.DATE_FORMATTER_YYYY_MM_DD));
DateTime endDateTime = dateDateTime.dayOfMonth().withMaximumValue();
String endTime = endDateTime.toString(DateTimeFormat.forPattern(ISystemConstant.DATE_FORMATTER_YYYY_MM_DD));
List<SmsPO> smsPOs = smsService.listPOByStartTimeAndEndTime(startTime, endTime);
List<NoticePO> noticePOs = noticeService.listPOByStartTimeAndEndTime(startTime, endTime);
List<String> xDatas = new ArrayList<>();
List<Integer> ySmsSendDatas = new ArrayList<>();
List<Integer> ySmsSendSuccessDatas = new ArrayList<>();
List<Integer> yNoticeSendDatas = new ArrayList<>();
List<Integer> yNoticeSendSuccessDatas = new ArrayList<>();
int totalDay = dateDateTime.dayOfMonth().getMaximumValue();
for (int i = 0; i < totalDay; i++) {
int smsSendCount = 0;
int smsSendSuccessCount = 0;
int noticeSendCount = 0;
int noticeSendSuccessCount = 0;
DateTime dayOfWeek = dateDateTime.withDayOfMonth(i + 1);
String dayOfWeekDate = dayOfWeek.toString(DateTimeFormat.forPattern(ISystemConstant.DATE_FORMATTER_YYYY_MM_DD));
xDatas.add(dayOfWeekDate);
for (SmsPO smsPO : smsPOs) {
if (!smsPO.getGmtCreate().startsWith(dayOfWeekDate)) {
continue;
}
smsSendCount++;
if (smsPO.getSendStatus() == 1) {
smsSendSuccessCount++;
}
}
for (NoticePO noticePO : noticePOs) {
if (!noticePO.getGmtCreate().startsWith(dayOfWeekDate)) {
continue;
}
noticeSendCount++;
if (noticePO.getIsSend() == 1) {
noticeSendSuccessCount++;
}
}
ySmsSendDatas.add(smsSendCount);
ySmsSendSuccessDatas.add(smsSendSuccessCount);
yNoticeSendDatas.add(noticeSendCount);
yNoticeSendSuccessDatas.add(noticeSendSuccessCount);
}
Map<String, Object> result = new HashMap<>();
result.put("xDatas", xDatas);
result.put("ySmsSendDatas", ySmsSendDatas);
result.put("ySmsSendSuccessDatas", ySmsSendSuccessDatas);
result.put("yNoticeSendDatas", yNoticeSendDatas);
result.put("yNoticeSendSuccessDatas", yNoticeSendSuccessDatas);
return result;
}
}

View File

@ -0,0 +1,323 @@
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<base th:href="${#request.getContextPath() + '/'}">
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
</head>
<body>
<div id="app" class="layui-fluid layui-anim layui-anim-fadein">
<div class="layui-row layui-col-space15">
<!-- 发送数量,默认今日 -->
<div class="layui-col-sm6 layui-col-md6 layui-col-xs6">
<div class="layui-card">
<div class="layui-card-header">
短信发送量
<span class="layui-badge layui-bg-blue layuiadmin-badge"></span>
</div>
<div class="layui-card-body layuiadmin-card-list">
<p id="smsSendCount" class="layuiadmin-big-font">0</p>
<p>
成功率
<span class="layuiadmin-span-color">
<span id="smsSendSuccessPercent">0</span>% <i class="layui-inline fa fa-arrow-up"></i>
</span>
</p>
</div>
</div>
</div>
<div class="layui-col-sm6 layui-col-md6 layui-col-xs6">
<div class="layui-card">
<div class="layui-card-header">
通知发送量
<span class="layui-badge layui-bg-blue layuiadmin-badge"></span>
</div>
<div class="layui-card-body layuiadmin-card-list">
<p id="noticeSendCount" class="layuiadmin-big-font">0</p>
<p>
成功率
<span class="layuiadmin-span-color">
<span id="noticeSendSuccessPercent">0</span>% <i class="layui-inline fa fa-arrow-up"></i>
</span>
</p>
</div>
</div>
</div>
</div>
<!-- 周统计情况 -->
<div class="layui-row layui-col-space15">
<div class="layui-col-sm12 layui-col-md12 layui-col-xs12" style="height: 300px;">
<div id="weekSendChart" class="layui-col-xs12" style="height: 100%; background: #fff; padding: 7.5px;"></div>
</div>
</div>
<!-- 月统计情况 -->
<div class="layui-row layui-col-space15">
<div class="layui-col-sm12 layui-col-md12 layui-col-xs12" style="height: 300px;">
<div id="monthSendChart" class="layui-col-xs12" style="height: 100%; background: #fff; padding: 7.5px;"></div>
</div>
</div>
</div>
<script src="assets/js/vue.min.js"></script>
<script type="text/javascript" src="assets/js/vendor/echarts/echarts.min.js"></script>
<script src="assets/layuiadmin/layui/layui.js"></script>
<script>
layui.config({
base: 'assets/layuiadmin/'
}).extend({
index: 'lib/index'
}).use(['index', 'table', 'laydate', 'animate-numbers', 'common', 'echarts'], function() {
var $ = layui.$;
var $win = $(window);
var common = layui.common;
var resizeTimeout = null;
new Vue({
el: '#app',
data: {
count: {
smsSendCount: 0,
smsSendSuccessPercent: 0,
noticeSendCount: 0,
noticeSendSuccessPercent: 0,
}
},
methods: {
initSendCount: function(date) {
var self = this;
top.restAjax.get(top.restAjax.path('api/visual-report/unified-messaging/day-send-count/{date}', [date]), {}, null, function(code, data) {
self.count.smsSendCount = data.data.smsSendCount;
self.count.smsSendSuccessPercent = data.data.smsSendSuccessPercent;
self.count.noticeSendCount = data.data.noticeSendCount;
self.count.noticeSendSuccessPercent = data.data.noticeSendSuccessPercent;
self.$nextTick(function() {
$('#smsSendCount').animateNumbers(self.count.smsSendCount);
$('#smsSendSuccessPercent').animateNumbers(self.count.smsSendSuccessPercent);
$('#noticeSendCount').animateNumbers(self.count.noticeSendCount);
$('#noticeSendSuccessPercent').animateNumbers(self.count.noticeSendSuccessPercent);
});
}, function(code, data) {
top.dialog.msg(data.msg);
})
},
autoPlaySendCount: function(chart, option) {
var currentIndex = -1;
setInterval(function() {
var dataLen = option.series[0].data.length;
// 取消之前高亮的图形
chart.dispatchAction({
type: 'downplay',
seriesIndex: 0,
dataIndex: currentIndex
});
currentIndex = (currentIndex + 1) % dataLen;
// 高亮当前图形
chart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: currentIndex
});
// 显示 tooltip
chart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: currentIndex
});
}, 3000);
},
initWeekSendCount: function(date) {
var self = this;
top.restAjax.get(top.restAjax.path('api/visual-report/unified-messaging/week-send-count/{date}', [date]), {}, null, function(code, data) {
var option = {
title: {
text: '周短信/通知发送情况'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: data.data.xDatas
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '短信发送数量',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: data.data.ySmsSendDatas
},
{
name: '通知发送数量',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: data.data.yNoticeSendDatas
},
{
name: '短信发送成功数量',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: data.data.yNoticeSendSuccessDatas
},
{
name: '通知发送成功数量',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: data.data.ySmsSendSuccessDatas
},
]
};
var weekSendChart = echarts.init(document.getElementById('weekSendChart'));
weekSendChart.setOption(option);
self.autoPlaySendCount(weekSendChart, option);
}, function(code, data) {
top.dialog.msg(data.msg);
})
},
initMonthSendCount: function(date) {
var self = this;
top.restAjax.get(top.restAjax.path('api/visual-report/unified-messaging/month-send-count/{date}', [date]), {}, null, function(code, data) {
var option = {
title: {
text: '月短信/通知发送情况'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: data.data.xDatas
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '短信发送数量',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: data.data.ySmsSendDatas
},
{
name: '通知发送数量',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: data.data.yNoticeSendDatas
},
{
name: '短信发送成功数量',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: data.data.yNoticeSendSuccessDatas
},
{
name: '通知发送成功数量',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: data.data.ySmsSendSuccessDatas
},
]
};
var monthSendChart = echarts.init(document.getElementById('monthSendChart'));
monthSendChart.setOption(option);
self.autoPlaySendCount(monthSendChart, option);
}, function(code, data) {
top.dialog.msg(data.msg);
})
},
},
mounted: function() {
var self = this;
var date = common.formatDate('yyyy-MM-dd', new Date());
self.initSendCount(date);
self.initWeekSendCount(date);
self.initMonthSendCount(date);
$win.on('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function() {
}, 500);
});
$(document).on('click', '#search', function() {
});
}
});
});
</script>
</body>
</html>