| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- import type { TimeSeriesQuery } from '@jeesite/otg/api/types/query';
- import type { LocationQueryValue } from 'vue-router';
- export const BEHAVIOR_SPACETIME_JUMP_QUERY_KEY = 'jumpPayload';
- export const BEHAVIOR_SPACETIME_JUMP_RESULT_KEY = 'behaviorSpacetimeJumpResult';
- export interface BehaviorSpacetimeJumpPayload extends Partial<TimeSeriesQuery> {
- tableName?: string;
- personName?: string;
- personNames?: string[];
- keyword?: string;
- startDate?: string;
- endDate?: string;
- seriesDateTime?: string;
- }
- type TimeSeriesJumpResponseLike =
- | BehaviorSpacetimeJumpPayload
- | Array<Record<string, unknown>>
- | {
- data?: BehaviorSpacetimeJumpPayload;
- query?: BehaviorSpacetimeJumpPayload;
- record?: BehaviorSpacetimeJumpPayload;
- row?: BehaviorSpacetimeJumpPayload;
- obj?: BehaviorSpacetimeJumpPayload;
- result?: BehaviorSpacetimeJumpPayload;
- }
- | null
- | undefined;
- const pickRouteQueryValue = (value?: LocationQueryValue | LocationQueryValue[]) => {
- return Array.isArray(value) ? value[0] : value;
- };
- const normalizeText = (value: unknown) => {
- if (value === 0) return '0';
- const text = String(value ?? '').trim();
- if (!text || text === 'null' || text === 'undefined') return undefined;
- return text;
- };
- const normalizeStringArray = (value: unknown) => {
- if (Array.isArray(value)) {
- const values = value.map((item) => normalizeText(item)).filter((item): item is string => Boolean(item));
- return values.length ? Array.from(new Set(values)) : undefined;
- }
- const text = normalizeText(value);
- if (!text) return undefined;
- if (text.startsWith('[') && text.endsWith(']')) {
- try {
- const parsed = JSON.parse(text);
- if (Array.isArray(parsed)) return normalizeStringArray(parsed);
- } catch {
- // Ignore invalid JSON and fall back to comma split.
- }
- }
- const values = text
- .split(',')
- .map((item) => normalizeText(item))
- .filter((item): item is string => Boolean(item));
- return values.length ? Array.from(new Set(values)) : undefined;
- };
- const extractIndexedObjectList = (value: unknown) => {
- if (!value || Array.isArray(value) || typeof value !== 'object') return [];
- return Object.entries(value as Record<string, unknown>)
- .filter(([key, item]) => /^\d+$/.test(key) && !!item && typeof item === 'object')
- .sort((left, right) => Number(left[0]) - Number(right[0]))
- .map(([, item]) => item as Record<string, unknown>);
- };
- const normalizeResponseList = (resp?: TimeSeriesJumpResponseLike) => {
- if (Array.isArray(resp)) return resp;
- if (Array.isArray(resp?.data)) return resp.data;
- const indexedDataList = extractIndexedObjectList(resp?.data);
- if (indexedDataList.length) return indexedDataList;
- if (Array.isArray((resp as Record<string, unknown> | undefined)?.records)) {
- return (resp as Record<string, unknown>).records as Array<Record<string, unknown>>;
- }
- if (Array.isArray((resp as Record<string, unknown> | undefined)?.list)) {
- return (resp as Record<string, unknown>).list as Array<Record<string, unknown>>;
- }
- if (Array.isArray((resp as Record<string, unknown> | undefined)?.result)) {
- return (resp as Record<string, unknown>).result as Array<Record<string, unknown>>;
- }
- const indexedRespList = extractIndexedObjectList(resp);
- if (indexedRespList.length) return indexedRespList;
- return [];
- };
- const pickJumpSource = (resp?: TimeSeriesJumpResponseLike) => {
- if (!resp || Array.isArray(resp)) return {};
- return resp.data ?? resp.query ?? resp.record ?? resp.row ?? resp.obj ?? resp.result ?? resp;
- };
- const normalizePayload = (source?: Record<string, unknown>) => {
- const tableNameEn = normalizeText(source?.tableNameEn) || normalizeText(source?.tableName);
- const tableName = normalizeText(source?.tableName) || tableNameEn;
- const personNames = normalizeStringArray(source?.personNames);
- const personName = normalizeText(source?.personName) || (personNames?.length === 1 ? personNames[0] : undefined);
- const id = normalizeText(source?.id);
- const rowId = normalizeText(source?.rowId);
- const startDate = normalizeText(source?.startDate);
- const endDate = normalizeText(source?.endDate);
- const seriesDateTime = normalizeText(source?.seriesDateTime);
- return {
- hasLocal: normalizeText(source?.hasLocal),
- types: normalizeStringArray(source?.types),
- tableName,
- tableNameEn,
- tableNameCn: normalizeText(source?.tableNameCn),
- id,
- rowId,
- personName,
- personNames,
- keyword: normalizeText(source?.keyword),
- startDate,
- endDate,
- seriesDateTime,
- } satisfies BehaviorSpacetimeJumpPayload;
- };
- export const buildTimeSeriesJumpQuery = (query?: Partial<BehaviorSpacetimeJumpPayload>) => {
- return normalizePayload((query || {}) as Record<string, unknown>);
- };
- export const hasMeaningfulJumpPayload = (payload?: Partial<BehaviorSpacetimeJumpPayload> | null) => {
- if (!payload) return false;
- return Boolean(
- payload.id ||
- payload.rowId ||
- payload.tableNameEn ||
- payload.tableName ||
- payload.personName ||
- payload.personNames?.length ||
- payload.types?.length ||
- payload.keyword ||
- payload.startDate ||
- payload.endDate ||
- payload.seriesDateTime,
- );
- };
- export const resolveBehaviorSpacetimeJumpPayload = (
- resp?: TimeSeriesJumpResponseLike,
- fallback?: Partial<BehaviorSpacetimeJumpPayload>,
- ) => {
- const responseList = normalizeResponseList(resp);
- if (responseList.length) {
- const fallbackPayload = buildTimeSeriesJumpQuery(fallback);
- const responsePersonNames = normalizeStringArray(
- responseList.map((item) => normalizeText(item?.personName)).filter(Boolean),
- );
- const personNames = fallbackPayload.personNames?.length ? fallbackPayload.personNames : responsePersonNames;
- const orderedDateTimes = responseList
- .map((item) => normalizeText(item?.seriesDateTime))
- .filter((item): item is string => Boolean(item))
- .sort((left, right) => new Date(left).getTime() - new Date(right).getTime());
- const startDate = orderedDateTimes[0];
- const endDate = orderedDateTimes[orderedDateTimes.length - 1];
- return buildTimeSeriesJumpQuery({
- ...fallbackPayload,
- personName: fallbackPayload.personName || (personNames?.length === 1 ? personNames[0] : undefined),
- personNames,
- keyword: undefined,
- startDate: fallbackPayload.startDate || startDate,
- endDate: fallbackPayload.endDate || endDate,
- });
- }
- const normalizedResp = normalizePayload(pickJumpSource(resp) as Record<string, unknown>);
- if (hasMeaningfulJumpPayload(normalizedResp)) return normalizedResp;
- return buildTimeSeriesJumpQuery(fallback);
- };
- export const persistBehaviorSpacetimeJumpResult = (resp?: unknown) => {
- if (typeof window === 'undefined') return;
- try {
- if (!resp) {
- window.sessionStorage.removeItem(BEHAVIOR_SPACETIME_JUMP_RESULT_KEY);
- return;
- }
- window.sessionStorage.setItem(BEHAVIOR_SPACETIME_JUMP_RESULT_KEY, JSON.stringify(resp));
- } catch {
- // Ignore storage errors.
- }
- };
- export const consumeBehaviorSpacetimeJumpResult = () => {
- if (typeof window === 'undefined') return null;
- try {
- const raw = window.sessionStorage.getItem(BEHAVIOR_SPACETIME_JUMP_RESULT_KEY);
- if (!raw) return null;
- window.sessionStorage.removeItem(BEHAVIOR_SPACETIME_JUMP_RESULT_KEY);
- return JSON.parse(raw);
- } catch {
- return null;
- }
- };
- const buildBehaviorSpacetimeNavigationPayload = (payload?: Partial<BehaviorSpacetimeJumpPayload>) => {
- const normalized = buildTimeSeriesJumpQuery(payload);
- return {
- ...normalized,
- id: normalized.id || normalized.rowId,
- rowId: undefined,
- } satisfies BehaviorSpacetimeJumpPayload;
- };
- export const serializeBehaviorSpacetimeJumpPayload = (payload?: Partial<BehaviorSpacetimeJumpPayload>) => {
- return JSON.stringify(buildBehaviorSpacetimeNavigationPayload(payload));
- };
- export const parseBehaviorSpacetimeJumpPayload = (raw?: LocationQueryValue | LocationQueryValue[]) => {
- const text = pickRouteQueryValue(raw);
- if (!text) return null;
- try {
- const parsed = JSON.parse(String(text));
- const payload = buildTimeSeriesJumpQuery(parsed as Partial<BehaviorSpacetimeJumpPayload>);
- return hasMeaningfulJumpPayload(payload) ? payload : null;
- } catch {
- return null;
- }
- };
|