import { computed, ref, watch } from 'vue';
|
import { useDark } from '@vueuse/core';
|
import { useTheme } from '/#/theme';
|
import { useCool } from '/@/cool';
|
import {
|
groupDemoFields
|
} from '../data/screen-field-meta';
|
import {
|
initialScreenData,
|
resolveScreenData,
|
type ScreenDataMode
|
} from '../data/screen-merge';
|
import type { ScreenData, TimeRange } from '../data/screen';
|
|
const sharedTimeRange = ref<TimeRange>('month');
|
const initial = initialScreenData(sharedTimeRange.value);
|
const screenData = ref<ScreenData>(initial.data);
|
const dataMode = ref<ScreenDataMode>(initial.mode);
|
const demoFields = ref<string[]>(initial.demoFields);
|
const liveFields = ref<string[]>(initial.liveFields);
|
const loading = ref(false);
|
const loadError = ref('');
|
/** 驾驶舱是否处于浏览器全屏;萤石播放器在全屏切换后需 remount 才能恢复画面 */
|
const screenFullscreen = ref(false);
|
const playerRemountKey = ref(0);
|
|
export function provideScreenTime() {
|
return sharedTimeRange;
|
}
|
|
export function useScreenTime() {
|
return sharedTimeRange;
|
}
|
|
export function useScreenFullscreen() {
|
function bumpPlayerRemount(delay = 280) {
|
window.setTimeout(() => {
|
playerRemountKey.value += 1;
|
window.dispatchEvent(
|
new CustomEvent('report-screen-fullscreen-change', {
|
detail: { remountKey: playerRemountKey.value }
|
})
|
);
|
}, delay);
|
}
|
|
function setFullscreen(active: boolean) {
|
const changed = screenFullscreen.value !== active;
|
screenFullscreen.value = active;
|
if (changed) {
|
bumpPlayerRemount();
|
}
|
}
|
|
return {
|
isFullscreen: screenFullscreen,
|
playerRemountKey,
|
bumpPlayerRemount,
|
setFullscreen
|
};
|
}
|
|
export function useScreenData() {
|
return {
|
timeRange: sharedTimeRange,
|
data: screenData,
|
dataMode,
|
demoFields,
|
liveFields,
|
loading,
|
loadError,
|
reload: () => loadImpl()
|
};
|
}
|
|
let inited = false;
|
let loadImpl: () => Promise<void> = async () => {};
|
|
function applyResolved(resolved: ReturnType<typeof resolveScreenData>) {
|
screenData.value = resolved.data;
|
dataMode.value = resolved.mode;
|
demoFields.value = resolved.demoFields;
|
liveFields.value = resolved.liveFields;
|
}
|
|
export function useScreenLoader() {
|
const { service } = useCool();
|
|
async function load() {
|
loading.value = true;
|
loadError.value = '';
|
try {
|
const payload = { range: sharedTimeRange.value };
|
const screen = service.report?.screen;
|
const res: ScreenData = screen?.query
|
? await screen.query(payload)
|
: await service.request({
|
url: 'admin/report/screen/query',
|
method: 'POST',
|
data: payload
|
});
|
applyResolved(resolveScreenData(res, sharedTimeRange.value));
|
} catch (e: any) {
|
applyResolved(resolveScreenData(null, sharedTimeRange.value));
|
const msg = e?.message || '';
|
if (!/登录失效|无权限/.test(msg)) {
|
loadError.value = msg || '驾驶舱接口调用失败';
|
}
|
} finally {
|
loading.value = false;
|
}
|
}
|
|
loadImpl = load;
|
|
if (!inited) {
|
inited = true;
|
watch(sharedTimeRange, () => load());
|
}
|
|
load();
|
|
return { load, loading, loadError, dataMode };
|
}
|
|
/** 首页只展示接口汇总结果,不再用演示数据填充 */
|
export function useScreenFieldSource() {
|
const { dataMode, demoFields } = useScreenData();
|
|
const demoSections = computed(() => groupDemoFields(demoFields.value));
|
|
function demoSection(_section: string) {
|
return false;
|
}
|
|
function demoField(_field: string) {
|
return false;
|
}
|
|
return {
|
dataMode,
|
demoSections,
|
isDemoSection: demoSection,
|
isDemoField: demoField
|
};
|
}
|
|
export function useChartTheme() {
|
const isDark = useDark();
|
const theme = useTheme();
|
|
const textColor = computed(() => (isDark.value ? '#e5e7eb' : '#334155'));
|
const mutedColor = computed(() => (isDark.value ? '#94a3b8' : '#64748b'));
|
const splitColor = computed(() => (isDark.value ? '#334155' : '#e2e8f0'));
|
const tooltipBg = computed(() => (isDark.value ? '#0f172a' : '#ffffff'));
|
const primary = computed(() => theme.color || '#16a34a');
|
|
function baseGrid() {
|
return { containLabel: true, left: 12, right: 16, top: 28, bottom: 8 };
|
}
|
|
function axisStyle() {
|
return {
|
axisLine: { show: false },
|
axisTick: { show: false },
|
splitLine: { show: false },
|
axisLabel: { color: mutedColor.value }
|
};
|
}
|
|
function tooltip() {
|
return {
|
backgroundColor: tooltipBg.value,
|
borderColor: splitColor.value,
|
textStyle: { color: textColor.value }
|
};
|
}
|
|
return {
|
isDark,
|
textColor,
|
mutedColor,
|
splitColor,
|
tooltipBg,
|
primary,
|
baseGrid,
|
axisStyle,
|
tooltip
|
};
|
}
|