
文章目录
一、背景
XNMS(Extended Network Management System,增强型网络管理系统)是一款远程监控和管理常规中转台的软件。中转台是系统的核心设备,所有业务都通过其进行中转。因此,只要对中转台进行监控,就能全面掌握系统的运行状况。而中转台通常部署室外,容易受到日晒雨淋等自然条件影响,造成设备损坏。为保证通讯系统正常运行,工作人员需要对中转台进行实时监控,发现中转台的异常问题,从而采取相关措施进行补救。
通过XNMS软件,工作人员可实时监控常规中转台的各项参数和告警情况,对异常问题进行排查;还可以查询或统计某时间段内中转台或终端的业务,从而全面了解常规系统的运行状况。
项目采用:Arco Design+java+mysql+springboot+vue3+nginx
二、页面
中转业务
统计和导出指定时间段内,各中转台的时隙使用情况。




从统计结果可以获知此时间段内各中转台的运行情况:
- 按日期统计:左侧通过折线图说明此时间段内该中转台时隙1和时隙2的使用情况;右侧通过环状图说明此时间段内该中转台处理各类业务的时间占比。
- 按时段统计:单击折线图下的某个日期,例如1.20,XNMS将按时间段列出当天各时间段内时隙1和时隙2的使用情况。
三、代码
TransferSingleCall.vue
java
<template>
<layout_1>
<div class="--search-line">
<div>
<div class="key">{{ $t(queryButtonValue[7]) }} </div>
<div class="val">
<a-range-picker
style="width: 280px"
:allow-clear="false"
v-model="param.timeRange"
:disabled-date="disabledDate"
>
<template #suffix-icon>
<svg-loader :width="20" :height="20" name="clock"></svg-loader>
</template>
<template #separator>
<svg-loader
:width="16"
:height="16"
name="arrow-right"
></svg-loader>
</template>
</a-range-picker>
</div>
</div>
<div>
<div class="key">{{ $t(queryButtonValue[9]) }} </div>
<div @click="radioIDsSearch" class="val select-input">
<a-select
v-model="param.radioIDs"
:multiple="true"
:max-tag-count="1"
>
<a-option
v-for="(item, index) in radioIDList"
:value="item"
:key="index"
>{{ item }}</a-option
>
</a-select>
</div>
</div>
<a-button class="huge" @click="search" type="primary">
<template #icon> <icon-search size="18" /> </template
>{{ $t(queryButtonValue[1]) }}
</a-button>
<a-button class="huge" @click="resetSearch">
<template #icon>
<svg-loader
:width="20"
:height="20"
name="reset"
></svg-loader> </template
>{{ $t(queryButtonValue[21]) }}</a-button
>
</div>
<div class="table-line">
<a-table
:data="tableData"
:bordered="false"
:pagination="false"
:scroll="{ x: '100%', y: 550 }"
>
<template #empty>
<div style="text-align: center">{{ $t("NoData") }}</div>
</template>
<template #columns>
<a-table-column
:title="$t(queryColumnValue[1])"
dataIndex="index"
:tooltip="true"
></a-table-column>
<a-table-column
dataIndex="callID"
:title="$t(queryColumnValue[20])"
:tooltip="true"
></a-table-column>
<a-table-column
dataIndex="callCount"
:title="$t(queryColumnValue[57])"
:tooltip="true"
></a-table-column>
<a-table-column
dataIndex="callTime"
:title="$t(queryColumnValue[58])"
:tooltip="true"
>
<template #cell="{ record }">
{{ formatTime(record.callTime) }}
</template>
</a-table-column>
<a-table-column
dataIndex="averageCallTime"
:title="$t(queryColumnValue[59])"
:tooltip="true"
>
<template #cell="{ record }">
{{ formatTime(record.averageCallTime) }}
</template>
</a-table-column>
</template>
</a-table>
<div class="--table-pager">
<a-config-provider :locale="arcoLang">
<a-pagination
:total="page.total"
v-model:current="page.currentPage"
v-model:page-size="page.pageSize"
@change="getTableData"
@page-size-change="getTableData"
show-total
show-page-size
show-jumper
/>
</a-config-provider>
</div>
</div>
</layout_1>
</template>
<script setup>
import { commonResponse, formatTime } from "@/views/pages/_common";
import { queryButtonValue, queryColumnValue } from "@/views/pages/_common/enum";
import Layout_1 from "@/views/pages/_common/layout_1.vue";
import {
getStatisticRadioID,
getTransferSingleCallList,
} from "@/views/pages/business/_request";
import * as moment from "moment";
import { inject, reactive, ref } from "vue";
const arcoLang = inject("arcoLang");
const param = reactive({
timeRange: [null, null],
radioIDs: [],
});
let reqParam = {
startTime: null,
endTime: null,
radioIDs: [],
};
const page = reactive({
currentPage: 1,
pageSize: 10,
total: 0,
});
const tableData = ref([]);
const getTableData = () => {
getTransferSingleCallList({
...reqParam,
currentPage: page.currentPage,
pageSize: page.pageSize,
}).then((response) => {
commonResponse({
response,
onSuccess: () => {
tableData.value = response.data;
page.total = response.pagination.totalRecords;
},
});
});
};
const radioIDList = ref([]);
const getRadioIDList = () => {
getStatisticRadioID().then((response) => {
commonResponse({
response,
onSuccess: () => {
radioIDList.value = response.data;
},
});
});
};
const disabledDate = (date) => {
return date.getTime() > moment().format("x");
};
let radioIDsSearchHasClicked = false;
const radioIDsSearch = () => {
if (!radioIDsSearchHasClicked) {
getRadioIDList(); //获取终端ID
}
radioIDsSearchHasClicked = true;
};
const search = () => {
reqParam = {
...reqParam,
...param,
};
reqParam.startTime = moment(reqParam.timeRange[0]).format(
"YYYY-MM-DDT00:00:00.000"
);
reqParam.endTime = moment(reqParam.timeRange[1]).format(
"YYYY-MM-DDT23:59:59.999"
);
delete reqParam.timeRange;
getTableData();
};
const resetSearch = () => {
init();
};
const init = () => {
param.timeRange = [moment().add(-9, "days"), moment()];
param.radioIDs = [];
page.currentPage = 1;
page.total = 0;
tableData.value = [];
};
init();
</script>
<style scoped lang="less">
.table-line {
box-sizing: border-box;
margin-top: 20px;
height: calc(100% - 60px);
}
.select-input {
width: 160px;
}
</style>
PrivateCallStatisticController
java
package com.xnms.client.service.controller.data.statistic;
import com.xnms.client.service.controller.common.ResponseModel;
import com.xnms.client.service.view.naviagation.page.data.statistice.PrivateCallStatisticUserControl;
import com.xnms.client.service.view.naviagation.page.data.statistice.StatisticSelectUserControl;
import com.xnms.data.contract.SingleResponse;
import com.xnms.data.contract.database.db.Pagination;
import com.xnms.data.contract.database.db.QueryConditionBase;
import com.xnms.data.contract.database.db.RepeaterBusinessCallData;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Api(tags = "业务统计 - 中转个呼")
@RestController
@RequestMapping("/api/private_call_statistic")
public class PrivateCallStatisticController implements InitializingBean {
private static final Logger logger = LoggerFactory.getLogger(PrivateCallStatisticController.class);
@Autowired
private StatisticSelectUserControl statisticSelectUserControl;
@Autowired
private PrivateCallStatisticUserControl privateCallStatisticUserControl;
@Override
public void afterPropertiesSet() throws Exception {
}
@Operation(summary = "终端ID,与数据查询里的枚举不一样,这个没有新增的动作")
@GetMapping(value = "/radios")
public ResponseModel<List<Integer>> radiosType() {
logger.info("PrivateCallStatisticController,radiosType start...");
return ResponseModel.ofSuccess(privateCallStatisticUserControl.radiosType());
}
@Operation(summary = "统计列表")
@PostMapping
public ResponseModel<List<RepeaterBusinessCallData>> statisticPrivateCall(@RequestBody QueryConditionBase queryConditionBase) {
logger.info("PrivateCallStatisticController,statisticPrivateCall:queryConditionBase = [{}]", queryConditionBase);
String msg = statisticSelectUserControl.verifyPrivateCallQueryCondition(queryConditionBase, "GetPrivateCallStatisticeDataFailed");
if (!StringUtils.isBlank(msg)) {
return ResponseModel.ofError(msg);
}
SingleResponse<List<RepeaterBusinessCallData>> businessDetailDataResult = privateCallStatisticUserControl.statisticPrivateCall(queryConditionBase);
return ResponseModel.ofSuccess(businessDetailDataResult.getData(), Pagination.of(queryConditionBase.getCurrentPage(), queryConditionBase.getPageSize(), businessDetailDataResult.getTotalCount()));
}
}
DataStatisticServImpl
java
package com.xnms.data.service.service.impl.client;
import com.xnms.data.contract.client.CustomTeleTrafficStatisticTable;
import com.xnms.data.contract.client.GroupTeleTrafficStatisticTable;
import com.xnms.data.contract.client.RadioTeleTrafficStatisticTable;
import com.xnms.data.contract.database.db.*;
import com.xnms.data.service.dao.*;
import com.xnms.data.service.service.impl.terminal.TerminalGroupServiceImpl;
import com.xnms.data.service.service.impl.terminal.TerminalServiceImpl;
import com.xnms.data.service.util.RptStatisticUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
public class DataStatisticServImpl {
private static final Logger logger = LoggerFactory.getLogger(DataStatisticServImpl.class);
@Autowired
private StacSiteDao stacSiteDao;
@Autowired
private StacRptDao stacRptDao;
@Autowired
private StacUserTrafficDao stacUserTrafficDao;
@Autowired
private StacGroupTrafficDao stacGroupTrafficDao;
@Autowired
private StacRssiDao stacRssiDao;
@Autowired
private CustomTrafficDao customTrafficDao;
@Autowired
private StacPrivateCallDao stacPrivateCallDao;
@Autowired
private StacGroupCallDao stacGroupCallDao;
@Autowired
private TerminalServiceImpl terminalService;
@Autowired
private TerminalGroupServiceImpl terminalGroupService;
public List<SiteStatisticDataResult> querySiteStatisticData(QueryConditionBase query) {
try {
return stacSiteDao.getSiteStaticesData(query.getSiteIDs(), query.getStartTime(), query.getEndTime());
} catch (Exception ex) {
logger.error("[DataStatisticServImpl] querySiteStatisticData: " + ex.getMessage() +
(ex.getCause() != null ? "\n" + ex.getCause().getMessage() : ""), ex);
return new ArrayList<>(); // Return an empty list
}
}
public List<RepeaterStatisticDay> queryRepeaterStatisticDayData(QueryConditionBase query) {
try {
return stacRptDao.getRepeaterStaticesDayData(query.getRepeaterSNs(), query.getStartTime(), query.getEndTime());
} catch (Exception ex) {
logger.error("[DataStatisticServImpl] queryRepeaterStatisticDayData: " + ex.getMessage() +
(ex.getCause() != null ? "\n" + ex.getCause().getMessage() : ""), ex);
return new ArrayList<>(); // 返回一个空列表
}
}
public List<RepeaterStatisticHour> queryRepeaterStatisticHourData(QueryConditionBase query) {
try {
List<RepeaterStatisticHour> rptHour = new ArrayList<>();
List<StatRpt> rptDay = new ArrayList<>();
// 调用DAO方法获取数据
rptDay = stacRptDao.getRepeaterStaticesHourData(query.getStartTime(), query.getEndTime(), query.getRepeaterSNs());
// 分割天数据到小时数据
rptHour = RptStatisticUtil.splitDayToHour(rptDay);
return rptHour;
} catch (Exception ex) {
// 记录异常
logger.error("[DataStatisticServImpl] queryRepeaterStatisticHourData: " + ex.getMessage() +
(ex.getCause() != null ? "\n" + ex.getCause().getMessage() : ""), ex);
return new ArrayList<>(); // 返回一个空列表
}
}
public List<StatUserTraffic> getUserTrafficStatisticDetail(QueryConditionBase queryCondition) {
List<StatUserTraffic> result = new ArrayList<>();
// 检查查询条件是否为 null
if (queryCondition == null) {
return result; // 返回空列表
}
try {
// 调用 DAO 方法获取用户流量数据
result = stacUserTrafficDao.obtainRadioTeleTrafficDataDetail(queryCondition);
} catch (Exception ex) {
// 记录异常
logger.error("[DataStatisticServImpl] getUserTrafficStatisticDetail: " + ex.getMessage() +
(ex.getCause() != null ? "\n" + ex.getCause().getMessage() : ""), ex);
}
return result; // 返回结果
}
public int getUserTrafficStatisticCount(QueryConditionBase queryCondition) {
int totalCount = 0;
// 检查查询条件是否为 null
if (queryCondition == null) {
return totalCount; // 返回 0
}
try {
// 调用 DAO 方法获取用户流量统计数量
totalCount = stacUserTrafficDao.obtainRadioTeleTrafficCount(queryCondition);
} catch (Exception ex) {
// 记录异常
logger.error("[DataStatisticServImpl] getUserTrafficStatisticCount: " + ex.getMessage() +
(ex.getCause() != null ? "\n" + ex.getCause().getMessage() : ""), ex);
}
return totalCount; // 返回总数量
}
public List<RadioTeleTrafficStatisticTable> getUserTrafficStatistic(QueryConditionBase queryCondition, int pageIndex, int pageSize) {
List<RadioTeleTrafficStatisticTable> result = new ArrayList<>();
// 检查查询条件是否为 null
if (queryCondition == null) {
return result; // 返回空列表
}
try {
// 调用 DAO 方法获取用户流量统计数据
result = stacUserTrafficDao.obtainRadioTeleTrafficData(queryCondition, pageIndex, pageSize);
} catch (Exception ex) {
// 记录异常
logger.error("[DataStatisticServImpl] getUserTrafficStatistic: " + ex.getMessage() +
(ex.getCause() != null ? "\n" + ex.getCause().getMessage() : ""), ex);
}
return result; // 返回结果列表
}
public int getGroupTrafficStatisticCount(QueryConditionBase queryCondition) {
int totalCount = 0;
// 检查查询条件是否为 null
if (queryCondition == null) {
return totalCount; // 返回计数 0
}
try {
// 调用 DAO 方法获取组流量统计计数
totalCount = stacGroupTrafficDao.obtainGroupTeleTrafficCount(queryCondition);
} catch (Exception ex) {
// 记录异常
logger.error("[DataStatisticServImpl] getGroupTrafficStatisticCount: " + ex.getMessage() +
(ex.getCause() != null ? "\n" + ex.getCause().getMessage() : ""), ex);
}
return totalCount; // 返回计数
}
public List<GroupTeleTrafficStatisticTable> getGroupTrafficStatistic(QueryConditionBase queryCondition, int pageIndex, int pageSize) {
List<GroupTeleTrafficStatisticTable> result = new ArrayList<>();
// 检查查询条件是否为 null
if (queryCondition == null) {
return result; // 返回空列表
}
try {
// 调用 DAO 方法获取组流量统计数据
result = stacGroupTrafficDao.obtainGroupTeleTrafficData(queryCondition, pageIndex, pageSize);
} catch (Exception ex) {
// 记录异常
logger.error("[DataStatisticServImpl] getGroupTrafficStatistic: " + ex.getMessage() +
(ex.getCause() != null ? "\n" + ex.getCause().getMessage() : ""), ex);
}
return result; // 返回结果列表
}
public List<StatRssi> getRssiProportionStatistic(QueryConditionBase queryCondition) {
List<StatRssi> result = new ArrayList<>();
// 检查查询条件是否为 null 或者某些属性为空
if (queryCondition == null || queryCondition.getStartTime() == null || queryCondition.getEndTime() == null || queryCondition.getRepeaterSNs() == null) {
return result; // 返回空列表
}
try {
// 调用 DAO 方法获取 RSSI 统计数据
result = stacRssiDao.obtainRssiStatisticData(queryCondition.getStartTime(), queryCondition.getEndTime(), queryCondition.getRepeaterSNs());
} catch (Exception ex) {
// 记录异常
logger.error("[DataStatisticServImpl] getRssiProportionStatistic: " + ex.getMessage() +
(ex.getCause() != null ? "\n" + ex.getCause().getMessage() : ""), ex);
}
return result; // 返回结果列表
}
public int getCustomTrafficStatisticCount(QueryConditionBase queryCondition) {
int totalCount = 0;
// 检查查询条件是否为 null
if (queryCondition == null) {
return totalCount; // 返回 0
}
try {
// 调用 DAO 方法获取自定义流量统计计数
totalCount = customTrafficDao.getCustomTrafficStatisticCount(queryCondition);
} catch (Exception ex) {
// 记录异常
logger.error("[DataStatisticServImpl] getUserTrafficStatisticCount: " + ex.getMessage() +
(ex.getCause() != null ? "\n" + ex.getCause().getMessage() : ""), ex);
}
return totalCount; // 返回总计数
}
public List<CustomTeleTrafficStatisticTable> getCustomTrafficStatistic(QueryConditionBase queryCondition, int pageIndex, int pageSize) {
List<CustomTeleTrafficStatisticTable> result = new ArrayList<>(); // 初始化结果列表
// 检查查询条件是否为 null
if (queryCondition == null) {
return result; // 返回空列表
}
try {
// 调用 DAO 方法获取自定义流量统计
result = customTrafficDao.getCustomTrafficStatistic(queryCondition, pageIndex, pageSize);
int startIndex = (pageIndex - 1) * pageSize;
int i = 0;
for (CustomTeleTrafficStatisticTable item : result) {
item.setIndex(startIndex + i + 1);
i++;
}
} catch (Exception ex) {
// 记录异常
logger.error("[DataStatisticServImpl] getCustomTrafficStatistic: " + ex.getMessage() +
(ex.getCause() != null ? "\n" + ex.getCause().getMessage() : ""), ex);
}
return result; // 返回结果列表
}
public RepeaterBusinessCallDatatResult queryBusinessCallData(List<Integer> callIDs, Date startTime, Date endTime, int callType, int pageCount, int pageIndex) {
try {
RepeaterBusinessCallDatatResult result = new RepeaterBusinessCallDatatResult(); // 初始化结果对象
// 根据 callType 调用不同的 DAO 方法
if (callType == 1) {
result = stacGroupCallDao.getGroupCallStaticesInfo(callIDs, startTime, endTime, pageCount, pageIndex);
} else if (callType == 0) {
result = stacPrivateCallDao.getSingleCallStaticesInfo(callIDs, startTime, endTime, pageCount, pageIndex);
}
return result; // 返回结果
} catch (Exception ex) {
// 记录异常信息
logger.error("[DataStatisticServImpl] queryBusinessCallData: " + ex.getMessage() +
(ex.getCause() != null ? "\n" + ex.getCause().getMessage() : ""), ex);
return new RepeaterBusinessCallDatatResult(); // 返回一个新的结果对象
}
}
public int queryBusinessCallDataCount(List<Integer> callIDs, Date startTime, Date endTime, int callType) {
int result = 0;
try {
// 根据 callType 调用不同的 DAO 方法
if (callType == 1) {
result = stacGroupCallDao.getGroupCallStaticesCount(callIDs, startTime, endTime);
} else if (callType == 0) {
result = stacPrivateCallDao.getSingleCallStaticesCount(callIDs, startTime, endTime);
}
return result; // 返回结果
} catch (Exception ex) {
// 记录异常信息
logger.error("[DataStatisticServImpl] queryBusinessCallDataCount: " + ex.getMessage() +
(ex.getCause() != null ? "\n" + ex.getCause().getMessage() : ""), ex);
return result; // 返回一个新的结果对象
}
}
// 前端组ID+终端ID
public RepeaterBusinessCallIDResult getRepeaterBusinessCallIDs() {
RepeaterBusinessCallIDResult callIDResult = new RepeaterBusinessCallIDResult(); // 初始化结果对象
try {
callIDResult.setPrivateCallIDs(terminalService.getDistinctAll());
callIDResult.setGroupCallIDs(terminalGroupService.getDistinctAll());
} catch (Exception ex) {
// 记录异常信息
logger.error("[DataStatisticServImpl] getRepeaterBusinessCallIDs: " + ex.getMessage() +
(ex.getCause() != null ? "\n" + ex.getCause().getMessage() : ""), ex);
}
return callIDResult; // 返回结果
}
}
StacPrivateCallDaoImpl
java
package com.xnms.data.service.dao.mysql.impl;
import com.xnms.data.contract.database.db.RepeaterBusinessCallData;
import com.xnms.data.contract.database.db.RepeaterBusinessCallDatatResult;
import com.xnms.data.service.dao.StacPrivateCallDao;
import com.xnms.data.service.entity.StacPrivateCallEntity;
import com.xnms.data.service.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
@Repository
public class StacPrivateCallDaoImpl implements StacPrivateCallDao {
private static final Logger logger = LoggerFactory.getLogger(StacPrivateCallDaoImpl.class);
private static final SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
private static final SimpleDateFormat YMDHMS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@PersistenceContext
private EntityManager entityManager;
private String getSql(String sqlBuilder) {
String sql = sqlBuilder;
if (sql.endsWith(";")) {
sql = sql.substring(0, sql.length() - 1);
}
sql = "SELECT UUID() as uuid, rbres.* from ( " + sql + " ) rbres";
return sql;
}
private String getSqlCount(String sqlBuilder) {
String sql = sqlBuilder;
if (sql.endsWith(";")) {
sql = sql.substring(0, sql.length() - 1);
}
sql = "SELECT count(1) from ( " + sql + " ) rbres";
return sql;
}
@Override
public List<StacPrivateCallEntity> getStacPrivateCallEntityList(Date fromTime, Date endTime) {
List<StacPrivateCallEntity> stacPrivateCallEntityList = new ArrayList<>();
String sql = "SELECT RADIOID,DATE,COUNT,CALLTIME,AvgCallTime AVGCALLTIME FROM stac_privatecall_day sp WHERE sp.Date >= :fromTime AND sp.Date <= :endTime";
try {
Query query = entityManager.createNativeQuery(getSql(sql), StacPrivateCallEntity.class);
query.setParameter("fromTime", yyyyMMdd.format(fromTime));
query.setParameter("endTime", yyyyMMdd.format(endTime));
// 执行查询并获取结果列表
stacPrivateCallEntityList = query.getResultList();
} catch (Exception ex) {
// 记录错误信息
logger.error("<StacPrivateCallDaoImpl getStacPrivateCallEntityList> Error: {}, SQL: {}", ex.getMessage(), sql, ex);
}
return stacPrivateCallEntityList;
}
@Override
public List<StacPrivateCallEntity> getStacPrivateCallEntityList() {
return null;
}
@Override
public void insertOrUpdateStacPrivateCallEntityList(List<String> sqlList) {
}
@Transactional
@Override
public Boolean doStacPrivateCall() {
List<String> sqlList = new ArrayList<>();
try {
for (int i = 0; i < 2; i++) {
// 计算日期
String date = yyyyMMdd.format(getDate(i - 1));
// 删除语句
String deleteSql = String.format("DELETE FROM stac_privatecall_day WHERE date='%s';", date);
// 获取表名
String tableName = DateUtil.convertStartTimeToTableName(getDate(i - 1));
// 插入语句
String insertSql = String.format("INSERT INTO stac_privatecall_day (radioid, date, count, calltime, avgcalltime) " +
"(SELECT senderid AS radioid, " +
"DATE_FORMAT(starttime, '%%Y-%%m-%%d') AS date, " +
"COUNT(*) AS count, " +
"SUM(duration) AS calltime, " +
"0 AS avgcalltime FROM %s " +
"WHERE type = 1 " +
"AND (calltype = 0 OR calltype = 6) " +
"AND DATE_FORMAT(starttime, '%%Y-%%m-%%d') = '%s' " +
"GROUP BY radioid, date);", tableName, date);
// 将 SQL 添加到列表中
sqlList.add(deleteSql);
sqlList.add(insertSql);
}
// 执行 SQL
if (!sqlList.isEmpty()) {
for (String sql : sqlList) {
Query query = entityManager.createNativeQuery(sql);
query.executeUpdate(); // 执行 SQL
}
}
return true;
} catch (Exception ex) {
// 记录错误日志
logger.error("StacPrivateCallDaoImpl类,doStacPrivateCall方法:sqlList:{}", sqlList, ex);
return false;
}
}
// 计算日期方法
private Date getDate(int daysOffset) {
return new Date(System.currentTimeMillis() + (daysOffset * 24L * 60L * 60L * 1000L));
}
@Override
public RepeaterBusinessCallDatatResult getSingleCallStaticesInfo(List<Integer> radioIds, Date startTime, Date endTime, int pageCount, int pageIndex) {
RepeaterBusinessCallDatatResult calls = new RepeaterBusinessCallDatatResult();
StringBuilder sql = new StringBuilder();
StringBuilder where = new StringBuilder();
sql.append("SELECT s.RADIOID, SUM(s.COUNT) AS COUNT, SUM(s.CallTime) AS CALLTIME,NOW() DATE,'' as AVGCALLTIME FROM stac_privatecall_day s ");
where.append(" WHERE 1=1 ");
if (radioIds != null && radioIds.size() > 0) {
String radioIdList = String.join(",", radioIds.stream().map(String::valueOf).toArray(String[]::new));
where.append("AND s.RadioID IN (").append(radioIdList).append(") ");
}
if (startTime != null) {
where.append("AND s.Date >= :fromDate ");
}
if (endTime != null) {
where.append("AND s.Date <= :toDate ");
}
int offset = (pageIndex - 1) * pageCount;
where.append("GROUP BY s.RadioID LIMIT :offset, :pageCount");
sql.append(where);
Query query = entityManager.createNativeQuery(getSql(sql.toString()), StacPrivateCallEntity.class);
if (startTime != null) {
query.setParameter("fromDate", yyyyMMdd.format(startTime));
}
if (endTime != null) {
query.setParameter("toDate", yyyyMMdd.format(endTime));
}
query.setParameter("offset", offset);
query.setParameter("pageCount", pageCount);
try {
List<StacPrivateCallEntity> resultList = query.getResultList();
if (resultList.isEmpty()) {
return calls;
}
int startIndex = (pageIndex - 1) * pageCount;
int i = 0;
for (StacPrivateCallEntity spc : resultList) {
long averageCallTime = spc.getCount() == 0 ? 0 : spc.getCallTime() / spc.getCount();
spc.setAvgCallTime(averageCallTime);
RepeaterBusinessCallData call = new RepeaterBusinessCallData();
call.setIndex(startIndex + i + 1);
call.setCallID(spc.getRadioId());
call.setCallTime(spc.getCallTime());
call.setCallCount(spc.getCount());
call.setAverageCallTime(spc.getAvgCallTime());
calls.getDatas().put(call.getCallID(), call);
i++;
}
} catch (Exception e) {
logger.error("StacPrivateCallDaoImpl类,getSingleCallStaticesInfo方法:", e);
}
return calls;
}
@Override
public int getSingleCallStaticesCount(List<Integer> radioIds, Date startTime, Date endTime) {
int count = 0;
RepeaterBusinessCallDatatResult calls = new RepeaterBusinessCallDatatResult();
StringBuilder sql = new StringBuilder();
StringBuilder where = new StringBuilder();
sql.append("SELECT s.RADIOID, SUM(s.COUNT) AS COUNT, SUM(s.CallTime) AS CALLTIME,NOW() DATE,'' as AVGCALLTIME FROM stac_privatecall_day s ");
where.append(" WHERE 1=1 ");
if (radioIds != null && radioIds.size() > 0) {
String radioIdList = String.join(",", radioIds.stream().map(String::valueOf).toArray(String[]::new));
where.append("AND s.RadioID IN (").append(radioIdList).append(") ");
}
if (startTime != null) {
where.append("AND s.Date >= :fromDate ");
}
if (endTime != null) {
where.append("AND s.Date <= :toDate ");
}
where.append("GROUP BY s.RadioID ");
sql.append(where);
Query query = entityManager.createNativeQuery(getSqlCount(sql.toString()));
if (startTime != null) {
query.setParameter("fromDate", yyyyMMdd.format(startTime));
}
if (endTime != null) {
query.setParameter("toDate", yyyyMMdd.format(endTime));
}
try {
Object result = query.getSingleResult();
return ((Number) result).intValue();
} catch (Exception e) {
logger.error("StacPrivateCallDaoImpl类,getSingleCallStaticesCount:", e);
}
return count;
}
@Override
public HashSet<Integer> getRepeaterPrivateCallIDs() {
return null;
}
@Transactional
@Override
public Boolean doStacPrivateCall(Date stacDate, Date todayStart, Date tomorrowStart) {
List<String> sqlList = new ArrayList<>();
try {
// 格式化日期为 "yyyy-MM-dd"
String formattedDate = yyyyMMdd.format(stacDate);
// 构造 DELETE SQL
String deleteSql = String.format("DELETE FROM stac_privatecall_day WHERE date='%s';", formattedDate);
// 获取表名
String tableName = DateUtil.convertStartTimeToTableName(stacDate);
// 构造 INSERT SQL
String insertSql = String.format("INSERT INTO stac_privatecall_day (radioid, date, count, calltime, avgcalltime) " +
"(SELECT senderid AS radioid, " +
"DATE_FORMAT(starttime, '%%Y-%%m-%%d') AS date, " +
"COUNT(*) AS count, " +
"SUM(duration) AS calltime, " +
"0 AS avgcalltime FROM %s " +
"WHERE type = 1 " +
"AND CALLTYPE in (0,6) " +
"AND STARTTIME between '%s' and '%s' " +
"GROUP BY radioid, date);", tableName, YMDHMS.format(todayStart), YMDHMS.format(tomorrowStart));
// 将 DELETE 和 INSERT SQL 加入列表
sqlList.add(deleteSql);
sqlList.add(insertSql);
// 执行 SQL
if (!sqlList.isEmpty()) {
for (String sql : sqlList) {
Query query = entityManager.createNativeQuery(sql);
query.executeUpdate(); // 执行 SQL
}
}
return true;
} catch (Exception ex) {
// 记录异常日志
logger.error("StacPrivateCallDaoImpl类,doStacPrivateCall方法:sqlList:{}", sqlList, ex);
return false;
}
}
}
StacGroupCallDaoImpl
java
package com.xnms.data.service.dao.mysql.impl;
import com.xnms.data.contract.database.db.RepeaterBusinessCallData;
import com.xnms.data.contract.database.db.RepeaterBusinessCallDatatResult;
import com.xnms.data.service.dao.StacGroupCallDao;
import com.xnms.data.service.entity.StacGroupCallEntity;
import com.xnms.data.service.util.DBUtil;
import com.xnms.data.service.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
@Repository
public class StacGroupCallDaoImpl implements StacGroupCallDao {
private static final Logger logger = LoggerFactory.getLogger(StacGroupCallDaoImpl.class);
private static final SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
private static final SimpleDateFormat YMDHMS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@PersistenceContext
private EntityManager entityManager;
@Autowired
private DBUtil dbUtil;
private String getSql(String sqlBuilder) {
String sql = sqlBuilder;
if (sql.endsWith(";")) {
sql = sql.substring(0, sql.length() - 1);
}
sql = "SELECT UUID() as uuid, rbres.* from ( " + sql + " ) rbres";
return sql;
}
private String getSqlCount(String sqlBuilder) {
String sql = sqlBuilder;
if (sql.endsWith(";")) {
sql = sql.substring(0, sql.length() - 1);
}
sql = "SELECT count(1) from ( " + sql + " ) rbres";
return sql;
}
@Override
public List<StacGroupCallEntity> getStacGroupCallEntityList(Date fromTime, Date endTime) {
List<StacGroupCallEntity> stacGroupCallEntityList;
String sql = "SELECT sg.* FROM stac_groupcall_day sg WHERE sg.date >= ? AND sg.date <= ?";
try {
Query query = entityManager.createNativeQuery(getSql(sql), StacGroupCallEntity.class);
query.setParameter(1, yyyyMMdd.format(fromTime));
query.setParameter(2, yyyyMMdd.format(endTime));
stacGroupCallEntityList = query.getResultList();
} catch (Exception ex) {
logger.error("<StacGroupCallDaoImpl getStacGroupCallEntityList> Error: {}, JPQL: {}", ex.getMessage(), sql, ex);
throw ex; // 可以选择重新抛出异常
}
return stacGroupCallEntityList;
}
@Override
public List<StacGroupCallEntity> getStacGroupCallEntityList() {
return null;
}
@Override
public void insertOrUpdateStacGroupCallEntityList(List<String> sqlList) {
}
@Transactional
@Override
public boolean doStacGroupCall() {
List<String> sqlList = new ArrayList<>();
try {
// Loop to generate SQL for the last 2 days
for (int i = 0; i < 2; i++) {
// Format the date for the current iteration (i-1 days from today)
String formattedDate = yyyyMMdd.format(new Date(System.currentTimeMillis() + (i - 1) * 24L * 60L * 60L * 1000L));
// Delete SQL
String deleteSql = String.format("DELETE FROM stac_groupcall_day WHERE date='%s';", formattedDate);
sqlList.add(deleteSql);
// Get the table name using the helper method
String tableName = DateUtil.convertStartTimeToTableName(new Date(System.currentTimeMillis() + (i - 1) * 24L * 60L * 60L * 1000L));
// Insert SQL
String insertSql = String.format(
"INSERT INTO stac_groupcall_day (groupId, date, count, calltime, avgcalltime) " +
"SELECT targetid AS groupid, DATE_FORMAT(starttime, '%%Y-%%m-%%d') AS date, " +
"COUNT(*) AS count, SUM(duration) AS calltime, 0 AS avgcalltime " +
"FROM %s " +
"WHERE type = 1 AND (calltype = 1 OR calltype = 2 OR calltype = 3 OR calltype = 7 OR calltype = 8) " +
"AND DATE_FORMAT(starttime, '%%Y-%%m-%%d') = '%s' " +
"GROUP BY groupid, date;",
tableName, formattedDate
);
sqlList.add(insertSql);
}
// Execute the SQL batch if any SQL statements are present
if (!sqlList.isEmpty()) {
for (String sql : sqlList) {
Query query = entityManager.createNativeQuery(sql);
query.executeUpdate();
}
}
return true;
} catch (Exception ex) {
// Log error if exception occurs
logger.error("<StacGroupCallDaoImpl doStacGroupCall> Error: " + ex.getMessage(), ex);
return false;
}
}
@Override
public RepeaterBusinessCallDatatResult getGroupCallStaticesInfo(List<Integer> callIDs, Date startTime, Date endTime, int pageCount, int pageIndex) {
RepeaterBusinessCallDatatResult calls = new RepeaterBusinessCallDatatResult();
StringBuilder sql = new StringBuilder();
StringBuilder where = new StringBuilder();
sql.append("SELECT s.GroupID GROUPID, SUM(s.Count) AS COUNT, SUM(s.CallTime) AS CALLTIME,NOW() DATE,'' as AVGCALLTIME ");
sql.append("FROM stac_groupcall_day s ");
where.append("WHERE 1=1 ");
// Handling RadioIDs condition
if (callIDs != null && callIDs.size() > 0) {
String radioIdString = String.join(",", callIDs.stream().map(String::valueOf).toArray(String[]::new));
where.append(" AND s.GroupID IN (").append(radioIdString).append(") ");
}
// Handling date conditions
if (startTime != null) {
where.append(" AND s.Date >= :Fdate ");
}
if (endTime != null) {
where.append(" AND s.Date <= :Tdate ");
}
// Adding pagination
int offset = (pageIndex - 1) * pageCount;
where.append("GROUP BY s.GroupID ");
where.append("LIMIT :offset, :pagecount");
sql.append(where.toString());
try {
// Create a native query
Query query = entityManager.createNativeQuery(getSql(sql.toString()), StacGroupCallEntity.class);
// Setting parameters for the query
if (startTime != null) {
query.setParameter("Fdate", yyyyMMdd.format(startTime));
}
if (endTime != null) {
query.setParameter("Tdate", yyyyMMdd.format(endTime));
}
query.setParameter("offset", offset);
query.setParameter("pagecount", pageCount);
// Execute query
int startIndex = (pageIndex - 1) * pageCount;
int i = 0;
List<StacGroupCallEntity> resultList = query.getResultList();
for (StacGroupCallEntity spc : resultList) {
long averageCallTime = spc.getCount() == 0 ? 0 : spc.getCallTime() / spc.getCount();
spc.setAvgCallTime(averageCallTime);
RepeaterBusinessCallData call = new RepeaterBusinessCallData();
call.setIndex(startIndex + i + 1);
call.setCallID(spc.getGroupId());
call.setCallTime(spc.getCallTime());
call.setCallCount(spc.getCount());
call.setAverageCallTime(spc.getAvgCallTime());
calls.getDatas().put(call.getCallID(), call);
i++;
}
} catch (Exception e) {
logger.error("StacGroupCallDaoImpl类,getGroupCallStaticesInfo方法:", e);
}
return calls;
}
@Override
public int getGroupCallStaticesCount(List<Integer> callIDs, Date startTime, Date endTime) {
int count = 0;
StringBuilder sql = new StringBuilder();
StringBuilder where = new StringBuilder();
sql.append("SELECT s.GroupID GROUPID, SUM(s.Count) AS COUNT, SUM(s.CallTime) AS CALLTIME,NOW() DATE,'' as AVGCALLTIME ");
sql.append("FROM stac_groupcall_day s ");
where.append("WHERE 1=1 ");
// Handling RadioIDs condition
if (callIDs != null && callIDs.size() > 0) {
String radioIdString = String.join(",", callIDs.stream().map(String::valueOf).toArray(String[]::new));
where.append(" AND s.GroupID IN (").append(radioIdString).append(") ");
}
// Handling date conditions
if (startTime != null) {
where.append(" AND s.Date >= :Fdate ");
}
if (endTime != null) {
where.append(" AND s.Date <= :Tdate ");
}
where.append("GROUP BY s.GroupID ");
sql.append(where.toString());
try {
// Create a native query
Query query = entityManager.createNativeQuery(getSqlCount(sql.toString()));
// Setting parameters for the query
if (startTime != null) {
query.setParameter("Fdate", yyyyMMdd.format(startTime));
}
if (endTime != null) {
query.setParameter("Tdate", yyyyMMdd.format(endTime));
}
Object result = query.getSingleResult();
return ((Number) result).intValue();
} catch (Exception e) {
logger.error("StacGroupCallDaoImpl类,getGroupCallStaticesCount方法:", e);
}
return count;
}
@Override
public HashSet<Integer> getRepeaterGroupCallIDs() {
return null;
}
@Transactional
@Override
public boolean doStacGroupCall(Date stacDate, Date todayStart, Date tomorrowStart) {
List<String> sqlList = new ArrayList<>();
try {
// Delete SQL query
String deleteSql = String.format(
"DELETE FROM stac_groupcall_day WHERE date='%s';",
yyyyMMdd.format(stacDate)
);
// Get table name based on the given date
String tableName = DateUtil.convertStartTimeToTableName(stacDate);
// Insert SQL query
String insertSql = String.format(
"INSERT INTO stac_groupcall_day (groupId, date, count, calltime, avgcalltime) " +
"SELECT " +
"targetid AS groupid, " +
"DATE_FORMAT(starttime, '%%Y-%%m-%%d') AS date, " +
"COUNT(*) AS count, " +
"SUM(duration) AS calltime, " +
"0 AS avgcalltime " +
"FROM %s " +
"WHERE type = 1 " +
"AND CALLTYPE in (1,2,3,7,8) " +
"AND STARTTIME between '%s' and '%s' " +
"GROUP BY groupid, date;",
tableName, YMDHMS.format(todayStart), YMDHMS.format(tomorrowStart)
);
// Add SQL queries to the list
sqlList.add(deleteSql);
sqlList.add(insertSql);
// Execute batch queries if list is not empty
if (!sqlList.isEmpty()) {
dbUtil.executeBatchQueries(sqlList, entityManager);
}
return true;
} catch (Exception ex) {
logger.error("<StacGroupCallDaoImpl doStacGroupCall> Error: {}, Sql: {}", ex.getMessage(), sqlList);
return false;
}
}
}