XNMS项目-mysql数据库同步

文章目录

一、背景

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;
}

五、本人其他相关文章链接

相关推荐
踢足球09295 小时前
寒假打卡:2026-01-22
数据库·sql
数巨小码人5 小时前
核心架构深度解析-揭开国产数据库内核的神秘面纱
数据库·架构
薛晓刚5 小时前
MySQL 精度扩展时候的DDL阻塞对比Oracle
数据库
卓怡学长5 小时前
m119在线购书商城系统
java·数据库·spring boot·spring·汽车
存在的五月雨5 小时前
Mysql 事务和锁的一些概念和理解
数据库·mysql
yuankunliu5 小时前
【redis】4、Redis的过期策略和淘汰策略
数据库·redis·缓存
optimistic_chen5 小时前
【Redis系列】Redis缓存
linux·数据库·redis·mysql·缓存·火山引擎
程农5 小时前
java计算机毕业设计婚纱摄影网站(附源码、数据库)
java·数据库·课程设计
川西胖墩墩6 小时前
网站开发完整流程梳理
大数据·数据库·架构·流程图·敏捷流程