|
|
@@ -168,55 +168,178 @@ namespace EasyTemplate.Service
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// 计算累计统计数据(核心业务逻辑)
|
|
|
- /// 规则:从当前日期往前找,直到累计笔数>=5 或达到 35 天上限
|
|
|
+ /// 计算累计统计数据(核心业务逻辑 - 按 C++ update_warning 实现)
|
|
|
+ /// 规则:从最早日期正向迭代到当前日期,累加统计并在满足条件时清零
|
|
|
/// </summary>
|
|
|
private void CalculateAccumulatedStatistics(List<TPrewarning> sortedData, int currentIndex, WarningStatistics stats)
|
|
|
{
|
|
|
- int accumulatedTotal = 0;
|
|
|
- int accumulatedOverproof = 0;
|
|
|
- int accumulatedOverproofAlert = 0;
|
|
|
- int accumulatedOverproof2 = 0;
|
|
|
- int accumulatedDays = 0;
|
|
|
-
|
|
|
- // 从当前日期往前累加,直到满足条件或达到 35 天
|
|
|
- for (int i = currentIndex; i >= 0 && (currentIndex - i) < 35; i--)
|
|
|
+ // 累加器初始化(对应 C++ acc_over, acc_over_alert, acc_total, acc_over_2)
|
|
|
+ int acc_over = 0; // 累计超标记录
|
|
|
+ int acc_over_alert = 0; // 累计严重超标记录
|
|
|
+ int acc_total = 0; // 累计总数
|
|
|
+ int acc_over_2 = 0; // 累计二级超标记录(广东中石化)
|
|
|
+
|
|
|
+ // 连续天数计数器
|
|
|
+ int continue_days = 0;
|
|
|
+ int continue_days_2 = 0;
|
|
|
+ int continue_days_alert = 0;
|
|
|
+
|
|
|
+ // 最后计算的超标率
|
|
|
+ int last_rate = 0;
|
|
|
+ int last_rate_2 = 0;
|
|
|
+ int last_rate_alert = 0;
|
|
|
+
|
|
|
+ // 获取区域规则配置
|
|
|
+ bool isBeijingMode = VRRules.RefReachCount; // 北京模式:ref_reach_count
|
|
|
+ int refCount = VRRules.RefCount; // 标准模式阈值(通常 5)
|
|
|
+ int refPrewarningIndex = VRRules.RefPrewarningIndex; // 超标率阈值
|
|
|
+ int refPrewarningIndexAlert = VRRules.RefPrewarningIndexAlert; // 严重超标率阈值
|
|
|
+ bool isZhejiangSpecial = VRRules.BCountAllDay; // 浙江中石化特殊逻辑
|
|
|
+
|
|
|
+ // 正向迭代:从第 0 天到当前天(对应 C++ mapDayWarning.begin() 到 end)
|
|
|
+ for (int i = 0; i <= currentIndex && i < sortedData.Count; i++)
|
|
|
{
|
|
|
var day = sortedData[i];
|
|
|
- accumulatedTotal += day.total;
|
|
|
- accumulatedOverproof += day.overproof;
|
|
|
- accumulatedOverproofAlert += day.overproof_alert;
|
|
|
- accumulatedOverproof2 += day.overproof_2;
|
|
|
- accumulatedDays++;
|
|
|
-
|
|
|
- // 如果累计笔数>=5,停止累加
|
|
|
- if (accumulatedTotal >= 5)
|
|
|
+
|
|
|
+ // 累加数据
|
|
|
+ acc_over += day.overproof;
|
|
|
+ acc_over_alert += day.overproof_alert;
|
|
|
+ acc_total += day.total;
|
|
|
+ acc_over_2 += day.overproof_2;
|
|
|
+
|
|
|
+ // 计算累计超标率(避免除以 0)
|
|
|
+ last_rate = acc_total == 0 ? 0 : (acc_over * 100) / acc_total;
|
|
|
+ last_rate_2 = acc_total == 0 ? 0 : (acc_over_2 * 100) / acc_total;
|
|
|
+ last_rate_alert = acc_total == 0 ? 0 : (acc_over_alert * 100) / acc_total;
|
|
|
+
|
|
|
+ // 更新警告对象中的累计值(用于显示)
|
|
|
+ // 注意:这里不直接设置 stats,因为可能还需要清零
|
|
|
+
|
|
|
+ if (isBeijingMode)
|
|
|
{
|
|
|
- break;
|
|
|
+ // === 北京模式(ref_reach_count)===
|
|
|
+ // 规则:超标率>=阈值 且 总笔数>=5 时,连续天数 +1
|
|
|
+
|
|
|
+ // 普通超标判断
|
|
|
+ if (last_rate >= refPrewarningIndex)
|
|
|
+ {
|
|
|
+ if (acc_total >= 5)
|
|
|
+ {
|
|
|
+ continue_days++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (acc_total >= 5)
|
|
|
+ {
|
|
|
+ continue_days = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 严重超标判断
|
|
|
+ if (last_rate_alert >= refPrewarningIndexAlert)
|
|
|
+ {
|
|
|
+ if (acc_total >= 5)
|
|
|
+ {
|
|
|
+ continue_days_alert++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (acc_total >= 5)
|
|
|
+ {
|
|
|
+ continue_days_alert = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 已经算入一天,清零累加器
|
|
|
+ acc_over = 0;
|
|
|
+ acc_over_alert = 0;
|
|
|
+ acc_total = 0;
|
|
|
+ acc_over_2 = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // === 标准模式 ===
|
|
|
+ // 规则:总笔数>=ref_count(通常 5) 时才检查超标率
|
|
|
+
|
|
|
+ if (acc_total >= refCount)
|
|
|
+ {
|
|
|
+ // 普通超标判断
|
|
|
+ if (last_rate >= refPrewarningIndex)
|
|
|
+ {
|
|
|
+ continue_days++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ continue_days = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 严重超标判断
|
|
|
+ if (last_rate_alert >= refPrewarningIndexAlert)
|
|
|
+ {
|
|
|
+ continue_days_alert++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ continue_days_alert = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 二级超标判断(广东中石化)
|
|
|
+ if (last_rate_2 >= refPrewarningIndex) // || day.continueoverproof == 1
|
|
|
+ {
|
|
|
+ continue_days_2++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ continue_days_2 = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 已经算入一天,清零累加器
|
|
|
+ acc_over = 0;
|
|
|
+ acc_over_alert = 0;
|
|
|
+ acc_total = 0;
|
|
|
+ acc_over_2 = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // 该分支是 ref_count 大于 0(即需要进行累计)的情况下,
|
|
|
+ // 而 acc_total 小于 ref_count 时进入
|
|
|
+
|
|
|
+ if (isZhejiangSpecial)
|
|
|
+ {
|
|
|
+ // === 浙江中石化特殊逻辑 ===
|
|
|
+ // 不足 5 笔时延续之前的预警状态
|
|
|
+ if (continue_days > 0)
|
|
|
+ {
|
|
|
+ continue_days++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (continue_days_alert > 0)
|
|
|
+ {
|
|
|
+ continue_days_alert++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- // 设置累计统计结果
|
|
|
- stats.total_count = accumulatedTotal;
|
|
|
- stats.total_overproof = accumulatedOverproof;
|
|
|
- stats.total_overproof_alert = accumulatedOverproofAlert;
|
|
|
- stats.total_overproof_2 = accumulatedOverproof2;
|
|
|
- stats.accumulated_days = accumulatedDays;
|
|
|
- stats.is_accumulated = accumulatedTotal >= 5;
|
|
|
-
|
|
|
- // 计算累计超标率(避免除以 0)
|
|
|
- if (accumulatedTotal > 0)
|
|
|
- {
|
|
|
- stats.total_overproofrate = (100 * accumulatedOverproof) / accumulatedTotal;
|
|
|
- stats.total_overproofrate_alert = (100 * accumulatedOverproofAlert) / accumulatedTotal;
|
|
|
- stats.total_overproofrate_2 = (100 * accumulatedOverproof2) / accumulatedTotal;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- stats.total_overproofrate = 0;
|
|
|
- stats.total_overproofrate_alert = 0;
|
|
|
- stats.total_overproofrate_2 = 0;
|
|
|
- }
|
|
|
+
|
|
|
+ // 设置最终统计结果
|
|
|
+ stats.continue_days = continue_days;
|
|
|
+ stats.continue_days_2 = continue_days_2;
|
|
|
+ stats.continue_days_alert = continue_days_alert;
|
|
|
+ stats.last_overproofrate = last_rate;
|
|
|
+ stats.last_overproofrate_2 = last_rate_2;
|
|
|
+ stats.last_overproofrate_alert = last_rate_alert;
|
|
|
+
|
|
|
+ // 同时保留原有的累计字段(用于兼容)
|
|
|
+ stats.total_count = acc_total;
|
|
|
+ stats.total_overproof = acc_over;
|
|
|
+ stats.total_overproof_alert = acc_over_alert;
|
|
|
+ stats.total_overproof_2 = acc_over_2;
|
|
|
+ stats.total_overproofrate = last_rate;
|
|
|
+ stats.total_overproofrate_2 = last_rate_2;
|
|
|
+ stats.total_overproofrate_alert = last_rate_alert;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|