|
|
@@ -1,29 +1,14 @@
|
|
|
import { defineStore } from 'pinia'
|
|
|
import { computed, ref } from 'vue'
|
|
|
|
|
|
-import { fetchState, saveState } from '../api/state'
|
|
|
import { getViewer } from '../three/instance'
|
|
|
-import type { PartMeta, PartStatus, SavedState } from '../types'
|
|
|
-
|
|
|
-interface CycleStep {
|
|
|
- label: string
|
|
|
- apply: (id: string) => void
|
|
|
-}
|
|
|
+import type { PartMeta, PartStatus } from '../types'
|
|
|
|
|
|
export const usePartsStore = defineStore('parts', () => {
|
|
|
const parts = ref<PartMeta[]>([])
|
|
|
const selected = ref<Set<string>>(new Set())
|
|
|
const queryOpen = ref(false)
|
|
|
const search = ref('')
|
|
|
- const saveStatus = ref('')
|
|
|
- const cycleText = ref('')
|
|
|
-
|
|
|
- let currentModel = ''
|
|
|
- let saveTimer: ReturnType<typeof setTimeout> | undefined
|
|
|
- let toastTimer: ReturnType<typeof setTimeout> | undefined
|
|
|
- let cycleTimer: ReturnType<typeof setInterval> | undefined
|
|
|
- let cyclePartId: string | null = null
|
|
|
- let cycleStep = 0
|
|
|
|
|
|
const selectedParts = computed(() => parts.value.filter((p) => selected.value.has(p.id)))
|
|
|
const selectedCount = computed(() => selected.value.size)
|
|
|
@@ -76,94 +61,24 @@ export const usePartsStore = defineStore('parts', () => {
|
|
|
getViewer()?.resetPart(id)
|
|
|
}
|
|
|
|
|
|
- function toast(msg: string): void {
|
|
|
- saveStatus.value = msg
|
|
|
- clearTimeout(toastTimer)
|
|
|
- toastTimer = setTimeout(() => { saveStatus.value = '' }, 2500)
|
|
|
- }
|
|
|
-
|
|
|
function applyPreset(hex: string, status: PartStatus | null): void {
|
|
|
- if (!selected.value.size) { toast('请先选择一个部件'); return }
|
|
|
+ if (!selected.value.size) return
|
|
|
selected.value.forEach((id) => setColor(id, hex, status))
|
|
|
- scheduleSave()
|
|
|
}
|
|
|
|
|
|
function resetSelected(): void {
|
|
|
- if (!selected.value.size) { toast('请先选择一个部件'); return }
|
|
|
+ if (!selected.value.size) return
|
|
|
selected.value.forEach((id) => resetColor(id))
|
|
|
- scheduleSave()
|
|
|
}
|
|
|
|
|
|
function resetAll(): void {
|
|
|
- stopCycle()
|
|
|
parts.value.forEach((p) => resetColor(p.id))
|
|
|
- scheduleSave()
|
|
|
- }
|
|
|
-
|
|
|
- /* ---------------- 持久化 ---------------- */
|
|
|
- function scheduleSave(): void {
|
|
|
- clearTimeout(saveTimer)
|
|
|
- saveStatus.value = '保存中…'
|
|
|
- saveTimer = setTimeout(doSave, 400)
|
|
|
- }
|
|
|
-
|
|
|
- async function doSave(): Promise<void> {
|
|
|
- if (!currentModel) return
|
|
|
- const state: SavedState = {}
|
|
|
- parts.value.forEach((p) => {
|
|
|
- if (p.colorHex) state[p.id] = { color: p.colorHex, status: p.status }
|
|
|
- })
|
|
|
- try {
|
|
|
- await saveState(currentModel, state)
|
|
|
- saveStatus.value = '✓ 已保存 ' + new Date().toLocaleTimeString('zh-CN', { hour12: false })
|
|
|
- } catch {
|
|
|
- saveStatus.value = '保存失败'
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- async function applySavedState(model: string): Promise<void> {
|
|
|
- currentModel = model
|
|
|
- const state = await fetchState(model)
|
|
|
- parts.value.forEach((p) => {
|
|
|
- const saved = state[p.id]
|
|
|
- if (saved && saved.color) setColor(p.id, saved.color, saved.status ?? null)
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- /* ---------------- 时序着色演示 ---------------- */
|
|
|
- const cycleSteps: CycleStep[] = [
|
|
|
- { label: '本色', apply: (id) => resetColor(id) },
|
|
|
- { label: '预警', apply: (id) => setColor(id, '#F9A825', 'warn') },
|
|
|
- { label: '故障', apply: (id) => setColor(id, '#E53935', 'fault') },
|
|
|
- ]
|
|
|
-
|
|
|
- function startCycle(id: string): void {
|
|
|
- stopCycle()
|
|
|
- cyclePartId = id
|
|
|
- cycleStep = 0
|
|
|
- const tick = (): void => {
|
|
|
- const step = cycleSteps[cycleStep]
|
|
|
- step.apply(id)
|
|
|
- cycleText.value = `${cycleStep + 1}/3 ${step.label}`
|
|
|
- cycleStep = (cycleStep + 1) % cycleSteps.length
|
|
|
- }
|
|
|
- tick()
|
|
|
- cycleTimer = setInterval(tick, 1000)
|
|
|
- }
|
|
|
-
|
|
|
- function stopCycle(): void {
|
|
|
- if (cycleTimer) { clearInterval(cycleTimer); cycleTimer = undefined }
|
|
|
- if (cyclePartId) resetColor(cyclePartId)
|
|
|
- cyclePartId = null
|
|
|
- cycleStep = 0
|
|
|
- cycleText.value = ''
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
- parts, selected, queryOpen, search, saveStatus, cycleText,
|
|
|
+ parts, selected, queryOpen, search,
|
|
|
selectedParts, selectedCount,
|
|
|
byId, setParts, selectOnly, toggle, clearSelection,
|
|
|
setColor, resetColor, applyPreset, resetSelected, resetAll,
|
|
|
- applySavedState, startCycle, stopCycle,
|
|
|
}
|
|
|
})
|