import { computed, reactive, ref, watch, watchEffect, watchPostEffect, } from "vue"; import { autoSetModeCallback, unSetModelUpdate, createTemploraryID, } from "./sys"; import { custom } from "@/env"; import { fetchFuseModels, postAddFuseModel, postDeleteFuseModel, postUpdateFuseModels, SceneType, SceneStatus, } from "@/api"; import { deleteStoreItem, updateStoreItem, fetchStoreItems, saveStoreItems, deepIsRevise, } from "@/utils"; import { initialTaggings } from "./tagging"; import { initialMeasures } from "./measure"; import type { FuseModel as SModel, FuseModelAttrs } from "@/api"; import { isUnSet } from "@/utils/unset"; export type FuseModel = SModel & { loaded: boolean; error: boolean; progress: number; }; export type FuseModels = FuseModel[]; export type { FuseModelAttrs } from "@/api"; export const fuseModels = ref([]); export const dynamicAddedModelIds = ref([]); export const defaultFuseModelAttrs: FuseModelAttrs = { show: true, scale: 100, opacity: 100, bottom: 0, position: { x: 0, y: 0, z: 0 }, rotation: { x: 0, y: 0, z: 0 }, }; export const createFuseModels = (model: Partial = {}): FuseModel => serviceToLocal({ id: createTemploraryID(), modelId: 0, fusionNumId: 0, url:[ ""], fusionId: 0, title: "", modelType: "glb", type: SceneType.SWMX, status: SceneStatus.SUCCESS, size: 0, time: new Date().toString(), ...defaultFuseModelAttrs, ...model, }); export const getFuseModel = (modelId: FuseModel["id"]) => fuseModels.value.find((model) => model.id === modelId); let setModel: FuseModel; export const getFuseModelShowVariable = (model: FuseModel) => computed({ get: () => { return false && custom.modelsChangeStore ? model.show : custom.showModelsMap.get(model) || false; }, set: (show: boolean) => { if (false && custom.modelsChangeStore) { model.show = show; } else { setModel = model; custom.showModelsMap.set(model, show); } }, }); watchEffect( () => { fuseModels.value.forEach((item) => custom.showModelsMap.get(item)); }, { flush: "sync" } ); export const fuseModelsLoaded = ref(false); watchPostEffect(() => { const loaded = fuseModels.value .filter((model) => getFuseModelShowVariable(model).value) .every((model) => model.loaded || model.error); console.log('a?') fuseModelsLoaded.value = loaded; }); let bcModels: FuseModels = []; export const getBackupFuseModels = () => bcModels; export const backupFuseModels = () => { console.error('???') bcModels = JSON.parse(JSON.stringify(fuseModels.value)) console.log('bcModels', bcModels) for (const model of fuseModels.value) { initFuseModel(model); } }; watch( fuseModels, () => { for (const model of bcModels) { const newModel = getFuseModel(model.id); if (newModel) { model.progress = newModel.progress; model.error = newModel.error; model.loaded = newModel.loaded; } } }, { deep: true } ); const serviceToLocal = (model: SModel): FuseModel => ({ ...model, error: false, loaded: false, progress: 0, }); const initFuseModel = (model: FuseModel) => { custom.showModelsMap.has(model) || custom.showModelsMap.set(model, model.show); }; export const recoverFuseModels = () => { const backupItems = getBackupFuseModels(); fuseModels.value = backupItems.map((oldItem) => { const model = fuseModels.value.find((item) => item.id === oldItem.id); return model ? Object.assign(model, oldItem) : serviceToLocal(oldItem); }); }; export const updateFuseModel = updateStoreItem( fuseModels, postUpdateFuseModels ); export const deleteFuseModel = deleteStoreItem(fuseModels, async (model) => { await postDeleteFuseModel(model); const index = dynamicAddedModelIds.value.indexOf(model.id); ~index && dynamicAddedModelIds.value.splice(index, 1); }); export const addFuseModel = async (model: FuseModel) => { const addModel = reactive(serviceToLocal(await postAddFuseModel(model))); initFuseModel(addModel); unSetModelUpdate(() => { fuseModels.value.push(addModel); dynamicAddedModelIds.value.push(addModel.id); }); backupFuseModels() }; export const initialFuseModels = fetchStoreItems( fuseModels, fetchFuseModels, () => { for (const model of fuseModels.value) { initFuseModel(model); } backupFuseModels(); }, (smodels) => smodels.map(serviceToLocal) ); export const saveFuseModels = saveStoreItems(fuseModels, getBackupFuseModels, { update: updateFuseModel, delete: deleteFuseModel, }); export const autoSaveFuseModels = autoSetModeCallback(fuseModels, { isUpdate: (fuseModels) => { // if (isUnSet) return false return deepIsRevise( fuseModels.map((item) => ({ ...item, loaded: true, error: true, progress: 0, })), getBackupFuseModels().map((item) => ({ ...item, loaded: true, error: true, progress: 0, })) ) }, backup: backupFuseModels, recovery: async () => { recoverFuseModels() await new Promise((resolve) => { setTimeout(() => { resolve() }, 100) }) }, save: async () => { await saveFuseModels(); // for (const model of bcModels) { // const currentModel = getFuseModel(model.id) // if (currentModel && currentModel.show !== model.show) { // custom.showModelsMap.set(currentModel, currentModel.show) // } // } await Promise.all([initialTaggings(), initialMeasures()]); }, });