1
0

index.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <template>
  2. <div>
  3. <div class="demo-image__preview">
  4. <el-image-viewer
  5. hide-on-click-modal
  6. @close="
  7. () => {
  8. showViewer = false;
  9. }
  10. "
  11. :initial-index="urlindex"
  12. v-if="showViewer"
  13. :url-list="initFileList"
  14. />
  15. </div>
  16. <div class="imgList flex justify-start flex-wrap">
  17. <div
  18. class="maskContainer previewBox my-2 mr-4"
  19. :style="{ width: width, height: height }"
  20. v-for="(item, index) in list"
  21. :key="index"
  22. >
  23. <div class="demo-image__preview h-full w-full">
  24. <el-image :src="urlFilter(item.filesUrl)" class="originalImg" fit="cover">
  25. <template #error>
  26. <div class="image-slot el-image__error">
  27. <el-icon :size="30"><VideoCameraFilled /></el-icon>
  28. </div>
  29. </template>
  30. </el-image>
  31. </div>
  32. <div class="mask">
  33. <div class="zoomInImg" v-if="TypeFilter(item.filesUrl) == '.mp4'" @click="showVideoView(item.filesUrl)">
  34. <el-icon color="#fff"><VideoPlay /></el-icon>
  35. </div>
  36. <div v-else class="zoomInImg" @click="showImgView(item.filesUrl)">
  37. <el-icon color="#fff"><zoom-in /></el-icon>
  38. </div>
  39. <div
  40. v-if="!edit"
  41. class="downloadImg"
  42. @click="handleItem('edit', item)"
  43. >
  44. <el-icon color="#fff"><Edit /></el-icon>
  45. </div>
  46. <div
  47. v-if="!deleteShow"
  48. class="downloadImg"
  49. @click="handleItem('delete', item)"
  50. >
  51. <el-icon color="red"><Delete /></el-icon>
  52. </div>
  53. <!-- <div v-if="!close" class="close" @click="handleItem('close', item)">
  54. <el-icon color="red"><CircleCloseFilled /></el-icon>
  55. </div> -->
  56. </div>
  57. </div>
  58. </div>
  59. <el-dialog v-model="visible.show" title="查看视频" width="500">
  60. <video ref="videoPlayer" style="width: 100%; height: 300px;" class="video-js">
  61. <source :src="visible.src" type="video/mp4">
  62. </video>
  63. </el-dialog>
  64. </div>
  65. </template>
  66. <script setup>
  67. import { ref, defineEmits, watchEffect, computed } from "vue";
  68. import { router } from "@/router";
  69. import { ElMessage, ElMessageBox } from "element-plus";
  70. import fileImg from "@/assets/svg/file.svg";
  71. import { delCaseFile, } from "@/store/caseFile";
  72. const caseId = computed(() => {
  73. const caseId = router.currentRoute.value.params.caseId;
  74. if (caseId) {
  75. return Number(caseId);
  76. }
  77. });
  78. const emits = defineEmits(['handleItem']);
  79. const props = defineProps({
  80. width: {
  81. type: String,
  82. default: "66px",
  83. required: false,
  84. },
  85. height: {
  86. type: String,
  87. default: "66px",
  88. required: false,
  89. },
  90. edit: {
  91. type: Boolean,
  92. default: false,
  93. required: false,
  94. },
  95. delete: {
  96. type: Boolean,
  97. default: false,
  98. required: false,
  99. },
  100. deleteShow: {
  101. type: Boolean,
  102. default: false,
  103. required: false,
  104. },
  105. close: {
  106. type: Boolean,
  107. default: false,
  108. required: false,
  109. },
  110. list: {
  111. type: Array,
  112. default() {
  113. return [];
  114. }
  115. }
  116. });
  117. const visible = ref({
  118. show: false,
  119. src: "",
  120. });
  121. const deleteVal = ref(props.deleteShow);
  122. const currSize = ref({ width: 0, height: 0 });
  123. const fileList = ref([".doc", ".docx", ".pdf", ".xls", ".xlsx"]);
  124. const initFileList = ref([
  125. "https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg",
  126. "https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg",
  127. "https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg",
  128. // "https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg",
  129. // "https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg",
  130. // "https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg",
  131. // "https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg",
  132. ]);
  133. const urlFilter = (url) => {
  134. if (!url) return "";
  135. const fileType = url.substring(url.lastIndexOf(".")).toLowerCase();
  136. console.log(url, fileType, "urlFilter");
  137. return fileList.value.includes(fileType) ? fileImg : url ;
  138. }
  139. const TypeFilter = (url) => {
  140. if (!url) return "";
  141. const fileType = url.substring(url.lastIndexOf(".")).toLowerCase();
  142. return fileType;
  143. }
  144. watchEffect(() => {
  145. if (props.list.length) {
  146. console.log(props.list, "watchEffect");
  147. let newlist = props.list.map(item => item.filesUrl || item.fileUrl);
  148. initFileList.value = newlist;
  149. }
  150. });
  151. const urlindex = ref("");
  152. const showViewer = ref(false);
  153. const previewList = ref([]);
  154. const showVideoView = (src) => {
  155. visible.value.show = true;
  156. visible.value.src = src;
  157. }
  158. const showImgView = (src) => {
  159. console.log(src, "showImgView", initFileList.value);
  160. const fileType = src.substring(src.lastIndexOf(".")).toLowerCase();
  161. urlindex.value = initFileList.value.findIndex((item) => item === src);
  162. console.log(fileType, fileList.value.includes(fileType), "urlFilter");
  163. if(fileList.value.includes(fileType)){
  164. window.open(window.location.origin + src);
  165. return;
  166. }
  167. url.value = src;
  168. showViewer.value = true;
  169. // previewList.value = [src];
  170. };
  171. const handleItem = (type, item) => {
  172. if(type == 'delete'){
  173. del(item)
  174. return
  175. }
  176. emits("handleItem", type, item);
  177. };
  178. const del = async (file) => {
  179. console.log(file, "file");
  180. ElMessageBox.confirm("确定删除?", "提示", {
  181. confirmButtonText: "确定",
  182. cancelButtonText: "取消",
  183. type: "warning",
  184. }).then(async () => {
  185. if(props.delete){
  186. }else{
  187. await delCaseFile({ caseId: caseId.value, filesId: file.filesId });
  188. }
  189. emits("handleItem", 'delete', file);
  190. ElMessage({
  191. type: "success",
  192. message: "删除成功",
  193. });
  194. });
  195. };
  196. </script>
  197. <style lang="scss" scoped>
  198. .maskContainer {
  199. position: relative;
  200. line-height: 0;
  201. width: 66px;
  202. height: 66px;
  203. padding: 7px;
  204. border: 1px solid #d9d9d9;
  205. &:hover {
  206. .mask {
  207. opacity: 1;
  208. }
  209. img {
  210. transform: scale(1.1);
  211. }
  212. }
  213. .mask {
  214. transition: all 0.5s;
  215. opacity: 0;
  216. position: absolute;
  217. top: 0;
  218. right: 0;
  219. bottom: 0;
  220. left: 0;
  221. background: rgba($color: #000000, $alpha: 0.3);
  222. display: flex;
  223. align-items: center;
  224. justify-content: center;
  225. div {
  226. margin: 3px;
  227. }
  228. .close {
  229. position: absolute;
  230. right: 0;
  231. top: 0;
  232. }
  233. .svgBox {
  234. height: 40px;
  235. width: 40px;
  236. background: rgb(#000, 0.3);
  237. border-radius: 50%;
  238. margin: 10px;
  239. padding: 10px;
  240. cursor: pointer;
  241. }
  242. svg {
  243. // color: #fff;
  244. width: 14px;
  245. height: 14px;
  246. }
  247. }
  248. .originalImg {
  249. height: 100%;
  250. width: 100%;
  251. }
  252. }
  253. </style>