Refactor analytics report data retrieval and enhance equipment report logic
- Updated the `getQualityReportData` function to improve item name retrieval logic by using `NULLIF` for better handling of empty values. - Refactored the `getEquipmentReportData` function to include company and date filters for equipment statistics, ensuring accurate data aggregation. - Enhanced the SQL queries for both quality and equipment reports to utilize lateral joins and improve performance. - Improved loading states in frontend components for inspection records and inspection results across multiple companies. This refactor enhances data accuracy and user experience in the analytics module.
This commit is contained in:
@@ -310,11 +310,15 @@ function getGroupKey(row: Record<string, any>, groupBy: string): string {
|
||||
function aggregateValues(
|
||||
rows: Record<string, any>[],
|
||||
metricId: string,
|
||||
method: string
|
||||
method: string,
|
||||
metric?: ReportMetric,
|
||||
): number {
|
||||
if (!rows.length) return 0;
|
||||
const vals = rows.map((r) => Number(r[metricId]) || 0);
|
||||
switch (method) {
|
||||
// 비율 메트릭(% 등 isRate)은 행 단위 합계가 의미 없음 → 산술평균으로 강제
|
||||
// (예: 100% 행이 N건이면 sum=N×100% 으로 비정상 누적되는 문제 방지)
|
||||
const effectiveMethod = metric?.isRate && method === "sum" ? "avg" : method;
|
||||
switch (effectiveMethod) {
|
||||
case "sum": return vals.reduce((a, b) => a + b, 0);
|
||||
case "avg": return Math.round((vals.reduce((a, b) => a + b, 0) / vals.length) * 10) / 10;
|
||||
case "max": return Math.max(...vals);
|
||||
@@ -957,10 +961,10 @@ export default function ReportEngine({ config }: ReportEngineProps) {
|
||||
// 각 라벨별 집계값을 한 번에 계산해서 저장 (렌더링 시 lookup 만)
|
||||
const values: Record<string, number> = {};
|
||||
for (const lb in groups) {
|
||||
values[lb] = aggregateValues(groups[lb], metricId, cond.aggMethod);
|
||||
values[lb] = aggregateValues(groups[lb], metricId, cond.aggMethod, m);
|
||||
}
|
||||
// 전체 합계
|
||||
const totalValue = aggregateValues(condData, metricId, cond.aggMethod);
|
||||
const totalValue = aggregateValues(condData, metricId, cond.aggMethod, m);
|
||||
seriesList.push({
|
||||
condId: cond.id,
|
||||
condName: cond.name,
|
||||
@@ -1744,7 +1748,7 @@ export default function ReportEngine({ config }: ReportEngineProps) {
|
||||
const m = config.metrics.find((x) => x.id === metricId);
|
||||
if (!m) return null;
|
||||
const condData = applyConditionFilters(rawData, cond.filters, filterFields);
|
||||
const val = aggregateValues(condData, metricId, cond.aggMethod);
|
||||
const val = aggregateValues(condData, metricId, cond.aggMethod, m);
|
||||
const color = COLORS[ci % COLORS.length];
|
||||
return (
|
||||
<div
|
||||
@@ -2074,9 +2078,10 @@ export default function ReportEngine({ config }: ReportEngineProps) {
|
||||
</td>
|
||||
{analysisResult.series.map((s, si) => {
|
||||
const allRows = subLabels.flatMap((lb) => s.groups[lb] || []);
|
||||
const m = config.metrics.find((x) => x.id === s.metricId);
|
||||
return (
|
||||
<td key={si} className="p-2 text-right tabular-nums">
|
||||
{formatNumber(aggregateValues(allRows, s.metricId, s.aggMethod))}
|
||||
{formatNumber(aggregateValues(allRows, s.metricId, s.aggMethod, m))}
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
@@ -2125,7 +2130,8 @@ export default function ReportEngine({ config }: ReportEngineProps) {
|
||||
let total: number;
|
||||
if (tableSearchQuery) {
|
||||
const allRows = displayLabels.flatMap((lb) => s.groups[lb] || []);
|
||||
total = aggregateValues(allRows, s.metricId, s.aggMethod);
|
||||
const m = config.metrics.find((x) => x.id === s.metricId);
|
||||
total = aggregateValues(allRows, s.metricId, s.aggMethod, m);
|
||||
} else {
|
||||
total = s.totalValue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user