Vibration.vue 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. <script setup lang="ts">
  2. import { vUnwrap } from '../lib/unwrap'
  3. /**
  4. * 振动融合分析(vibration)——对应重构前 `app.js` 的 `vibration()`。
  5. *
  6. * 该页签内部有 **5 个子视图**(旧 `FUS.sub`):matrix(判级矩阵,默认)/ loop / units / events / cms。
  7. * 本版只迁 **matrix**,其余如实标"迁移中";5 个子视图全过对拍后才列入 DONE。
  8. */
  9. import {computed, ref, watch } from 'vue'
  10. import { t } from '../i18n/zh'
  11. import { FUS_SUBS, cmsHtml, eventsHtml, loopHtml, matrixHtml, portalCmsHtml, unitsHtml } from '../lib/vib'
  12. const props = defineProps<{ d: any; sub?: string | null; cms?: any }>()
  13. const emit = defineEmits<{ (e: 'sub', id: string): void }>()
  14. const sub = computed(() => props.sub || 'matrix')
  15. /** ★P63 照旧页 app.js:980 —— 选中 cms 子视图时**按需异步取** `/api/vibcms`(prop 优先,用于对拍同源)。
  16. * 实逮:此前应用从不取该接口 ⇒ 真实打开「振动分析」时无数据(对拍工具喂数据把它掩盖了)。 */
  17. const cmsLocal = ref<any>(null)
  18. const cmsErr = ref<string>('')
  19. watch(sub, async (s) => {
  20. if ((s === 'cms' || s === 'portal_cms') && !cmsLocal.value && !props.cms && !cmsErr.value) {
  21. try {
  22. const r = await fetch('/api/vibcms')
  23. cmsLocal.value = await r.json()
  24. } catch (e) {
  25. cmsErr.value = String((e as any)?.message || e)
  26. }
  27. }
  28. }, { immediate: true })
  29. const cmsData = computed<any>(() => props.cms ?? cmsLocal.value)
  30. const F = computed<any>(() => props.d?.fus)
  31. const bodyHtml = computed(() => {
  32. const f = F.value
  33. if (!f || f.err) return `<section><div class="panel"><p>${t('fus.unavailable', { e: String((f && f.err) || '') })}</p></div></section>`
  34. if (sub.value === 'matrix') return matrixHtml(f)
  35. if (sub.value === 'loop') return loopHtml(f)
  36. if (sub.value === 'units') return unitsHtml(f, null)
  37. if (sub.value === 'events') return eventsHtml(f, props.d)
  38. if (sub.value === 'cms') return cmsHtml(cmsData.value)
  39. if (sub.value === 'portal_cms') return portalCmsHtml(props.d, cmsData.value) // ★P65 门户「振动·CMS」(受时间窗影响)
  40. return `<div class="panel mb"><p class="small muted">子视图「${t('fus.sub.' + sub.value)}」尚未迁移到 Vue(迁移中)。</p></div>`
  41. })
  42. </script>
  43. <template>
  44. <section>
  45. <div class="eyebrow">{{ t('fus.eyebrow') }}</div>
  46. <div style="display:flex;gap:8px;margin-bottom:14px;flex-wrap:wrap">
  47. <button v-for="s in FUS_SUBS" :key="s" class="pill" :class="{ on: s === sub }" :data-fsub="s"
  48. @click="emit('sub', s)">{{ t('fus.sub.' + s) }}</button>
  49. </div>
  50. <div class="unwrap-host" v-html="bodyHtml"></div>
  51. </section>
  52. </template>