|
@@ -0,0 +1,415 @@
|
|
|
|
|
+package org.dromara.risk.service.impl;
|
|
|
|
|
+
|
|
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.dromara.risk.domain.*;
|
|
|
|
|
+import org.dromara.risk.domain.vo.BigScreenCardVo;
|
|
|
|
|
+import org.dromara.risk.domain.vo.BigScreenChartVo;
|
|
|
|
|
+import org.dromara.risk.domain.vo.BigScreenWarningStreamVo;
|
|
|
|
|
+import org.dromara.risk.mapper.*;
|
|
|
|
|
+import org.dromara.risk.service.IBigScreenService;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+
|
|
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 3.3 大屏 - 聚合统计 Service 实现
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * 数据来源:
|
|
|
|
|
+ * <ul>
|
|
|
|
|
+ * <li>隐患: risk_hidden_danger</li>
|
|
|
|
|
+ * <li>危险源: risk_danger_source</li>
|
|
|
|
|
+ * <li>作业上报: risk_work_report</li>
|
|
|
|
|
+ * <li>人员异动: risk_personnel_change / 人员: risk_personnel</li>
|
|
|
|
|
+ * <li>特种设备: risk_special_equipment</li>
|
|
|
|
|
+ * <li>访厂审核: risk_factory_visit</li>
|
|
|
|
|
+ * <li>事故: risk_accident</li>
|
|
|
|
|
+ * <li>预警: risk_warning</li>
|
|
|
|
|
+ * <li>品控巡检: risk_inspection_task (biz_type='quality')</li>
|
|
|
|
|
+ * <li>风控抽检: risk_supervision_inspection / 监督抽检记录</li>
|
|
|
|
|
+ * <li>客诉: risk_supervision_complaint</li>
|
|
|
|
|
+ * </ul>
|
|
|
|
|
+ * </p>
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author ruoyi
|
|
|
|
|
+ */
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+@RequiredArgsConstructor
|
|
|
|
|
+@Service
|
|
|
|
|
+public class BigScreenServiceImpl implements IBigScreenService {
|
|
|
|
|
+
|
|
|
|
|
+ private final RiskHiddenDangerMapper hiddenDangerMapper;
|
|
|
|
|
+ private final RiskDangerSourceMapper dangerSourceMapper;
|
|
|
|
|
+ private final RiskWorkReportMapper workReportMapper;
|
|
|
|
|
+ private final RiskPersonnelChangeMapper personnelChangeMapper;
|
|
|
|
|
+ private final RiskPersonnelMapper personnelMapper;
|
|
|
|
|
+ private final RiskSpecialEquipmentMapper specialEquipmentMapper;
|
|
|
|
|
+ private final RiskFactoryVisitMapper factoryVisitMapper;
|
|
|
|
|
+ private final RiskAccidentMapper accidentMapper;
|
|
|
|
|
+ private final RiskWarningMapper warningMapper;
|
|
|
|
|
+ private final RiskInspectionTaskMapper inspectionTaskMapper;
|
|
|
|
|
+ private final RiskSupervisionInspectionMapper supervisionInspectionMapper;
|
|
|
|
|
+ private final RiskSupervisionComplaintMapper supervisionComplaintMapper;
|
|
|
|
|
+
|
|
|
|
|
+ // ============================================================
|
|
|
|
|
+ // ① 6 张业务数据卡片
|
|
|
|
|
+ // ============================================================
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public BigScreenCardVo getCardStats() {
|
|
|
|
|
+ BigScreenCardVo vo = new BigScreenCardVo();
|
|
|
|
|
+
|
|
|
|
|
+ // ====== 1. 安全隐患卡片 ======
|
|
|
|
|
+ // 隐患总数 / 已闭环 / 待处理
|
|
|
|
|
+ try {
|
|
|
|
|
+ int dangerTotal = safeCount(hiddenDangerMapper);
|
|
|
|
|
+ int dangerHandled = safeCount(hiddenDangerMapper, "handle_status", "ne", "待处理");
|
|
|
|
|
+ int dangerPending = safeCount(hiddenDangerMapper, "handle_status", "eq", "待处理");
|
|
|
|
|
+ vo.setDangerTotal(dangerTotal);
|
|
|
|
|
+ vo.setDangerHandled(dangerHandled);
|
|
|
|
|
+ vo.setDangerPending(dangerPending);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("[BigScreen] 隐患统计失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ====== 2. 危险源卡片 ======
|
|
|
|
|
+ // 危险源总数 / 本月新增
|
|
|
|
|
+ try {
|
|
|
|
|
+ int total = safeCount(dangerSourceMapper);
|
|
|
|
|
+ vo.setDangerSourceTotal(total);
|
|
|
|
|
+ // 本月新增 = report_time 在本月 1 号至当前时间
|
|
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
+ Calendar c = Calendar.getInstance();
|
|
|
|
|
+ c.set(Calendar.DAY_OF_MONTH, 1);
|
|
|
|
|
+ c.set(Calendar.HOUR_OF_DAY, 0);
|
|
|
|
|
+ c.set(Calendar.MINUTE, 0);
|
|
|
|
|
+ c.set(Calendar.SECOND, 0);
|
|
|
|
|
+ String monthStart = sdf.format(c.getTime());
|
|
|
|
|
+ int monthNew = safeCount(dangerSourceMapper, "report_time", "ge", monthStart);
|
|
|
|
|
+ vo.setDangerSourceMonthNew(monthNew);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("[BigScreen] 危险源统计失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ====== 3. 作业上报卡片 ======
|
|
|
|
|
+ // 上报总条数 / 进行中(审核通过且当前时间在工期内)
|
|
|
|
|
+ try {
|
|
|
|
|
+ int total = safeCount(workReportMapper);
|
|
|
|
|
+ vo.setWorkReportTotal(total);
|
|
|
|
|
+ // 进行中: 审核通过 + 当前时间在 work_start_time ~ work_end_time 之间
|
|
|
|
|
+ QueryWrapper<RiskWorkReport> lqw = new QueryWrapper<>();
|
|
|
|
|
+ lqw.eq("audit_status", "审核通过");
|
|
|
|
|
+ lqw.le("work_start_time", new Date());
|
|
|
|
|
+ lqw.ge("work_end_time", new Date());
|
|
|
|
|
+ int ongoing = Math.toIntExact(workReportMapper.selectCount(lqw));
|
|
|
|
|
+ vo.setWorkReportOngoing(ongoing);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("[BigScreen] 作业上报统计失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ====== 4. 审计工作卡片 ======
|
|
|
|
|
+ // 人员异动总人次 / 离职 / 调任
|
|
|
|
|
+ try {
|
|
|
|
|
+ int total = safeCount(personnelChangeMapper);
|
|
|
|
|
+ vo.setPersonnelChangeTotal(total);
|
|
|
|
|
+ int leave = safeCount(personnelChangeMapper, "change_type", "eq", "离职");
|
|
|
|
|
+ int transfer = safeCount(personnelChangeMapper, "change_type", "eq", "调任");
|
|
|
|
|
+ vo.setPersonnelLeave(leave);
|
|
|
|
|
+ vo.setPersonnelTransfer(transfer);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("[BigScreen] 审计工作统计失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ====== 5. 特种设备卡片 ======
|
|
|
|
|
+ // 设备总数 / 运行中 / 维护保养中
|
|
|
|
|
+ try {
|
|
|
|
|
+ int total = safeCount(specialEquipmentMapper);
|
|
|
|
|
+ vo.setSpecialEquipmentTotal(total);
|
|
|
|
|
+ int running = safeCount(specialEquipmentMapper, "use_status", "eq", "在用");
|
|
|
|
|
+ // 维护中包含: 维护中 / 检修中 / 维修中(多状态)
|
|
|
|
|
+ int maintaining = safeCount(specialEquipmentMapper, "use_status", "in",
|
|
|
|
|
+ "维护中", "检修中", "维修中");
|
|
|
|
|
+ vo.setSpecialEquipmentRunning(running);
|
|
|
|
|
+ vo.setSpecialEquipmentMaintaining(maintaining);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("[BigScreen] 特种设备统计失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ====== 6. 访厂审核卡片 ======
|
|
|
|
|
+ // 访厂总次数 / 通过 / 不通过
|
|
|
|
|
+ try {
|
|
|
|
|
+ int total = safeCount(factoryVisitMapper);
|
|
|
|
|
+ int passed = safeCount(factoryVisitMapper, "audit_result", "eq", "通过");
|
|
|
|
|
+ int rejected = safeCount(factoryVisitMapper, "audit_result", "eq", "不通过");
|
|
|
|
|
+ vo.setFactoryVisitTotal(total);
|
|
|
|
|
+ vo.setFactoryVisitPassed(passed);
|
|
|
|
|
+ vo.setFactoryVisitRejected(rejected);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("[BigScreen] 访厂审核统计失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ============================================================
|
|
|
|
|
+ // ② ③ ④ 图表数据
|
|
|
|
|
+ // ============================================================
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public BigScreenChartVo getChartData() {
|
|
|
|
|
+ BigScreenChartVo vo = new BigScreenChartVo();
|
|
|
|
|
+ vo.setPersonnelDistribution(buildPersonnelDistribution());
|
|
|
|
|
+ vo.setAccidentDistribution(buildAccidentDistribution());
|
|
|
|
|
+ buildInspectionTrend(vo);
|
|
|
|
|
+ buildComplaintMonthly(vo);
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 人员岗位占比(按 position 字段聚合)
|
|
|
|
|
+ */
|
|
|
|
|
+ private List<BigScreenChartVo.NameValue> buildPersonnelDistribution() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 按 position 分组统计(去重 + 仅统计未删除)
|
|
|
|
|
+ QueryWrapper<RiskPersonnel> lqw = new QueryWrapper<>();
|
|
|
|
|
+ lqw.select("position as name, COUNT(*) as value");
|
|
|
|
|
+ lqw.eq("del_flag", "0");
|
|
|
|
|
+ lqw.isNotNull("position");
|
|
|
|
|
+ lqw.ne("position", "");
|
|
|
|
|
+ lqw.groupBy("position");
|
|
|
|
|
+ lqw.orderByDesc("value");
|
|
|
|
|
+ List<Map<String, Object>> rows = personnelMapper.selectMaps(lqw);
|
|
|
|
|
+ List<BigScreenChartVo.NameValue> result = new ArrayList<>();
|
|
|
|
|
+ for (Map<String, Object> row : rows) {
|
|
|
|
|
+ result.add(new BigScreenChartVo.NameValue() {{
|
|
|
|
|
+ setName(toStr(row.get("name")));
|
|
|
|
|
+ setValue(toInt(row.get("value")));
|
|
|
|
|
+ }});
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("[BigScreen] 人员岗位占比统计失败", e);
|
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 事故类型分布
|
|
|
|
|
+ */
|
|
|
|
|
+ private List<BigScreenChartVo.NameValue> buildAccidentDistribution() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ QueryWrapper<RiskAccident> lqw = new QueryWrapper<>();
|
|
|
|
|
+ lqw.select("accident_type as name, COUNT(*) as value");
|
|
|
|
|
+ lqw.eq("del_flag", "0");
|
|
|
|
|
+ lqw.isNotNull("accident_type");
|
|
|
|
|
+ lqw.ne("accident_type", "");
|
|
|
|
|
+ lqw.groupBy("accident_type");
|
|
|
|
|
+ lqw.orderByDesc("value");
|
|
|
|
|
+ List<Map<String, Object>> rows = accidentMapper.selectMaps(lqw);
|
|
|
|
|
+ List<BigScreenChartVo.NameValue> result = new ArrayList<>();
|
|
|
|
|
+ for (Map<String, Object> row : rows) {
|
|
|
|
|
+ result.add(new BigScreenChartVo.NameValue() {{
|
|
|
|
|
+ setName(toStr(row.get("name")));
|
|
|
|
|
+ setValue(toInt(row.get("value")));
|
|
|
|
|
+ }});
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("[BigScreen] 事故类型分布统计失败", e);
|
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 巡检/抽检近 30 天趋势
|
|
|
|
|
+ * - 品控巡检: risk_inspection_task 中 biz_type='quality' 且 create_time 在日期
|
|
|
|
|
+ * - 风控抽检: risk_supervision_inspection 中 create_time 在日期
|
|
|
|
|
+ */
|
|
|
|
|
+ private void buildInspectionTrend(BigScreenChartVo vo) {
|
|
|
|
|
+ List<String> dates = new ArrayList<>();
|
|
|
|
|
+ List<Integer> qualityCounts = new ArrayList<>();
|
|
|
|
|
+ List<Integer> riskCounts = new ArrayList<>();
|
|
|
|
|
+ try {
|
|
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
|
|
+ Calendar c = Calendar.getInstance();
|
|
|
|
|
+ // 从 29 天前到今天(共 30 天)
|
|
|
|
|
+ for (int i = 29; i >= 0; i--) {
|
|
|
|
|
+ Calendar day = Calendar.getInstance();
|
|
|
|
|
+ day.add(Calendar.DAY_OF_YEAR, -i);
|
|
|
|
|
+ String dayStr = sdf.format(day.getTime());
|
|
|
|
|
+ dates.add(dayStr);
|
|
|
|
|
+ // 一天的起止
|
|
|
|
|
+ Calendar start = (Calendar) day.clone();
|
|
|
|
|
+ start.set(Calendar.HOUR_OF_DAY, 0);
|
|
|
|
|
+ start.set(Calendar.MINUTE, 0);
|
|
|
|
|
+ start.set(Calendar.SECOND, 0);
|
|
|
|
|
+ Calendar end = (Calendar) day.clone();
|
|
|
|
|
+ end.set(Calendar.HOUR_OF_DAY, 23);
|
|
|
|
|
+ end.set(Calendar.MINUTE, 59);
|
|
|
|
|
+ end.set(Calendar.SECOND, 59);
|
|
|
|
|
+ // 品控巡检
|
|
|
|
|
+ QueryWrapper<RiskInspectionTask> qualityQw = new QueryWrapper<>();
|
|
|
|
|
+ qualityQw.eq("biz_type", "quality");
|
|
|
|
|
+ qualityQw.between("create_time", start.getTime(), end.getTime());
|
|
|
|
|
+ int qualityCount = Math.toIntExact(inspectionTaskMapper.selectCount(qualityQw));
|
|
|
|
|
+ qualityCounts.add(qualityCount);
|
|
|
|
|
+ // 风控抽检
|
|
|
|
|
+ QueryWrapper<RiskSupervisionInspection> riskQw = new QueryWrapper<>();
|
|
|
|
|
+ riskQw.between("create_time", start.getTime(), end.getTime());
|
|
|
|
|
+ int riskCount = Math.toIntExact(supervisionInspectionMapper.selectCount(riskQw));
|
|
|
|
|
+ riskCounts.add(riskCount);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("[BigScreen] 巡检/抽检近 30 天趋势统计失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ vo.setTrendDates(dates);
|
|
|
|
|
+ vo.setQualityInspectionCount(qualityCounts);
|
|
|
|
|
+ vo.setRiskInspectionCount(riskCounts);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 客诉月度统计(近 12 个月)
|
|
|
|
|
+ */
|
|
|
|
|
+ private void buildComplaintMonthly(BigScreenChartVo vo) {
|
|
|
|
|
+ List<String> months = new ArrayList<>();
|
|
|
|
|
+ List<Integer> counts = new ArrayList<>();
|
|
|
|
|
+ try {
|
|
|
|
|
+ SimpleDateFormat monthFmt = new SimpleDateFormat("yyyy-MM");
|
|
|
|
|
+ SimpleDateFormat dayFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
+ Calendar c = Calendar.getInstance();
|
|
|
|
|
+ for (int i = 11; i >= 0; i--) {
|
|
|
|
|
+ Calendar m = Calendar.getInstance();
|
|
|
|
|
+ m.add(Calendar.MONTH, -i);
|
|
|
|
|
+ String monthStr = monthFmt.format(m.getTime());
|
|
|
|
|
+ months.add(monthStr);
|
|
|
|
|
+ // 月初到下月初
|
|
|
|
|
+ Calendar start = (Calendar) m.clone();
|
|
|
|
|
+ start.set(Calendar.DAY_OF_MONTH, 1);
|
|
|
|
|
+ start.set(Calendar.HOUR_OF_DAY, 0);
|
|
|
|
|
+ start.set(Calendar.MINUTE, 0);
|
|
|
|
|
+ start.set(Calendar.SECOND, 0);
|
|
|
|
|
+ Calendar end = (Calendar) start.clone();
|
|
|
|
|
+ end.add(Calendar.MONTH, 1);
|
|
|
|
|
+ QueryWrapper<RiskSupervisionComplaint> lqw = new QueryWrapper<>();
|
|
|
|
|
+ lqw.between("create_time", dayFmt.format(start.getTime()),
|
|
|
|
|
+ dayFmt.format(end.getTime()));
|
|
|
|
|
+ int count = Math.toIntExact(supervisionComplaintMapper.selectCount(lqw));
|
|
|
|
|
+ counts.add(count);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("[BigScreen] 客诉月度统计失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ vo.setComplaintMonths(months);
|
|
|
|
|
+ vo.setComplaintCounts(counts);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ============================================================
|
|
|
|
|
+ // ⑤ 滚动动态 - 最新预警
|
|
|
|
|
+ // ============================================================
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<BigScreenWarningStreamVo> getWarningStream(int limit) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ LambdaQueryWrapper<RiskWarning> lqw = new LambdaQueryWrapper<>();
|
|
|
|
|
+ lqw.eq(RiskWarning::getDelFlag, "0");
|
|
|
|
|
+ lqw.orderByDesc(RiskWarning::getReleaseTime);
|
|
|
|
|
+ lqw.last("LIMIT " + Math.max(1, Math.min(limit, 50)));
|
|
|
|
|
+ List<RiskWarning> list = warningMapper.selectList(lqw);
|
|
|
|
|
+ List<BigScreenWarningStreamVo> result = new ArrayList<>();
|
|
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
+ for (RiskWarning w : list) {
|
|
|
|
|
+ BigScreenWarningStreamVo vo = new BigScreenWarningStreamVo();
|
|
|
|
|
+ vo.setId(w.getId());
|
|
|
|
|
+ vo.setWarningCode(w.getWarningCode());
|
|
|
|
|
+ vo.setTitle(w.getWarningTitle());
|
|
|
|
|
+ vo.setWarningType(w.getWarningType());
|
|
|
|
|
+ vo.setWarningLevel(w.getWarningLevel());
|
|
|
|
|
+ vo.setLevelColor(mapLevelColor(w.getWarningLevel()));
|
|
|
|
|
+ vo.setReleaseTime(w.getReleaseTime() == null ? "" : sdf.format(w.getReleaseTime()));
|
|
|
|
|
+ vo.setStoreName(w.getStoreName());
|
|
|
|
|
+ result.add(vo);
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("[BigScreen] 预警走马灯统计失败", e);
|
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 预警等级 → 状态点颜色
|
|
|
|
|
+ * - 重大/红色: 紧急
|
|
|
|
|
+ * - 较大/黄色: 警告
|
|
|
|
|
+ * - 一般/蓝色: 提示
|
|
|
|
|
+ */
|
|
|
|
|
+ private String mapLevelColor(String level) {
|
|
|
|
|
+ if (level == null) return "blue";
|
|
|
|
|
+ if (level.contains("重大") || level.contains("高") || level.contains("紧急") || level.contains("红")) {
|
|
|
|
|
+ return "red";
|
|
|
|
|
+ }
|
|
|
|
|
+ if (level.contains("较大") || level.contains("中") || level.contains("黄")) {
|
|
|
|
|
+ return "yellow";
|
|
|
|
|
+ }
|
|
|
|
|
+ return "blue";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ============================================================
|
|
|
|
|
+ // 工具方法
|
|
|
|
|
+ // ============================================================
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 通用 count 工具:支持 eq/ne/in 条件
|
|
|
|
|
+ * <p>使用 raw type 接受任意 BaseMapper</p>
|
|
|
|
|
+ */
|
|
|
|
|
+ @SuppressWarnings({"rawtypes", "unchecked"})
|
|
|
|
|
+ private int safeCount(com.baomidou.mybatisplus.core.mapper.BaseMapper mapper, String field, String op, Object... vals) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ QueryWrapper lqw = new QueryWrapper();
|
|
|
|
|
+ if (field != null && op != null && vals != null && vals.length > 0) {
|
|
|
|
|
+ switch (op) {
|
|
|
|
|
+ case "eq" -> lqw.eq(field, vals[0]);
|
|
|
|
|
+ case "ne" -> lqw.ne(field, vals[0]);
|
|
|
|
|
+ case "in" -> lqw.in(field, vals);
|
|
|
|
|
+ case "ge" -> lqw.ge(field, vals[0]);
|
|
|
|
|
+ case "le" -> lqw.le(field, vals[0]);
|
|
|
|
|
+ default -> {}
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return Math.toIntExact(mapper.selectCount(lqw));
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("[BigScreen] safeCount 失败: field={}, op={}, vals={}", field, op, vals, e);
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 重载:仅 count 全部
|
|
|
|
|
+ */
|
|
|
|
|
+ @SuppressWarnings({"rawtypes", "unchecked"})
|
|
|
|
|
+ private int safeCount(com.baomidou.mybatisplus.core.mapper.BaseMapper mapper) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ return Math.toIntExact(mapper.selectCount(new QueryWrapper()));
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("[BigScreen] safeCount(全量) 失败", e);
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static String toStr(Object o) {
|
|
|
|
|
+ return o == null ? "" : o.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static int toInt(Object o) {
|
|
|
|
|
+ if (o == null) return 0;
|
|
|
|
|
+ if (o instanceof Number) return ((Number) o).intValue();
|
|
|
|
|
+ try {
|
|
|
|
|
+ return Integer.parseInt(o.toString());
|
|
|
|
|
+ } catch (Exception ignored) {
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|