FileTimeLine.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <template>
  2. <!-- 时间线模式 -->
  3. <div class="image-timeline-wrapper">
  4. <div class="radio">
  5. 排序:
  6. <a-radio-group v-model:value="reverse">
  7. <a-radio :value="true">倒序</a-radio>
  8. <a-radio :value="false">正序</a-radio>
  9. </a-radio-group>
  10. </div>
  11. <a-timeline class="image-timeline-list" :reverse="reverse" v-if="imageTimelineData.length">
  12. <a-timeline-item
  13. class="image-timeline-item"
  14. v-for="(item, index) in imageTimelineData"
  15. :key="index"
  16. :label="item.uploadDate"
  17. color="blue"
  18. position="top"
  19. >
  20. <ul class="image-list">
  21. <li
  22. class="image-item"
  23. v-for="(image, imageIndex) in item.imageList"
  24. :key="`${index}-${imageIndex}`"
  25. :style="`width: ${gridSize + 40}px; `"
  26. @click="$file.handleImgPreview(imageIndex, {}, item.imageList)"
  27. @contextmenu.prevent="handleContextMenu(item, imageIndex, $event)"
  28. >
  29. <img
  30. class="image"
  31. :src="$file.getMinImgStream(image)"
  32. :alt="$file.getFileNameComplete(image)"
  33. :style="`width: ${gridSize}px; height: ${gridSize}px;`"
  34. />
  35. <div class="image-name" v-html="$file.getFileNameComplete(image, true)"></div>
  36. </li>
  37. </ul>
  38. </a-timeline-item>
  39. </a-timeline>
  40. </div>
  41. </template>
  42. <script setup>
  43. import { ref, computed, inject } from 'vue'
  44. import { useMyResourceStore } from '@/store/myResource'
  45. const props = defineProps({
  46. // 文件列表
  47. fileList: {
  48. required: true,
  49. type: Array
  50. }
  51. })
  52. const emit = defineEmits(['getTableDataByType'])
  53. const myResourceStore = useMyResourceStore()
  54. const reverse = ref(true)
  55. const selectedFile = ref({})
  56. // 注入全局方法,如果这些方法是通过 provide 提供的
  57. const $file = inject('$file')
  58. const $openBox = inject('$openBox')
  59. // 按年-月-日分组排序
  60. const imageTimelineData = computed(() => {
  61. let res = []
  62. // 去重,获取返回的所有日期年-月-日
  63. let uploadTimeSet = new Set(props.fileList.map((item) => item.uploadTime.split(' ')[0]))
  64. let uploadDate = [...uploadTimeSet]
  65. uploadDate.sort((a, b) => {
  66. const dateA = new Date(a)
  67. const dateB = new Date(b)
  68. return dateB - dateA
  69. })
  70. // 分组
  71. uploadDate.forEach((element) => {
  72. res.push({
  73. uploadDate: element,
  74. imageList: props.fileList.filter((item) => item.uploadTime.split(' ')[0] === element) // 过滤
  75. })
  76. })
  77. return res
  78. })
  79. const gridSize = computed(() => myResourceStore.gridSize)
  80. const screenWidth = computed(() => myResourceStore.screenWidth)
  81. const isBatchOperation = computed(() => myResourceStore.isBatchOperation)
  82. /**
  83. * 文件鼠标右键事件
  84. * @param {object} item 文件信息
  85. * @param {number} index 文件索引
  86. * @param {object} event 鼠标事件信息
  87. */
  88. const handleContextMenu = (item, index, event) => {
  89. // 阻止右键事件冒泡
  90. event.cancelBubble = true
  91. // xs 以上的屏幕
  92. if (screenWidth.value > 768) {
  93. selectedFile.value = item
  94. if (!isBatchOperation.value) {
  95. event.preventDefault()
  96. $openBox
  97. .contextMenu({
  98. selectedFile: item,
  99. domEvent: event
  100. })
  101. .then((res) => {
  102. selectedFile.value = {}
  103. if (res === 'confirm') {
  104. emit('getTableDataByType') // 刷新文件列表
  105. myResourceStore.showStorage() // 刷新存储容量
  106. }
  107. })
  108. }
  109. }
  110. }
  111. </script>
  112. <style lang="less" scoped>
  113. @import '@/style/myResource/varibles.less';
  114. @import '@/style/myResource/mixins.less';
  115. .image-timeline-wrapper {
  116. margin-top: 20px;
  117. height: calc(100vh - 215px);
  118. overflow-y: auto;
  119. .setScrollbar(6px, transparent, #C0C4CC); // 假设 setScrollbar 混合宏已转换为 less
  120. .image-timeline-list {
  121. margin-top: 10px;
  122. .image-timeline-item {
  123. .image-list {
  124. display: flex;
  125. flex-wrap: wrap;
  126. list-style: none;
  127. .image-item {
  128. margin: 0 16px 16px 0;
  129. padding: 8px;
  130. text-align: center;
  131. cursor: pointer;
  132. &:hover {
  133. background: @tabBackColor;
  134. .file-name {
  135. font-weight: 550;
  136. }
  137. }
  138. .image-name {
  139. margin-top: 8px;
  140. height: 44px;
  141. line-height: 22px;
  142. font-size: 12px;
  143. word-break: break-all;
  144. .setEllipsis(2); // 假设 setEllipsis 混合宏已转换为 less
  145. :deep(.keyword) {
  146. // 使用 :deep() 或 ::v-deep 替代 >>>
  147. color: @Danger;
  148. }
  149. }
  150. }
  151. }
  152. }
  153. }
  154. }
  155. </style>