
文章目录
- 一、背景
- 二、页面
- 三、代码
-
- DatabaseManage.vue
- TaskManageServiceImpl
- StacGroupCallDaoImpl
- StacPrivateCallDaoImpl
- StacRptDaoImpl
- StacUserTrafficDaoImpl
- StacGroupTrafficDaoImpl
- StacRssiDaoImpl
- StacSiteDaoImpl
- stac_groupcall_day表:中转组呼
- stac_privatecall_day表:中转个呼
- stac_rpt表:中转业务
- stac_usertraffic_day表:终端业务
- stac_grouptraffic_day表:终端组业务
- stac_rssi_day表:中转台RSSI
- stac_site_day表:站点统计
- 四、说明
- 五、本人其他相关文章链接
一、背景
XNMS(Extended Network Management System,增强型网络管理系统)是一款远程监控和管理常规中转台的软件。中转台是系统的核心设备,所有业务都通过其进行中转。因此,只要对中转台进行监控,就能全面掌握系统的运行状况。而中转台通常部署室外,容易受到日晒雨淋等自然条件影响,造成设备损坏。为保证通讯系统正常运行,工作人员需要对中转台进行实时监控,发现中转台的异常问题,从而采取相关措施进行补救。
通过XNMS软件,工作人员可实时监控常规中转台的各项参数和告警情况,对异常问题进行排查;还可以查询或统计某时间段内中转台或终端的业务,从而全面了解常规系统的运行状况。
数据库同步在进行业务统计时,当天的数据可能无法及时同步至数据库中,为确保业务统计的正确性,您可以单击"开始同步",选择同步的日期,将当天的数据同步更新至数据服务的数据库中,
最终会统计7种不同业务的数据入库,用于后续业务统计页面查询使用。
前提我们的各种业务表的统计是基于中转台/终端基础业务表数据进行归类统计的,业务统计表采用项目初始化自动生成,一周一张表,一次性把一年所有周的表都创建出来。

二、页面


