You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
6.5 KiB
TypeScript

import { getMonitorInfoTree } from '@/api/ems/base/baseMonitorInfo';
import type { VibrationBoardQuery } from '@/api/ems/types';
import { createDefaultTimeRange } from './vibrationBoardShared';
type VibrationBoardQueryForm = {
compareScope: string;
monitorId: string;
monitorIds: string[];
selectionLabel: string;
samplingInterval: number;
vibrationParam: string;
highThreshold: number | undefined;
warningThreshold: number | undefined;
minContinuousSamples: number | undefined;
rapidRiseThreshold: number | undefined;
stddevThreshold: number | undefined;
};
type BuildQueryOptions = {
includeVibrationParam?: boolean;
};
const createDefaultQueryForm = (defaultMetric = 'vibrationSpeed'): VibrationBoardQueryForm => ({
compareScope: 'all',
monitorId: '',
monitorIds: [],
selectionLabel: '全部振动设备',
samplingInterval: 5,
vibrationParam: defaultMetric,
highThreshold: undefined,
warningThreshold: undefined,
minContinuousSamples: undefined,
rapidRiseThreshold: undefined,
stddevThreshold: undefined
});
// 模块级缓存:同一浏览器会话内 7 个页面共享设备树与查询状态,避免重复请求和切页丢筛选。
const sharedState = reactive({
treeLoaded: false,
monitorTreeOptions: [] as any[],
deviceDisplayMap: {} as Record<string, string>,
daterangeRecordTime: createDefaultTimeRange() as string[],
queryForm: createDefaultQueryForm()
});
export function useVibrationBoardQueryState(defaultMetric = 'vibrationSpeed') {
const localState = reactive({
loading: false,
treeLoading: false,
treeProps: { label: 'label', children: 'children' }
});
// 仅在首次进入页面时应用默认主看指标,后续页面切换沿用用户最新选择。
if (!sharedState.queryForm.vibrationParam) {
sharedState.queryForm.vibrationParam = defaultMetric;
}
const { loading, treeLoading, treeProps } = toRefs(localState);
const { monitorTreeOptions, deviceDisplayMap, daterangeRecordTime, queryForm } = toRefs(sharedState);
const deviceCount = computed(() => queryForm.value.monitorIds?.length || (queryForm.value.monitorId ? 1 : 0));
const hasMultiDevice = computed(() => deviceCount.value > 1 || ['group', 'all'].includes(queryForm.value.compareScope));
const buildDeviceDisplayMap = (nodes: any[]): Record<string, string> =>
(nodes || []).reduce(
(acc, item) => {
if (item.code && !item.children?.length) acc[item.code] = item.label;
if (item.children?.length) Object.assign(acc, buildDeviceDisplayMap(item.children));
return acc;
},
{} as Record<string, string>
);
const getLeafNodes = (nodes: any[]): any[] =>
(nodes || []).flatMap((item) => (item.children?.length ? getLeafNodes(item.children) : item.code ? [item] : []));
const buildSelection = (nodes: any[], selectionLabel: string, compareScope?: string) => {
const monitorIds = nodes.map((item) => item.code);
return {
compareScope: compareScope || (monitorIds.length > 1 ? 'group' : 'single'),
monitorId: monitorIds.length === 1 ? monitorIds[0] : '',
monitorIds,
selectionLabel
};
};
const applySelection = (selection: any) => {
Object.assign(queryForm.value, selection);
};
const setTimeRange = (value: string[]) => {
daterangeRecordTime.value = value;
};
const setSamplingInterval = (value: number) => {
queryForm.value.samplingInterval = value;
};
const setVibrationParam = (value: string) => {
queryForm.value.vibrationParam = value;
};
const resetAnomalyThresholds = () => {
// 主看指标切换后必须回到“未覆盖”状态,让后端按新指标重新下发默认阈值,
// 否则会把上一指标的阈值误当成当前指标的用户自定义值。
queryForm.value.highThreshold = undefined;
queryForm.value.warningThreshold = undefined;
queryForm.value.minContinuousSamples = undefined;
queryForm.value.rapidRiseThreshold = undefined;
queryForm.value.stddevThreshold = undefined;
};
const loadTree = async () => {
// 已加载且有缓存时直接复用,避免 7 个页面重复打同一个树接口。
if (sharedState.treeLoaded) {
return;
}
treeLoading.value = true;
try {
const response = await getMonitorInfoTree({ monitorType: 10 });
monitorTreeOptions.value = response.data || [];
deviceDisplayMap.value = buildDeviceDisplayMap(monitorTreeOptions.value);
sharedState.treeLoaded = true;
if (!queryForm.value.monitorIds.length && !queryForm.value.monitorId) {
applySelection(buildSelection(getLeafNodes(monitorTreeOptions.value), '全部振动设备', 'all'));
}
} finally {
treeLoading.value = false;
}
};
const handleTreeNodeClick = (data: any) => {
if (!data) return;
if (data.children?.length) {
applySelection(buildSelection(getLeafNodes(data.children), `${data.label}设备组`, 'group'));
return;
}
applySelection(buildSelection([data], data.label, 'single'));
};
const buildQuery = (options?: BuildQueryOptions): VibrationBoardQuery => ({
samplingInterval: queryForm.value.samplingInterval,
// 质量页不展示主看指标时,必须禁掉这个隐藏筛选条件,
// 否则会继承其它页面的指标选择,悄悄改变质量统计口径。
vibrationParam: options?.includeVibrationParam === false ? undefined : queryForm.value.vibrationParam,
beginRecordTime: daterangeRecordTime.value[0],
endRecordTime: daterangeRecordTime.value[1],
highThreshold: queryForm.value.highThreshold,
warningThreshold: queryForm.value.warningThreshold,
minContinuousSamples: queryForm.value.minContinuousSamples,
rapidRiseThreshold: queryForm.value.rapidRiseThreshold,
stddevThreshold: queryForm.value.stddevThreshold,
monitorId: queryForm.value.monitorIds?.length > 1 ? undefined : queryForm.value.monitorIds?.[0] || queryForm.value.monitorId,
monitorIds: queryForm.value.monitorIds?.length > 1 ? queryForm.value.monitorIds : undefined,
params: {
beginRecordTime: daterangeRecordTime.value[0],
endRecordTime: daterangeRecordTime.value[1]
}
});
const getMonitorDisplayName = (monitorId?: string) => (monitorId ? deviceDisplayMap.value[monitorId] || monitorId : '--');
return {
loading,
treeLoading,
monitorTreeOptions,
treeProps,
daterangeRecordTime,
queryForm,
deviceCount,
hasMultiDevice,
loadTree,
handleTreeNodeClick,
setTimeRange,
setSamplingInterval,
setVibrationParam,
resetAnomalyThresholds,
buildQuery,
getMonitorDisplayName
};
}