fuse-model.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import { computed, ref, watch, watchEffect, watchPostEffect } from 'vue'
  2. import { autoSetModeCallback, unSetModelUpdate, createTemploraryID } from './sys'
  3. import { custom } from '@/env'
  4. import {
  5. fetchFuseModels,
  6. postAddFuseModel,
  7. postDeleteFuseModel,
  8. postUpdateFuseModels,
  9. SceneType
  10. } from '@/api'
  11. import {
  12. deleteStoreItem,
  13. addStoreItem,
  14. updateStoreItem,
  15. fetchStoreItems,
  16. saveStoreItems,
  17. recoverStoreItems,
  18. deepIsRevise
  19. } from '@/utils'
  20. import { initialTaggings } from './tagging'
  21. import { initialMeasures } from './measure'
  22. import type { FuseModel as SModel, FuseModelAttrs } from '@/api'
  23. export type FuseModel = SModel & { loaded: boolean, error: boolean, progress: number }
  24. export type FuseModels = FuseModel[]
  25. export type { FuseModelAttrs } from '@/api'
  26. export const fuseModels = ref<FuseModels>([])
  27. export const defaultFuseModelAttrs: FuseModelAttrs = {
  28. show: true,
  29. scale: 100,
  30. opacity: 100,
  31. bottom: 0,
  32. position: {x: 0, y: 0, z: 0},
  33. rotation: {x: 0, y: 0, z: 0}
  34. }
  35. export const createFuseModels = (model: Partial<FuseModel> = {}): FuseModel => serviceToLocal({
  36. id: createTemploraryID(),
  37. modelId: 0,
  38. fusionNumId: 0,
  39. url: '',
  40. fusionId: 0,
  41. title: '',
  42. type: SceneType.SWMX,
  43. size: 0,
  44. time: new Date().toString(),
  45. ...defaultFuseModelAttrs,
  46. ...model
  47. })
  48. export const getFuseModel = (modelId: FuseModel['id']) => fuseModels.value.find(model => model.id === modelId)
  49. export const getFuseModelShowVariable = (model: FuseModel) =>
  50. computed({
  51. get: () => custom.modelsChangeStore
  52. ? model.show
  53. : custom.showModelsMap.get(model) || false,
  54. set: (show: boolean) => {
  55. if (custom.modelsChangeStore) {
  56. model.show = show
  57. } else {
  58. custom.showModelsMap.set(model, show)
  59. }
  60. }
  61. })
  62. export const fuseModelsLoaded = ref(false)
  63. watchPostEffect(() => {
  64. const loaded = fuseModels.value
  65. .filter(model => getFuseModelShowVariable(model).value)
  66. .every(model => model.loaded || model.error)
  67. fuseModelsLoaded.value = loaded
  68. })
  69. let bcModels: FuseModels = []
  70. export const getBackupFuseModels = () => bcModels
  71. export const backupFuseModels = () => {
  72. bcModels = fuseModels.value.map(model => ({
  73. ...model,
  74. rotation: {...model.rotation},
  75. position: {...model.position},
  76. }))
  77. }
  78. watchEffect(() => {
  79. for (const model of bcModels) {
  80. const newModel = getFuseModel(model.id)
  81. if (newModel) {
  82. model.progress = newModel.progress
  83. model.error = newModel.error
  84. model.loaded = newModel.loaded
  85. }
  86. }
  87. })
  88. const serviceToLocal = (model: SModel): FuseModel => ({
  89. ...model,
  90. error: false,
  91. loaded: false,
  92. progress: 0,
  93. })
  94. const initFuseModel = (model: FuseModel) => {
  95. custom.showModelsMap.set(model, model.show)
  96. }
  97. export const recoverFuseModels = () => {
  98. const backupItems = getBackupFuseModels()
  99. fuseModels.value = backupItems.map(oldItem => {
  100. const model = fuseModels.value.find(item => item.id === oldItem.id)
  101. return model ? Object.assign(model, oldItem) : serviceToLocal(oldItem)
  102. })
  103. }
  104. export const updateFuseModel = updateStoreItem(fuseModels, postUpdateFuseModels)
  105. export const deleteFuseModel = deleteStoreItem(fuseModels, postDeleteFuseModel)
  106. export const addFuseModel = async (model: FuseModel) => {
  107. const addModel = serviceToLocal(await postAddFuseModel(model))
  108. initFuseModel(addModel)
  109. unSetModelUpdate(() => fuseModels.value.push(addModel))
  110. }
  111. export const initialFuseModels = fetchStoreItems(
  112. fuseModels,
  113. fetchFuseModels,
  114. () => {
  115. for (const model of fuseModels.value) {
  116. initFuseModel(model)
  117. }
  118. backupFuseModels()
  119. },
  120. smodels => smodels.map(serviceToLocal),
  121. )
  122. export const saveFuseModels = saveStoreItems(
  123. fuseModels,
  124. getBackupFuseModels,
  125. {
  126. update: updateFuseModel,
  127. delete: deleteFuseModel
  128. }
  129. )
  130. export const autoSaveFuseModels = autoSetModeCallback(fuseModels, {
  131. isUpdate: (fuseModels) =>
  132. deepIsRevise(
  133. fuseModels.map(item => ({...item, loaded: true, error: true, progress: 0})),
  134. getBackupFuseModels().map(item => ({...item, loaded: true, error: true, progress: 0}))
  135. ),
  136. backup: backupFuseModels,
  137. recovery: recoverFuseModels,
  138. save: async () => {
  139. await saveFuseModels()
  140. for (const model of bcModels) {
  141. const currentModel = getFuseModel(model.id)
  142. if (currentModel && currentModel.show !== model.show) {
  143. custom.showModelsMap.set(currentModel, currentModel.show)
  144. }
  145. }
  146. await Promise.all([
  147. initialTaggings(),
  148. initialMeasures()
  149. ])
  150. },
  151. })