DetailDialog.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <template>
  2. <div>
  3. <el-dialog v-model="visible" title="问题详情" width="80%" align-center :close-on-click-modal="false"
  4. @close="handleClose">
  5. <div class="description-box">
  6. <div class="title">问题描述</div>
  7. <p>{{ description }}</p>
  8. </div>
  9. <div>
  10. <div class="title">问题图片/视频</div>
  11. <div class="media-box">
  12. <div class="video-box" v-if="videoPaths && videoPaths.length != 0">
  13. <img src="@/assets/images/alert/video-play.png" @click="videoDialogVisible = true"
  14. style="object-fit:contain; width:200px; height:200px; border: solid 1px #CCC; cursor: pointer;" />
  15. </div>
  16. <div class="img-box" v-for="(imagePath, index) in imagePaths" :key="index">
  17. <img :src="imagePath" alt="" style="object-fit:contain; width:200px; height:200px; border: solid 1px #CCC"
  18. @mouseenter="handleOpenPre(imagePath, index)">
  19. <div class="cover-box" v-if="isCoverVisible(index)" @mouseleave="handleClosePre(index)">
  20. <el-icon :size="40" color="#e6e6e6" style="cursor: pointer;" @click="handlePreview">
  21. <ZoomIn />
  22. </el-icon>
  23. </div>
  24. </div>
  25. </div>
  26. </div>
  27. </el-dialog>
  28. <el-dialog v-model="dialogVisible">
  29. <img w-full :src="dialogImageUrl" alt="" />
  30. </el-dialog>
  31. <el-dialog v-model="videoDialogVisible" class="video-dialog">
  32. <video type="video/mp4" muted="true" preload="auto" :controls="true" autoplay
  33. style="height: 464px;object-fit: contain;">
  34. <source :src="videoPaths![0]" />
  35. </video>
  36. </el-dialog>
  37. </div>
  38. </template>
  39. <script setup lang="ts">
  40. import { ref } from 'vue';
  41. import { ZoomIn } from '@element-plus/icons-vue';
  42. const props = defineProps({
  43. description: String,
  44. imagePaths: Array<string>,
  45. videoPaths: Array<string>,
  46. });
  47. const emits = defineEmits(['close']);
  48. const visible = ref(true);
  49. const showPreview = ref<boolean[]>(new Array(props.imagePaths?.values.length).fill(false));
  50. const dialogVisible = ref(false);
  51. const dialogImageUrl = ref('');
  52. const videoDialogVisible = ref(false);
  53. const handleOpenPre = (val, index) => {
  54. dialogImageUrl.value = val;
  55. showPreview.value[index] = true;
  56. };
  57. const handleClosePre = (index) => {
  58. showPreview.value[index] = false;
  59. };
  60. const isCoverVisible = (index) => {
  61. return showPreview.value[index];
  62. };
  63. const handlePreview = () => {
  64. dialogVisible.value = true;
  65. };
  66. const handleClose = () => {
  67. emits('close');
  68. }
  69. </script>
  70. <style scoped>
  71. :deep(.el-dialog) {
  72. padding: 0;
  73. background: #FFFFFF;
  74. box-shadow: 0px 9px 28px 8px rgba(0, 0, 0, 0.05), 0px 6px 16px 0px rgba(0, 0, 0, 0.08), 0px 3px 6px -4px rgba(0, 0, 0, 0.12);
  75. .el-dialog__header {
  76. display: flex;
  77. align-items: center;
  78. height: 56px;
  79. padding-left: 24px;
  80. padding-bottom: 0;
  81. border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  82. }
  83. .el-dialog__title {
  84. color: rgba(0, 0, 0, 0.88);
  85. font-size: 16px;
  86. font-weight: 500;
  87. }
  88. .el-dialog__headerbtn .el-dialog__close {
  89. color: #000;
  90. }
  91. .el-dialog__body {
  92. height: 564px;
  93. padding: 40px;
  94. overflow: scroll;
  95. }
  96. }
  97. .title {
  98. margin-bottom: 20px;
  99. color: #303133;
  100. font-size: 16px;
  101. font-weight: 500;
  102. }
  103. .title:before {
  104. margin-right: 8px;
  105. content: '';
  106. border-left: 3px solid #1777FF;
  107. }
  108. .description-box {
  109. margin-bottom: 20px;
  110. p {
  111. color: #606266;
  112. }
  113. }
  114. .media-box {
  115. display: flex;
  116. .video-box {
  117. width: 200px;
  118. height: 200px;
  119. margin-right: 10px;
  120. }
  121. .img-box {
  122. position: relative;
  123. width: 200px;
  124. height: 200px;
  125. margin-right: 10px;
  126. }
  127. .cover-box {
  128. display: flex;
  129. align-items: center;
  130. justify-content: center;
  131. position: absolute;
  132. top: 0;
  133. width: 200px;
  134. height: 200px;
  135. background-color: rgba(0, 0, 0, 0.5);
  136. }
  137. }
  138. :deep(.video-dialog) {
  139. .el-dialog__body {
  140. display: flex;
  141. align-items: center;
  142. justify-content: center;
  143. }
  144. }
  145. </style>