modal-floder-view.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <template>
  2. <ui-group v-if="floders.length">
  3. <ui-group-option>
  4. <span @click="canAll && (showAll = !showAll)" :class="{ ['fun-ctrl']: canAll }">
  5. <template v-if="canAll">
  6. <UpOutlined v-if="showAll" />
  7. <DownOutlined v-else />
  8. </template>
  9. {{ root.title }}
  10. </span>
  11. </ui-group-option>
  12. <ui-group-option>
  13. <div class="items">
  14. <div
  15. class="img-item"
  16. v-for="(_, i) in showLen"
  17. :key="floders[i].filesId"
  18. :style="{ '--rawLen': samLen }"
  19. >
  20. <div class="img-item-content">
  21. <div>
  22. <Sign
  23. focus
  24. :media="{ url: floders[i].filesUrl }"
  25. @click="clickHandler(floders[i])"
  26. />
  27. </div>
  28. <!-- <img :src="floders[i].filesUrl" /> -->
  29. </div>
  30. </div>
  31. </div>
  32. </ui-group-option>
  33. </ui-group>
  34. <Tabs v-if="!emptyTabs" v-model:activeKey="activeTab" class="f-tabs">
  35. <template v-for="children in root.children">
  36. <TabPane
  37. :tab="children.title"
  38. :key="children.id"
  39. v-if="getFlatFloders(children).length"
  40. >
  41. <ModalFloderView :root="children" @preview="(v: any) => emit('preview', v)" />
  42. </TabPane>
  43. </template>
  44. </Tabs>
  45. <template v-for="c in children" :key="c.id" v-else>
  46. <ModalFloderView
  47. :root="c"
  48. v-if="isLastLevel(c)"
  49. @preview="(v: any) => emit('preview', v)"
  50. />
  51. </template>
  52. </template>
  53. <script lang="ts" setup>
  54. import { Floder, FloderRoot, getFlatFloders } from "@/store";
  55. import { computed, ref } from "vue";
  56. import { TabPane, Tabs } from "ant-design-vue";
  57. import { DownOutlined, UpOutlined } from "@ant-design/icons-vue";
  58. import Sign from "@/components/static-preview/sign.vue";
  59. const props = defineProps<{ root: FloderRoot }>();
  60. const emit = defineEmits<{ (e: "preview", v: [Floder, FloderRoot]): void }>();
  61. const isLastLevel = (root: FloderRoot) => {
  62. return !root.children?.length;
  63. };
  64. const emptyTabs = computed(
  65. () => props.root.children?.every((r) => isLastLevel(r)) && !props.root.flat
  66. );
  67. const oneTabs = computed(() => {
  68. if (!emptyTabs.value) return null;
  69. return props.root.children!.find((i) => !isLastLevel(i));
  70. });
  71. const clickHandler = (floder: Floder) => {
  72. emit("preview", [floder, props.root]);
  73. };
  74. const activeTab = ref(oneTabs.value?.id);
  75. const floders = computed(() => {
  76. if (props.root.flat) {
  77. return getFlatFloders(props.root);
  78. } else {
  79. return props.root.floders;
  80. }
  81. });
  82. const children = computed(() => {
  83. if (props.root.flat) {
  84. return [];
  85. } else {
  86. return props.root.children;
  87. }
  88. });
  89. const len = computed(() => floders.value.length);
  90. const showAll = ref(false);
  91. const samLen = 6;
  92. const showLen = computed(() => (showAll.value ? len.value : Math.min(samLen, len.value)));
  93. const canAll = computed(() => len.value > samLen);
  94. </script>
  95. <style lang="scss" scoped>
  96. .items {
  97. display: flex;
  98. flex-wrap: wrap;
  99. }
  100. .img-item {
  101. width: calc(100% / var(--rawLen));
  102. padding-right: 5px;
  103. .img-item-content {
  104. padding-top: 56.25%;
  105. position: relative;
  106. cursor: pointer;
  107. > div {
  108. position: absolute;
  109. width: 100%;
  110. height: 100%;
  111. left: 0;
  112. top: 0;
  113. object-fit: cover;
  114. }
  115. }
  116. }
  117. .mySwiper {
  118. --swiper-pagination-fraction-color: #000;
  119. --swiper-theme-color: #03ad98;
  120. --swiper-navigation-size: 30px;
  121. }
  122. </style>
  123. <style>
  124. .f-tabs.ant-tabs-top > .ant-tabs-nav {
  125. margin-bottom: 30px;
  126. }
  127. .f-tabs.ant-tabs-top > .ant-tabs-nav::before {
  128. display: none !important;
  129. }
  130. </style>