三、代码
DatabaseManage.vue
java
<template>
<a-spin
:size="80"
:loading="uploadeLoading"
:tip="spinTip"
style="width: 100%; height: 100%"
>
<layout_1>
<a-scrollbar outer-class="setting-scroll" style="padding: 0 4px; height: 100%; overflow: scroll">
<div class="param" style="margin-top: 0">
<a-spin style="width: 70%">
<div class="param-title">
<div class="param-title-text">{{$t('DatabaseCleanUp')}}:</div>
</div>
<div class="param-content">
<a-button @click="databaseCleanupFunction">{{$t('StartCleanUp')}}</a-button>
<param-item style="display: flex;align-items: center;gap: 20px">
<template #label><span class="label">{{$t('CleanupData')}}</span></template>
<a-select v-model="cleanupData" style="width: 260px;margin-top: -8px">
<a-option value="0" :label="$t('OneMonthAgo')"></a-option>
<a-option value="1" :label="$t('TwoMonthAgo')"></a-option>
<a-option value="2" :label="$t('ThreeMonthAgo')"></a-option>
</a-select>
</param-item>
</div>
</a-spin>
</div>
<div class="param">
<a-spin style="width: 70%">
<div class="param-title">
<div class="param-title-text">{{$t('DatabaseSynchronization')}}:</div>
</div>
<div class="param-content">
<a-button @click="databaseSynchronizationFunction">{{$t('StartSynchronous')}}</a-button>
<param-item style="display: flex;align-items: center;gap: 20px">
<template #label><span class="label">{{$t('SynchronousData')}}</span></template>
<a-date-picker style="width: 260px;margin-top: -8px" v-model="synchronousData" :placeholder="$t('GroupTrafficStatis_PleaseSelect') + $t('Custom_Report_Date')" :disabledDate="(current) => dayjs(current).isAfter(dayjs())"></a-date-picker>
</param-item>
</div>
</a-spin>
</div>
<div class="param">
<a-spin style="width: 70%">
<div class="param-title">
<div class="param-title-text">{{$t('DatabaseBackup')}}:</div>
</div>
<div class="param-content">
<a-button @click="backupDatabaseFunction">{{$t('DatabaseBackup')}}</a-button>
</div>
</a-spin>
</div>
<div class="param">
<a-spin style="width: 70%">
<div class="param-title">
<div class="param-title-text">{{$t('DatabaseShrink')}}:</div>
</div>
<div class="param-content">
<a-button @click="tarDatabaseFunction">{{$t('DatabaseShrink')}}</a-button>
</div>
</a-spin>
</div>
</a-scrollbar>
</layout_1>
</a-spin>
</template>
<script setup>
import {inject, ref} from "vue";
import ParamItem from "@/views/pages/device/_common/Param.vue";
import {databaseCleanup, databaseSynchronization, backupDatabase, tarDatabase} from "@/views/pages/system/system.js";
import {commonResponse} from "@/views/pages/_common";
import {Message} from "@arco-design/web-vue";
import dayjs from 'dayjs';
import Layout_1 from "@/views/pages/_common/layout_1.vue";
const t = inject('t')
const cleanupData = ref("0")
const spinTip = ref("$t('Loading')")
const synchronousData = ref(null)
const uploadeLoading = ref(false);
const databaseCleanupFunction = async () => {
spinTip.value = t('Cleaning');
uploadeLoading.value = true;
await databaseCleanup(Number(cleanupData.value)).then(response => {
commonResponse({
response,
onSuccess: () => {
Message.success(t('DatabaseCleanupSuccess'));
}
})
})
uploadeLoading.value = false;
};
const databaseSynchronizationFunction = async () => {
if (synchronousData.value === null || synchronousData.value === '') {
Message.warning(t('SynchronousData') + t('Device_Excel_SerialNumberIsNotEmpty'));
return
}
spinTip.value = t('Synchronization');
uploadeLoading.value = true;
await databaseSynchronization({"timeBefore": synchronousData.value}).then(response => {
commonResponse({
response,
onSuccess: () => {
Message.success(t('DatabaseSynchronizeSuccess'));
}
})
})
uploadeLoading.value = false;
};
const backupDatabaseFunction = async () => {
spinTip.value = t('Backuping');
uploadeLoading.value = true;
await backupDatabase().then(response => {
commonResponse({
response,
onSuccess: () => {
Message.success(t('BackupSuccess'));
}
})
})
uploadeLoading.value = false;
}
const tarDatabaseFunction = async () => {
spinTip.value = t('Shrinking');
uploadeLoading.value = true;
await tarDatabase().then(response => {
commonResponse({
response,
onSuccess: () => {
Message.success(t('TarSuccess'));
}
})
})
uploadeLoading.value = false;
}
</script>
<style scoped lang="less">
.setting-scroll {
margin-top: 28px;
height: calc(100% - 60px);
.param {
margin-top: 40px;
&-title {
position: relative;
height: 28px;
&:before {
content: "";
position: absolute;
top: 8px;
height: 13px;
width: 2px;
background-color: #3348FF;
}
&-text {
margin-left: 10px;
color: #192840;
font-family: "PingFang SC";
font-size: 18px;
font-weight: 500;
line-height: 28px;
}
}
&-content {
display: flex;
gap: 40px;
margin-top: 20px;
& > div {
flex: 0 1 48%;
}
}
&-table {
margin-top: 20px;
}
&-button {
margin-top: 20px;
.arco-btn {
padding: 5px 36px;
}
}
}
}
.param-content {
display: flex; /* 使用 Flexbox 布局 */
align-items: center; /* 垂直居中对齐 */
gap: 20px; /* 元素间距 */
margin-left: 200px; /* 左侧距离,可以根据需要调整 */
}
.param-content a-button,
.param-content param-item {
text-align: center; /* 文字居中 */
flex: 1; /* 让每个元素平分空间 */
}
.label {
display: inline-block; /* 使标签成为块级元素 */
width: 150px; /* 固定宽度,可以根据需要调整 */
text-align: right; /* 文字右对齐 */
}
</style>
TaskManageServiceImpl
java
public boolean doStac(Date stacDate) {
String tableName = DateUtil.convertStartTimeToTableName(stacDate);
if (!systemDao.existTable(tableName)) {
return false;
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(stacDate);
// 当天0点
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Date todayStart = calendar.getTime();
// 明天0点
calendar.add(Calendar.DAY_OF_MONTH, 1);
Date tomorrowStart = calendar.getTime();
boolean res1 = stacGroupCallDao.doStacGroupCall(stacDate, todayStart, tomorrowStart);
boolean res2 = stacPrivateCallDao.doStacPrivateCall(stacDate, todayStart, tomorrowStart);
boolean res3 = stacRptDao.doStacRpt(stacDate, todayStart, tomorrowStart);
boolean res4 = stacUserTrafficDao.doStacUserTraffic(stacDate, todayStart, tomorrowStart);
boolean res5 = stacGroupTrafficDao.doStacGroupTraffice(stacDate, todayStart, tomorrowStart);
boolean res6 = stacRssiDao.doStacRssi(stacDate, todayStart, tomorrowStart);
boolean res7 = stacSiteDao.doStacSite(stacDate);
// 根据业务写入终端表
try {
terminalService.writeTerimalFromRptBiz(stacDate, todayStart, tomorrowStart);
} catch (Exception ex) {
logger.error("<TaskManageServiceImpl doStac(Date) WriteTerimalFromRptBiz> Error: " + ex.getMessage(), ex);
}
// 根据业务写入组
try {
terminalGroupService.writeGroupFromRptBiz(stacDate, todayStart, tomorrowStart);
} catch (Exception ex) {
logger.error("<TaskManageServiceImpl doStac(Date) WriteGroupFromRptBiz> Error: " + ex.getMessage(), ex);
}
return res1 && res2 && res3 && res4 && res5 && res6 && res7;
}
StacGroupCallDaoImpl
java
@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;
}
}
StacPrivateCallDaoImpl
java
@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;
}
}
StacRptDaoImpl
java
@Transactional
@Override
public Boolean doStacRpt(Date stacDate, Date todayStart, Date tomorrowStart) {
List<String> sqlList = new ArrayList<>();
try {
// Delete SQL
String deleteSql = String.format(
"DELETE FROM stac_rpt WHERE date='%s';",
yyyyMMdd.format(stacDate)
);
// Table name based on DateUtil (this should be implemented in Java)
String tableName = DateUtil.convertStartTimeToTableName(stacDate);
String insertSql = String.format("INSERT INTO stac_rpt (rptsn, date, timesolt, biztype, biztime, count, " +
"h0001biztime, h0001bizcount, " +
"h0102biztime, h0102bizcount, " +
"h0203biztime, h0203bizcount, " +
"h0304biztime, h0304bizcount, " +
"h0405biztime, h0405bizcount, " +
"h0506biztime, h0506bizcount, " +
"h0607biztime, h0607bizcount, " +
"h0708biztime, h0708bizcount, " +
"h0809biztime, h0809bizcount, " +
"h0910biztime, h0910bizcount, " +
"h1011biztime, h1011bizcount, " +
"h1112biztime, h1112bizcount, " +
"h1213biztime, h1213bizcount, " +
"h1314biztime, h1314bizcount, " +
"h1415biztime, h1415bizcount, " +
"h1516biztime, h1516bizcount, " +
"h1617biztime, h1617bizcount, " +
"h1718biztime, h1718bizcount, " +
"h1819biztime, h1819bizcount, " +
"h1920biztime, h1920bizcount, " +
"h2021biztime, h2021bizcount, " +
"h2122biztime, h2122bizcount, " +
"h2223biztime, h2223bizcount, " +
"h2324biztime, h2324bizcount) " +
"(SELECT " +
"serial_no AS RptSN, " +
"DATE_FORMAT(starttime, '%%Y-%%m-%%d') AS date, " + // 这里需要使用 '%%' 转义
"slot AS TimeSolt, " +
"type AS BizType, " +
"SUM(duration) AS biztime, " +
"COUNT(*) AS count, " +
"SUM(CASE WHEN HOUR(starttime) = 0 THEN duration ELSE 0 END) AS H0001BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 0 THEN 1 ELSE NULL END) AS H0001BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 1 THEN duration ELSE 0 END) AS H0102BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 1 THEN 1 ELSE NULL END) AS H0102BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 2 THEN duration ELSE 0 END) AS H0203BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 2 THEN 1 ELSE NULL END) AS H0203BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 3 THEN duration ELSE 0 END) AS H0304BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 3 THEN 1 ELSE NULL END) AS H0304BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 4 THEN duration ELSE 0 END) AS H0405BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 4 THEN 1 ELSE NULL END) AS H0405BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 5 THEN duration ELSE 0 END) AS H0506BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 5 THEN 1 ELSE NULL END) AS H0506BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 6 THEN duration ELSE 0 END) AS H0607BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 6 THEN 1 ELSE NULL END) AS H0607BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 7 THEN duration ELSE 0 END) AS H0708BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 7 THEN 1 ELSE NULL END) AS H0708BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 8 THEN duration ELSE 0 END) AS H0809BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 8 THEN 1 ELSE NULL END) AS H0809BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 9 THEN duration ELSE 0 END) AS H0910BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 9 THEN 1 ELSE NULL END) AS H0910BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 10 THEN duration ELSE 0 END) AS H1011BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 10 THEN 1 ELSE NULL END) AS H1011BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 11 THEN duration ELSE 0 END) AS H1112BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 11 THEN 1 ELSE NULL END) AS H1112BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 12 THEN duration ELSE 0 END) AS H1213BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 12 THEN 1 ELSE NULL END) AS H1213BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 13 THEN duration ELSE 0 END) AS H1314BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 13 THEN 1 ELSE NULL END) AS H1314BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 14 THEN duration ELSE 0 END) AS H1415BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 14 THEN 1 ELSE NULL END) AS H1415BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 15 THEN duration ELSE 0 END) AS H1516BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 15 THEN 1 ELSE NULL END) AS H1516BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 16 THEN duration ELSE 0 END) AS H1617BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 16 THEN 1 ELSE NULL END) AS H1617BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 17 THEN duration ELSE 0 END) AS H1718BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 17 THEN 1 ELSE NULL END) AS H1718BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 18 THEN duration ELSE 0 END) AS H1819BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 18 THEN 1 ELSE NULL END) AS H1819BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 19 THEN duration ELSE 0 END) AS H1920BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 19 THEN 1 ELSE NULL END) AS H1920BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 20 THEN duration ELSE 0 END) AS H2021BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 20 THEN 1 ELSE NULL END) AS H2021BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 21 THEN duration ELSE 0 END) AS H2122BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 21 THEN 1 ELSE NULL END) AS H2122BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 22 THEN duration ELSE 0 END) AS H2223BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 22 THEN 1 ELSE NULL END) AS H2223BizCount, " +
"SUM(CASE WHEN HOUR(starttime) = 23 THEN duration ELSE 0 END) AS H2324BizTime, " +
"COUNT(CASE WHEN HOUR(starttime) = 23 THEN 1 ELSE NULL END) AS H2324BizCount " +
"FROM %s " +
"WHERE type != -1 " +
"AND STARTTIME between '%s' and '%s' " +
"GROUP BY serial_no, date, slot, type );",
tableName, YMDHMS.format(todayStart), YMDHMS.format(tomorrowStart)
);
// 将 SQL 查询添加到 SQL 列表中
sqlList.add(deleteSql);
sqlList.add(insertSql);
// 如果 SQL 列表不为空,则批量执行
if (!sqlList.isEmpty()) {
executeBatch(sqlList);
}
return true;
} catch (Exception ex) {
logger.error("<StacRptDaoImpl doStacRpt> 错误: {}", ex.getMessage());
return false;
}
}
StacUserTrafficDaoImpl
java
@Transactional
@Override
public Boolean doStacUserTraffic(Date stacDate, Date todayStart, Date tomorrowStart) {
List<String> sqlList = new ArrayList<>();
try {
String date = yyyyMMdd.format(stacDate);
String tableName = DateUtil.convertStartTimeToTableName(stacDate);
// DELETE SQL
String deleteSql = String.format("DELETE FROM stac_usertraffic_day WHERE date='%s';", date);
sqlList.add(deleteSql);
// Calling Insert SQL
String callingInsertSql = String.format(
"INSERT INTO stac_usertraffic_day (radioId, date, count, durationTime, biztype, calling, groupId, calltype) " +
"SELECT senderid AS radioId, " +
"DATE_FORMAT(starttime, '%%Y-%%m-%%d') AS date, " +
"COUNT(*) AS count, " +
"SUM(duration) AS durationTime, " +
"type AS bizType, " +
"1 AS calling, -1 AS groupId, " +
"calltype AS calltype " +
"FROM %s " +
"WHERE status in (0,6,11) " +
"AND STARTTIME between '%s' and '%s' " +
"GROUP BY senderid, date, type, calltype;",
tableName, YMDHMS.format(todayStart), YMDHMS.format(tomorrowStart)
);
sqlList.add(callingInsertSql);
// Called Insert SQL
String calledInsertSql = String.format(
"INSERT INTO stac_usertraffic_day (radioId, date, count, durationTime, biztype, calling, groupId, calltype) " +
"SELECT " +
"(CASE WHEN calltype IN (1, 2, 3, 5, 7, 12) THEN -1 ELSE targetid END) AS radioId, " +
"DATE_FORMAT(starttime, '%%Y-%%m-%%d') AS date, " +
"COUNT(*) AS count, " +
"SUM(duration) AS durationTime, " +
"type AS bizType, " +
"0 AS calling, " +
"(CASE WHEN calltype IN (1, 2, 3, 5, 7, 12) THEN targetid ELSE -1 END) AS groupId, " +
"calltype AS calltype " +
"FROM %s " +
"WHERE status in (0,6,11) " +
"AND type not in (3,4) " +
"AND STARTTIME between '%s' and '%s' " +
"GROUP BY targetid, date, type, calltype;",
tableName, YMDHMS.format(todayStart), YMDHMS.format(tomorrowStart)
);
sqlList.add(calledInsertSql);
// 批量执行 SQL
if (!sqlList.isEmpty()) {
for (String sql : sqlList) {
Query query = entityManager.createNativeQuery(sql);
query.executeUpdate();
}
}
return true;
} catch (Exception ex) {
// 错误日志记录
logger.error("StacUserTrafficDaoImpl类,doStacUserTraffic方法:SQL:{}",sqlList.toString(),ex);
return false;
}
}
StacGroupTrafficDaoImpl
java
@Transactional
@Override
public Boolean doStacGroupTraffice(Date stacDate, Date todayStart, Date tomorrowStart) {
List<String> sqlList = new ArrayList<>();
try {
String date = yyyyMMdd.format(stacDate);
String tableName = DateUtil.convertStartTimeToTableName(stacDate);
// Construct delete SQL
String deleteSql = String.format(
"DELETE FROM stac_grouptraffic_day WHERE date='%s';",
date
);
sqlList.add(deleteSql);
// Construct insert SQL
String insertSql = String.format(
"INSERT INTO stac_grouptraffic_day (groupId, date, biztype, count, durationTime, senderid) " +
"SELECT targetid AS groupId, " +
"DATE_FORMAT(starttime, '%%Y-%%m-%%d') AS date, " +
"type AS biztype, " +
"COUNT(*) AS count, " +
"SUM(duration) AS durationTime, " +
"senderid " +
"FROM %s " +
"WHERE status in (0,6,11) " +
"AND type in (1,2) " +
"AND calltype in (1,3,5,7,12) " +
"AND STARTTIME between '%s' and '%s' " +
"GROUP BY targetid, date, type, senderid;",
tableName, YMDHMS.format(todayStart), YMDHMS.format(tomorrowStart)
);
sqlList.add(insertSql);
// Execute SQL queries in batch
if (!sqlList.isEmpty()) {
for (String sql : sqlList) {
Query query = entityManager.createNativeQuery(sql);
query.executeUpdate(); // Execute each SQL query
}
}
return true;
} catch (Exception ex) {
// Log error
logger.error("StacGroupTrafficDaoImpl类,doStacGroupTraffice方法:SQL:{}", sqlList.toString(), ex);
return false;
}
}
StacRssiDaoImpl
java
@Transactional
@Override
public Boolean doStacRssi(Date stacDate, Date todayStart, Date tomorrowStart) {
List<String> sqlList = new ArrayList<>();
try {
// Create SQL list
String stacDateStr = yyyyMMdd.format(stacDate);
String deleteSql = String.format("DELETE FROM stac_rssi_day WHERE date = '%s';",
stacDateStr);
String tableName = DateUtil.convertStartTimeToTableName(stacDate);
String insertSql = String.format(
"INSERT INTO stac_rssi_day (rptsn, date, count, rssi) " +
"SELECT serial_no AS rptsn, DATE_FORMAT(starttime, '%%Y-%%m-%%d') AS date, " +
"count(*) AS count, rssi " +
"FROM %s " +
"WHERE STARTTIME between '%s' and '%s' " +
"GROUP BY serial_no, date, rssi;",
tableName, YMDHMS.format(todayStart), YMDHMS.format(tomorrowStart)
);
sqlList.add(deleteSql);
sqlList.add(insertSql);
// 执行 SQL 语句
if (!sqlList.isEmpty()) {
for (String sql : sqlList) {
Query query = entityManager.createNativeQuery(sql);
query.executeUpdate(); // 执行更新操作
}
}
return true;
} catch (Exception ex) {
logger.error("<StacRssiDaoImpl doStacRssi> Error: {}", ex.getMessage(), ex);
return false;
}
}
StacSiteDaoImpl
java
@Transactional
@Override
public Boolean doStacSite(Date stacDate) {
List<String> sqlList = new ArrayList<>();
try {
// Calculate date based on i
String date = yyyyMMdd.format(stacDate);
// Construct delete SQL
String deleteSql = String.format(
"DELETE FROM stac_site_day WHERE date='%s';",
date
);
sqlList.add(deleteSql);
String insertSql = String.format(
"INSERT INTO stac_site_day (SiteID, `Date`, BizType, BizTime, Count) " +
"SELECT r.site_id, rd.`date`, rd.biztype, SUM(BizTime) AS BizTime, SUM(Count) AS Count " +
"FROM stac_rpt rd " +
"INNER JOIN repeater r ON rd.RptSN = r.serial_no " +
"WHERE r.deleted = 0 " +
"AND DATE_FORMAT(rd.date, '%%Y-%%m-%%d') = '%s' " +
"GROUP BY r.site_id, rd.`date`, rd.biztype;",
date
);
sqlList.add(insertSql);
if (!sqlList.isEmpty()) {
for (String sql : sqlList) {
Query query = entityManager.createNativeQuery(sql);
query.executeUpdate(); // Execute each SQL query
}
}
return true;
} catch (Exception ex) {
// Log error
logger.error("StacSiteDaoImpl类,doStacSite方法:SQL:{}", sqlList.toString(), ex);
return false;
}
}
stac_groupcall_day表:中转组呼

