ViewerCard.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <script setup lang="ts">
  2. import { computed, ref, watch } from 'vue'
  3. import Markdown from '/@/components/markdown/Markdown.vue'
  4. import type { MarkdownDashBoard } from './types'
  5. import { MarkdownPlugin } from '/@/components/markdown/type/markdown'
  6. import EChartsPlugin from '/@/components/markdown/plugins/echarts'
  7. import VueCharts from '/@/components/markdown/plugins/impl/VueCharts.vue'
  8. import VueStructData from '/@/components/markdown/plugins/impl/VueStructData.vue'
  9. const plugin: Array<MarkdownPlugin<any>> = [EChartsPlugin()]
  10. const props = defineProps<{
  11. card: MarkdownDashBoard
  12. }>()
  13. // 计算卡片样式
  14. const cardStyle = computed(() => ({
  15. position: 'absolute' as const,
  16. left: `${props.card.x}%`,
  17. top: `${props.card.y}%`,
  18. width: `${props.card.w}%`,
  19. height: `${props.card.h}%`,
  20. zIndex: props.card.z + 100
  21. }))
  22. const charts = ref()
  23. watch(()=> props.card.w, () => {
  24. charts.value?.resize()
  25. })
  26. watch(()=> props.card.h, () => {
  27. charts.value?.resize()
  28. })
  29. </script>
  30. <template>
  31. <div
  32. :style="cardStyle"
  33. class="viewer-card"
  34. >
  35. <el-card class="card-content" shadow="hover">
  36. <!-- 卡片标题栏 -->
  37. <template #header v-if="card.title !== undefined">
  38. <div class="card-header">
  39. <span class="card-title">{{ card.title }}</span>
  40. </div>
  41. </template>
  42. <!-- 卡片内容 -->
  43. <div class="card-body">
  44. <Markdown
  45. v-if="card.type === 'markdown'"
  46. :content="card.data"
  47. :plugins="plugin"
  48. class="markdown-content"
  49. />
  50. <vue-charts ref="charts" style="width: 100%;height: 100%" :data="card.data" v-if="card.type === 'echarts'"/>
  51. <vue-struct-data :uuid="card.data" v-if="card.type === 'structdata'" refresh/>
  52. </div>
  53. </el-card>
  54. </div>
  55. </template>
  56. <style scoped lang="scss">
  57. .viewer-card {
  58. transition: none;
  59. }
  60. .card-content {
  61. height: 100%;
  62. display: flex;
  63. flex-direction: column;
  64. :deep(.el-card__header) {
  65. padding: 12px 16px;
  66. border-bottom: 1px solid var(--el-border-color-lighter);
  67. background: var(--el-fill-color-extra-light);
  68. }
  69. :deep(.el-card__body) {
  70. flex: 1;
  71. padding: 16px;
  72. overflow: auto;
  73. }
  74. }
  75. .card-header {
  76. display: flex;
  77. justify-content: space-between;
  78. align-items: center;
  79. user-select: none;
  80. }
  81. .card-title {
  82. font-weight: 600;
  83. color: var(--el-text-color-primary);
  84. font-size: 14px;
  85. }
  86. .card-body {
  87. height: 100%;
  88. overflow: auto;
  89. }
  90. .markdown-content {
  91. font-size: 13px;
  92. line-height: 1.5;
  93. :deep(h1), :deep(h2), :deep(h3), :deep(h4), :deep(h5), :deep(h6) {
  94. margin-top: 12px;
  95. margin-bottom: 8px;
  96. font-size: 14px;
  97. }
  98. :deep(p) {
  99. margin-bottom: 8px;
  100. }
  101. :deep(blockquote) {
  102. margin: 8px 0;
  103. padding: 8px 12px;
  104. font-size: 12px;
  105. }
  106. :deep(table) {
  107. font-size: 12px;
  108. margin: 8px 0;
  109. }
  110. :deep(th), :deep(td) {
  111. padding: 4px 8px;
  112. }
  113. }
  114. </style>