feat: 修改图片加载占位

pull/265/head
raofuzi 1 year ago
parent 3d1fc49fd8
commit c8bd5c81e0

@ -37,10 +37,11 @@
"sortablejs": "^1.15.1",
"vue": "^3.3.8",
"vue-draggable-plus": "^0.3.5",
"vue-lazyload": "^3.0.0",
"vue-mousetrap": "^1.0.5",
"vue-router": "^4.1.6",
"vue-types": "^4.2.1",
"vue-waterfall2": "^2.0.7",
"vue3-lazy": "1.0.0-alpha.1",
"xlsx": "^0.18.5"
},
"devDependencies": {

@ -71,9 +71,6 @@ dependencies:
vue-draggable-plus:
specifier: ^0.3.5
version: 0.3.5(@types/sortablejs@1.15.7)
vue-lazyload:
specifier: ^3.0.0
version: 3.0.0
vue-mousetrap:
specifier: ^1.0.5
version: 1.0.5
@ -83,6 +80,12 @@ dependencies:
vue-types:
specifier: ^4.2.1
version: 4.2.1(vue@3.3.10)
vue-waterfall2:
specifier: ^2.0.7
version: 2.0.7(vue@3.3.10)
vue3-lazy:
specifier: 1.0.0-alpha.1
version: 1.0.0-alpha.1(vue@3.3.10)
xlsx:
specifier: ^0.18.5
version: 0.18.5
@ -7323,10 +7326,6 @@ packages:
- supports-color
dev: true
/vue-lazyload@3.0.0:
resolution: {integrity: sha512-h2keL/Rj550dLgesgOtXJS9qOiSMmuJNeVlfNAYV1/IYwOQYaWk5mFJlwRxmZDK9YC5gECcFLYYj7z1lKSf9ug==}
dev: false
/vue-mousetrap@1.0.5:
resolution: {integrity: sha512-mDyPBBTnOrpUNDZ4vjd7X8emYwKFG2/Rsi5coZKDmF+dM5XpENrnvdmef4xHq2gcZ1HVmHqeI5jQP17p9fFpzA==}
dependencies:
@ -7374,6 +7373,24 @@ packages:
vue: 3.3.10(typescript@4.9.5)
dev: false
/vue-waterfall2@2.0.7(vue@3.3.10):
resolution: {integrity: sha512-TO7VWC0ZWPkdjKrghtYjvxJk6iGMDsnKx13W2vdk+P0lljpETyi6t5eLcNF7aEcY0P8sGlxUltV/oF497XX7NQ==}
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
peerDependencies:
vue: ^3.3.4
dependencies:
vue: 3.3.10(typescript@4.9.5)
dev: false
/vue3-lazy@1.0.0-alpha.1(vue@3.3.10):
resolution: {integrity: sha512-dpjpKK4DC5q+wZVtS/VY3X6pYBJHxRmYanr20s39RB6o6fvbneQ/DNuz37bipYfEdrEvbSZ95Y2SCexuznQNrQ==}
engines: {node: '>=6.0.0'}
peerDependencies:
vue: ^3.0.0-alpha.9
dependencies:
vue: 3.3.10(typescript@4.9.5)
dev: false
/vue@3.3.10(typescript@4.9.5):
resolution: {integrity: sha512-zg6SIXZdTBwiqCw/1p+m04VyHjLfwtjwz8N57sPaBhEex31ND0RYECVOC1YrRwMRmxFf5T1dabl6SGUbMKKuVw==}
peerDependencies:

@ -1,11 +1,12 @@
import './styles/tailwind.css'
import { createApp } from 'vue'
import waterfall from 'vue-waterfall2'
import lazyPlugin from 'vue3-lazy'
import App from './App.vue'
import router, { setupRouter } from './router'
import { setupGlobalProperties, setupMousestrap, setupNaive, setupNaiveDiscreteApi, setupSvgIcon } from '@/plugins'
import { setupStore } from '@/store'
import 'virtual:svg-icons-register'
import VueLazyload from 'vue-lazyload'
import bgPng from '@/assets/images/bg-loading.png'
import closePng from '@/assets/images/close.png'
@ -19,14 +20,13 @@ async function bootstrap() {
setupGlobalProperties(app)
setupRouter(app)
await router.isReady()
const meta = document.createElement('meta')
const meta = document.createElement('meta')
meta.name = 'naive-ui-style'
document.head.appendChild(meta)
app.use(VueLazyload, {
preLoad: 1.3,
app.use(waterfall)
app.use(lazyPlugin, {
error: closePng,
loading: bgPng,
attempt: 1
})
app.mount('#app', true)
}

@ -4,15 +4,18 @@ import { Download as DownloadIcon, Upload as UploadIcon } from '@vicons/tabler'
import { Icon } from '@vicons/utils'
import { useInfiniteScroll } from '@vueuse/core'
import dayjs from 'dayjs'
import imagesloaded from 'imagesloaded'
// import imagesloaded from 'imagesloaded'
import { cloneDeep, debounce } from 'lodash-es'
import Masonry from 'masonry-layout'
// import Masonry from 'masonry-layout'
import { NIcon, useMessage } from 'naive-ui'
import type { Component } from 'vue'
import {
computed,
h,
nextTick,
onBeforeMount,
onMounted,
onUnmounted,
onUpdated,
@ -54,9 +57,9 @@ const listData = ref<any[]>([])
const timer = ref()
const showClose = ref(false)
const deviceHeight = ref(600)
let _masonry: null | Masonry = null
let _imagesload: any
const masonryRef = ref<ComponentRef>(null)
// let _masonry: null | Masonry = null
// let _imagesload: any
// const masonryRef = ref<ComponentRef>(null)
const el = ref<HTMLDivElement | null>(null)
const viewMode = ref('masonry')
const pagination = reactive({
@ -101,36 +104,36 @@ const listStyle = computed(() => {
}
})
const layout = debounce(() => {
if (masonryRef.value == null || el.value == null)
return
if (_masonry !== null)
(_masonry as any).addItems()
_masonry = new Masonry(masonryRef.value as any, {
itemSelector: '.grid-item',
gutter: 17,
columnWidth: 182,
percentPosition: true,
stagger: 10,
})
loading.value = false
//
_imagesload = imagesloaded('.grid-item')
_imagesload.on('done', (instance) => {
(_masonry as any).layout()
if (!el.value)
return
loading.value = false
})
_imagesload.on('fail', (instance) => {
message.error('图片错误')
loading.value = false
})
}, 300)
// const layout = debounce(() => {
// if (masonryRef.value == null || el.value == null)
// return
// if (_masonry !== null)
// (_masonry as any).addItems()
// _masonry = new Masonry(masonryRef.value as any, {
// itemSelector: '.grid-item',
// gutter: 17,
// columnWidth: 182,
// percentPosition: true,
// stagger: 10,
// })
// loading.value = false
// //
// _imagesload = imagesloaded('.grid-item')
// _imagesload.on('done', (instance) => {
// (_masonry as any).layout()
// if (!el.value)
// return
// loading.value = false
// })
// _imagesload.on('fail', (instance) => {
// message.error('')
// loading.value = false
// })
// }, 300)
useInfiniteScroll(
el as any,
@ -140,12 +143,25 @@ useInfiniteScroll(
{ distance: 10, canLoadMore: () => canloadMore },
)
onUpdated(() => {
nextTick(() => {
setTimeout(() => {
layout()
}, 50)
onBeforeMount(async () => {
const more = await featchList()
more.forEach((item) => {
item.calHeight = 182 * item.high / item.wide
})
listData.value = more
const tmore = await featchList()
tmore.forEach((item) => {
item.calHeight = 182 * item.high / item.wide
})
listData.value = listData.value.concat(tmore)
})
onUpdated(() => {
// nextTick(() => {
// setTimeout(() => {
// layout()
// }, 50)
// })
})
const timeRange = ref('')
@ -254,42 +270,48 @@ async function featchList(userSearchId?: string) {
const list = data.map((item) => {
return {
calHeight: 0,
imgUrl: item.imgurl,
thumburl: item.serverThumbnailUrl || item.imgurl || bgLoadingImg,
thumburl: item.serverThumbnailUrl,
upname: item.upname,
ocrPictureclass: item.ocrPictureclass,
uphead: item.uphead,
similar: item.similarityscore || -1,
imgName: item.imgname,
states: item.states,
wide: item.wide,
high: item.high,
loadOver: false,
}
})
loading.value = false
return list
}
catch (error) {
canloadMore = false
loading.value = false
return []
}
}
async function loadMore() {
console.log('loading.value加兹安', loading.value, el.value)
if (loading.value || el.value == null)
return
canloadMore = false
const more = await featchList()
// if(isInitSeaerch.value) {
// listData.value = []
// isInitSeaerch.value = false
// }
listData.value.push(...more)
more.forEach((item) => {
item.calHeight = 182 * item.high / item.wide
})
// listData.value.push(...more)
listData.value = listData.value.concat(more)
console.log('listData.value出来了', listData.value)
}
const gridHeight = computed(() => {
let height = ''
if (viewMode.value === 'masonry')
height = ''
height = 'auto'
else if (viewMode.value === 'horizontalVersion')
height = '145px'
else if (viewMode.value === 'verticalVersion')
@ -477,9 +499,13 @@ function reset() {
canloadMore = true
filterId = null
layout()
// layout()
}
watch(listData.value, (newVal, oldVal) => {
console.log('最新的val', newVal)
})
async function refreshHandler(filtersearchId?: any) {
reset()
@ -639,9 +665,19 @@ const dropdownOptions = ref([
},
])
function finish() {
console.log('finish')
}
function scroll() {
}
const masonryRef = ref(null)
defineExpose({
showLoginSuccessModal,
closeLoginSuccessModal
closeLoginSuccessModal,
})
</script>
@ -711,124 +747,117 @@ defineExpose({
<span style="color: #507afd; font-weight: 500">{{ totalCount }}</span> </span>
</div>
<n-spin :show="loading">
<div ref="el" class="scroll" :style="listStyle">
<!-- <n-scrollbar :on-scroll="scrollHandler"> -->
<div ref="masonryRef" class="grid">
<div
v-for="(item, index) in listData"
:key="index"
:style="{ height: gridHeight, minHeight: gridMinHeight }"
class="grid-item"
<!-- <n-spin :show="loading"> -->
<div ref="el" class="scroll" :style="listStyle">
<waterfall :col="8" :data="listData" :gutter-width="10" @finish="finish">
<div
v-for="(item, index) in listData"
:key="item.calHeight"
:style="{ height: gridHeight }"
class="grid-item"
>
<img
:key="item.thumburl"
v-lazy="item.thumburl"
:class="{
'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
}"
:style="{ height: `${`${item.calHeight}px`}` }"
class="img"
alt="加载错误"
>
<!-- <div :style="{ 'background-color': randomColor(0.2) }" class="wrapper-content-item-img" /> -->
<!-- <img
class="wrapper-content-item-img" :class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }"
:src="item.imgUrl"
> -->
<n-image
ref="imageRef"
class="img"
:img-props="{
onClick: ($event) => {
hideDownload($event);
showClose = true;
},
}"
:class="{
'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
}"
:preview-src="item.imgUrl"
:src="item.thumburl"
:fallback-src="bgLoadingImg"
:style="{ backgroundImage: `url(${loading ? bgLoadingImg : 'none'})` }"
/>
<img
v-if="item.states == 3"
class="tag-status"
src="@/assets/images/task/tag-pass.png"
alt=""
>
<img
v-if="item.states == 5"
class="tag-status"
src="@/assets/images/task/tag-not-pass.png"
alt=""
>
<!-- @load="loadImgOver(item)" -->
<!-- <n-image
class="img"
:class="{
'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
}"
:src="baseImg"
v-show="!item.loadOver"
/> -->
<div v-if="item.similar != -1" class="percent">
<SvgIcon size="42" :name="item.similar == 100 ? 'error_tag' : 'tag'" />
<div class="val">
{{ `${item.similar}%` }}
</div>
</div>
<div v-if="isAllowDownload" class="glass">
<SvgIcon
size="16"
name="download"
style="margin-top: -6px; cursor: pointer"
@click="downloadImage(item)"
/>
<n-image
ref="imageRef"
:key="item.imgUrl"
class="img"
:img-props="{
onClick: ($event) => {
hideDownload($event);
showClose = true;
},
}"
:class="{
'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
}"
:preview-src="item.imgUrl"
:src="item.thumburl"
:fallback-src="bgLoadingImg"
:style="{ backgroundImage: `url(${loading ? bgLoadingImg : 'none'})` }"
style="display: none"
/>
<img
v-if="item.states == 3"
class="tag-status"
src="@/assets/images/task/tag-pass.png"
alt=""
>
<img
v-if="item.states == 5"
class="tag-status"
src="@/assets/images/task/tag-not-pass.png"
alt=""
>
<div v-if="item.similar != -1" class="percent">
<SvgIcon size="42" :name="item.similar == 100 ? 'error_tag' : 'tag'" />
<div class="val">
{{ `${item.similar}%` }}
</div>
</div>
<div v-if="isAllowDownload" class="glass">
<SvgIcon
size="16"
name="download"
style="margin-top: -6px; cursor: pointer"
@click="downloadImage(item)"
/>
</div>
<div class="info">
<div class="footer">
<div class="img-name">
<n-tooltip trigger="hover">
<template #trigger>
<span>{{ item.imgName }}</span>
</template>
<span
style="font-size: 12px; margin-top: 4px; margin-bottom: 16px"
>{{ item.imgName }}</span>
</n-tooltip>
</div>
<div
class="icon-wrap"
@click="
($event) => {
previewHandler(index, $event);
hideDownload($event);
}
"
>
<SvgIcon
size="13"
name="magnifying-2"
style="cursor: pointer; color: #898481"
/>
</div>
<div class="info">
<div class="footer">
<div class="img-name">
<n-tooltip trigger="hover">
<template #trigger>
<span>{{ item.imgName }}</span>
</template>
<span
style="font-size: 12px; margin-top: 4px; margin-bottom: 16px"
>{{ item.imgName }}</span>
</n-tooltip>
</div>
<div class="left">
<n-avatar
:src="(item.uphead && getAvatar(item.uphead)) || defaultAvatar"
class="avatar"
round
<div
class="icon-wrap"
@click="
($event) => {
previewHandler(index, $event);
hideDownload($event);
}
"
>
<SvgIcon
size="13"
name="magnifying-2"
style="cursor: pointer; color: #898481"
/>
<span>{{ item.upname }}</span>
</div>
<!-- <div class="right">
<span :style="{ marginRight: '5px' }">分类</span>
<span>{{ item.ocrPictureclass?.classname }}</span>
</div> -->
</div>
<div class="left">
<n-avatar
:src="(item.uphead && getAvatar(item.uphead)) || defaultAvatar"
class="avatar"
round
/>
<span>{{ item.upname }}</span>
</div>
</div>
</div>
<!-- </n-scrollbar> -->
</div>
</n-spin>
</waterfall>
</div>
<!-- </n-spin> -->
</div>
<PackageSettingsModal ref="packageModalRef" @commit="commitHandler" />
<GeneratePackageModal ref="generateModalRef" />
@ -898,19 +927,26 @@ defineExpose({
padding-bottom: 16px;
}
.grid{
display: block !important;
}
.img {
width: 182px;
max-width: 182px;
border-radius: 7px;
display: block;
height: calc(100% - 25px);
opacity: 1 !important;
// height: calc(100% - 25px);
}
.img-fit {
width: 100%;
width: 182px;
overflow: hidden;
}
.img-full {
width: 100%;
width: 182px;
overflow: hidden;
::v-deep(img) {

Loading…
Cancel
Save