java
CREATE TABLE `stac_groupcall_day` (
`GROUPID` int(11) NOT NULL,
`DATE` date NOT NULL,
`COUNT` bigint(20) DEFAULT NULL,
`CALLTIME` bigint(20) DEFAULT NULL,
`AvgCallTime` bigint(20) DEFAULT NULL,
PRIMARY KEY (`GROUPID`,`DATE`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
stac_privatecall_day表:中转个呼

java
CREATE TABLE `stac_privatecall_day` (
`RADIOID` int(11) NOT NULL,
`DATE` date NOT NULL,
`COUNT` bigint(20) DEFAULT NULL,
`CALLTIME` bigint(20) DEFAULT NULL,
`AvgCallTime` bigint(20) DEFAULT NULL,
PRIMARY KEY (`RADIOID`,`DATE`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
stac_rpt表:中转业务

java
CREATE TABLE `stac_rpt` (
`RPTSN` varchar(128) COLLATE utf8_bin NOT NULL,
`Date` date NOT NULL,
`TimeSolt` int(11) NOT NULL,
`BizType` int(11) NOT NULL,
`BizTime` bigint(20) DEFAULT NULL,
`Count` bigint(20) DEFAULT NULL,
`H0001BizTime` bigint(20) DEFAULT '0',
`H0001BizCount` bigint(20) DEFAULT '0',
`H0102BizTime` bigint(20) DEFAULT '0',
`H0102BizCount` bigint(20) DEFAULT '0',
`H0203BizTime` bigint(20) DEFAULT '0',
`H0203BizCount` bigint(20) DEFAULT '0',
`H0304BizTime` bigint(20) DEFAULT '0',
`H0304BizCount` bigint(20) DEFAULT '0',
`H0405BizTime` bigint(20) DEFAULT '0',
`H0405BizCount` bigint(20) DEFAULT '0',
`H0506BizTime` bigint(20) DEFAULT '0',
`H0506BizCount` bigint(20) DEFAULT '0',
`H0607BizTime` bigint(20) DEFAULT '0',
`H0607BizCount` bigint(20) DEFAULT '0',
`H0708BizTime` bigint(20) DEFAULT '0',
`H0708BizCount` bigint(20) DEFAULT '0',
`H0809BizTime` bigint(20) DEFAULT '0',
`H0809BizCount` bigint(20) DEFAULT '0',
`H0910BizTime` bigint(20) DEFAULT '0',
`H0910BizCount` bigint(20) DEFAULT '0',
`H1011BizTime` bigint(20) DEFAULT '0',
`H1011BizCount` bigint(20) DEFAULT '0',
`H1112BizTime` bigint(20) DEFAULT '0',
`H1112BizCount` bigint(20) DEFAULT '0',
`H1213BizTime` bigint(20) DEFAULT '0',
`H1213BizCount` bigint(20) DEFAULT '0',
`H1314BizTime` bigint(20) DEFAULT '0',
`H1314BizCount` bigint(20) DEFAULT '0',
`H1415BizTime` bigint(20) DEFAULT '0',
`H1415BizCount` bigint(20) DEFAULT '0',
`H1516BizTime` bigint(20) DEFAULT '0',
`H1516BizCount` bigint(20) DEFAULT '0',
`H1617BizTime` bigint(20) DEFAULT '0',
`H1617BizCount` bigint(20) DEFAULT '0',
`H1718BizTime` bigint(20) DEFAULT '0',
`H1718BizCount` bigint(20) DEFAULT '0',
`H1819BizTime` bigint(20) DEFAULT '0',
`H1819BizCount` bigint(20) DEFAULT '0',
`H1920BizTime` bigint(20) DEFAULT '0',
`H1920BizCount` bigint(20) DEFAULT '0',
`H2021BizTime` bigint(20) DEFAULT '0',
`H2021BizCount` bigint(20) DEFAULT '0',
`H2122BizTime` bigint(20) DEFAULT '0',
`H2122BizCount` bigint(20) DEFAULT '0',
`H2223BizTime` bigint(20) DEFAULT '0',
`H2223BizCount` bigint(20) DEFAULT '0',
`H2324BizTime` bigint(20) DEFAULT '0',
`H2324BizCount` bigint(20) DEFAULT '0',
PRIMARY KEY (`RPTSN`,`Date`,`TimeSolt`,`BizType`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
stac_usertraffic_day表:终端业务

java
CREATE TABLE `stac_usertraffic_day` (
`RADIOID` int(11) NOT NULL,
`DATE` date NOT NULL,
`COUNT` bigint(11) DEFAULT NULL,
`durationTime` bigint(11) DEFAULT NULL,
`biztype` int(11) NOT NULL,
`calling` tinyint(1) NOT NULL,
`groupId` int(11) NOT NULL,
`calltype` int(11) NOT NULL,
PRIMARY KEY (`RADIOID`,`DATE`,`biztype`,`calling`,`groupId`,`calltype`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
stac_grouptraffic_day表:终端组业务

java
CREATE TABLE `stac_grouptraffic_day` (
`GROUPID` int(11) NOT NULL,
`DATE` date NOT NULL,
`bizType` int(11) NOT NULL,
`COUNT` bigint(11) DEFAULT NULL,
`durationTime` bigint(11) DEFAULT NULL,
`senderId` int(11) NOT NULL,
PRIMARY KEY (`GROUPID`,`DATE`,`bizType`,`senderId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
stac_rssi_day表:中转台RSSI

java
CREATE TABLE `stac_rssi_day` (
`RPTSN` varchar(128) COLLATE utf8_bin NOT NULL,
`DATE` date NOT NULL,
`COUNT` bigint(11) DEFAULT NULL,
`RSSI` int(11) NOT NULL,
PRIMARY KEY (`RPTSN`,`DATE`,`RSSI`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
stac_site_day表:站点统计

java
CREATE TABLE `stac_site_day` (
`SiteID` int(11) NOT NULL,
`Date` date NOT NULL,
`BizType` int(11) NOT NULL,
`BizTime` bigint(20) DEFAULT NULL,
`Count` bigint(20) DEFAULT NULL,
PRIMARY KEY (`SiteID`,`Date`,`BizType`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
四、说明
说明点1:该数据库同步只是数据同步,不是传统意义上的数据同步从一个库同步到另一个库中。
说明点2:这块分手动同步和自动同步。
自动同步:每30分钟定时任务自动执行一次。手动同步:菜单栏进行手动触发同步。
说明点3:nginx记得配置超时配置,因为像大地图切片上传或者数据库同步执行总时间随数据增加而增加,浏览器默认请求30s超时,如果不配置会造成错误。
nginx.conf
java
location /api/databaseManage/databaseSynchronization {
client_max_body_size 600m;
client_body_buffer_size 128k;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_send_timeout 600;
proxy_buffer_size 64k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
# 添加 proxy_pass 及请求头设置
proxy_pass http://localhost:62000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}