feat: 修改滚动加载等

pull/280/head
raoyongjun 1 year ago
parent fd44bfd380
commit 8a42ba736e

9
components.d.ts vendored

@ -11,6 +11,7 @@ declare module 'vue' {
BasicModal: typeof import('./src/components/Modal/BasicModal.vue')['default'] BasicModal: typeof import('./src/components/Modal/BasicModal.vue')['default']
DataHeader: typeof import('./src/components/DataHeader/index.vue')['default'] DataHeader: typeof import('./src/components/DataHeader/index.vue')['default']
NAvatar: typeof import('naive-ui')['NAvatar'] NAvatar: typeof import('naive-ui')['NAvatar']
NBackTop: typeof import('naive-ui')['NBackTop']
NButton: typeof import('naive-ui')['NButton'] NButton: typeof import('naive-ui')['NButton']
NCard: typeof import('naive-ui')['NCard'] NCard: typeof import('naive-ui')['NCard']
NCheckbox: typeof import('naive-ui')['NCheckbox'] NCheckbox: typeof import('naive-ui')['NCheckbox']
@ -21,8 +22,11 @@ declare module 'vue' {
NDialogProvider: typeof import('naive-ui')['NDialogProvider'] NDialogProvider: typeof import('naive-ui')['NDialogProvider']
NDivider: typeof import('naive-ui')['NDivider'] NDivider: typeof import('naive-ui')['NDivider']
NDropdown: typeof import('naive-ui')['NDropdown'] NDropdown: typeof import('naive-ui')['NDropdown']
NEllipsis: typeof import('naive-ui')['NEllipsis']
NEmpty: typeof import('naive-ui')['NEmpty']
NForm: typeof import('naive-ui')['NForm'] NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem'] NFormItem: typeof import('naive-ui')['NFormItem']
NGi: typeof import('naive-ui')['NGi']
NGrid: typeof import('naive-ui')['NGrid'] NGrid: typeof import('naive-ui')['NGrid']
NGridItem: typeof import('naive-ui')['NGridItem'] NGridItem: typeof import('naive-ui')['NGridItem']
NImage: typeof import('naive-ui')['NImage'] NImage: typeof import('naive-ui')['NImage']
@ -31,6 +35,7 @@ declare module 'vue' {
NModal: typeof import('naive-ui')['NModal'] NModal: typeof import('naive-ui')['NModal']
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider'] NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
NotPassed: typeof import('./src/components/NotPassed.vue')['default'] NotPassed: typeof import('./src/components/NotPassed.vue')['default']
NPopconfirm: typeof import('naive-ui')['NPopconfirm']
NPopover: typeof import('naive-ui')['NPopover'] NPopover: typeof import('naive-ui')['NPopover']
NPopselect: typeof import('naive-ui')['NPopselect'] NPopselect: typeof import('naive-ui')['NPopselect']
NProgress: typeof import('naive-ui')['NProgress'] NProgress: typeof import('naive-ui')['NProgress']
@ -40,7 +45,11 @@ declare module 'vue' {
NSpace: typeof import('naive-ui')['NSpace'] NSpace: typeof import('naive-ui')['NSpace']
NSpin: typeof import('naive-ui')['NSpin'] NSpin: typeof import('naive-ui')['NSpin']
NSwitch: typeof import('naive-ui')['NSwitch'] NSwitch: typeof import('naive-ui')['NSwitch']
NTabPane: typeof import('naive-ui')['NTabPane']
NTabs: typeof import('naive-ui')['NTabs']
NTag: typeof import('naive-ui')['NTag'] NTag: typeof import('naive-ui')['NTag']
NTimeline: typeof import('naive-ui')['NTimeline']
NTimelineItem: typeof import('naive-ui')['NTimelineItem']
NTooltip: typeof import('naive-ui')['NTooltip'] NTooltip: typeof import('naive-ui')['NTooltip']
NUpload: typeof import('naive-ui')['NUpload'] NUpload: typeof import('naive-ui')['NUpload']
NUploadDragger: typeof import('naive-ui')['NUploadDragger'] NUploadDragger: typeof import('naive-ui')['NUploadDragger']

@ -94,7 +94,7 @@ export async function getSimilarityList(params: any) {
const { data } = res const { data } = res
if (data) { if (data) {
const { records, pages, total } = data const { records, pages, total, current } = data
// 精简一下数据 // 精简一下数据
const list = records.map((item) => { const list = records.map((item) => {
return { return {
@ -114,6 +114,7 @@ export async function getSimilarityList(params: any) {
pageCount: pages, pageCount: pages,
data: records, data: records,
total, total,
current,
} }
} }
else { else {

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import Masonry from 'masonry-layout' import type Masonry from 'masonry-layout'
import { useDialog, useMessage } from 'naive-ui' import { useDialog, useMessage } from 'naive-ui'
import { computed, nextTick, onBeforeMount, onMounted, onUpdated, reactive, ref, unref, watch } from 'vue' import { computed, nextTick, onBeforeMount, onMounted, onUpdated, reactive, ref, unref, watch } from 'vue'
@ -35,6 +35,9 @@ let sortObj: any = {
orderByUptime: 'desc', orderByUptime: 'desc',
} }
const cols = ref(8)
const waterfallRef = ref(null)
const timeOptions = [{ const timeOptions = [{
label: '升序', label: '升序',
value: 'asc', value: 'asc',
@ -86,62 +89,66 @@ const pagination = reactive({
pageSize: 30, pageSize: 30,
}) })
let loading = false let loading = false
let _masonry: null | Masonry = null const _masonry: null | Masonry = null
const show = ref(false) const show = ref(false)
const selectedApproveItems = ref<any[]>([]) // const selectedApproveItems = ref<any[]>([]) //
const dialog = useDialog() const dialog = useDialog()
let processItems: any[] = [] let processItems: any[] = []
const confrimModalRef = ref<any>() const confrimModalRef = ref<any>()
const layout = debounce(() => { // const layout = debounce(() => {
if (!show.value) // if (!show.value)
return // return
if (_masonry !== null) // if (_masonry !== null)
(_masonry as any).destroy() // (_masonry as any).destroy()
_masonry = new Masonry(masonryRef.value as any, { // _masonry = new Masonry(masonryRef.value as any, {
itemSelector: '.grid-item', // itemSelector: '.grid-item',
columnWidth: 214, // columnWidth: 214,
percentPosition: true, // percentPosition: true,
stagger: 10, // stagger: 10,
}) // })
imagesloaded('.grid-item', () => {
(_masonry as any).layout()
const scrollHeight = el.value!.scrollHeight
const clientHeight = el.value!.clientHeight
const top = scrollHeight - clientHeight - 20
if (isTop.value)
el.value!.scrollTo({ top: 0, behavior: 'instant' })
else
el.value!.scrollTo({ top, behavior: 'instant' })
// let height = 800 - 15; // imagesloaded('.grid-item', () => {
// const screenWidth = window.screen.width; // (_masonry as any).layout()
// if(screenWidth <= 1920) { // const scrollHeight = el.value!.scrollHeight
// height = 600 - 15; // const clientHeight = el.value!.clientHeight
// const top = scrollHeight - clientHeight - 20
// if (isTop.value)
// el.value!.scrollTo({ top: 0, behavior: 'instant' })
// else
// el.value!.scrollTo({ top, behavior: 'instant' })
// // let height = 800 - 15;
// // const screenWidth = window.screen.width;
// // if(screenWidth <= 1920) {
// // height = 600 - 15;
// // }
// // el.value!.scrollTo({ top: height, behavior: 'instant' })
// loading = false
// console.log('loading---------------', loading)
// console.log('pagination.pageNo---------------', pagination.pageNo)
// if (pagination.pageNo == 3) {
// let timer
// if (timer)
// clearTimeout(timer)
// timer = setTimeout(() => {
// isTop.value = false
// console.log('isTop.value---------------', isTop.value)
// }, 1000)
// } // }
// el.value!.scrollTo({ top: height, behavior: 'instant' }) // })
loading = false // }, 300)
console.log('loading---------------', loading)
console.log('pagination.pageNo---------------', pagination.pageNo)
if (pagination.pageNo == 3) {
let timer
if (timer)
clearTimeout(timer)
timer = setTimeout(() => {
isTop.value = false
console.log('isTop.value---------------', isTop.value)
}, 1000)
}
})
}, 300)
watch(viewMode, () => { watch(viewMode, (newVal, oldVal) => {
if (newVal) {
isTop.value = true isTop.value = true
layout() reset()
loadMore()
}
// layout()
}) })
onBeforeMount(async () => { onBeforeMount(async () => {
@ -153,7 +160,7 @@ let canloadMore = true
useInfiniteScroll( useInfiniteScroll(
el as any, el as any,
() => { () => {
loading = false // loading = false
console.log('加载了000000000000000---------------------------') console.log('加载了000000000000000---------------------------')
loadMore() loadMore()
}, },
@ -164,15 +171,17 @@ async function featchList() {
loading = true loading = true
try { try {
// const result = await dubiousfilelist({ ...pagination, orderbyname: timeRange.value }) // const result = await dubiousfilelist({ ...pagination, orderbyname: timeRange.value })
pagination.pageNo += 1
console.log('pagination.pageNo------------', pagination.pageNo) console.log('pagination.pageNo------------', pagination.pageNo)
const result = await dubiousfilelist({ ...pagination, ...sortObj }) const result = await dubiousfilelist({ ...pagination, ...sortObj })
// TODO // TODO
// result.data = Array.from({ length: 30 }) // result.data = Array.from({ length: 30 })
const { data, pageCount } = result const { data, pageCount, current } = result
pagination.pageNo = data.current
// canloadMore = pageCount >= pagination.pageNo && pageCount > 0; // canloadMore = pageCount >= pagination.pageNo && pageCount > 0;
canloadMore = data.pages >= pagination.pageNo && data.pages > 0 canloadMore = data.pages >= pagination.pageNo && data.pages > 0
console.log('canloadMore------------', canloadMore) console.log('canloadMore------------', canloadMore)
loading = false
return result.data.records return result.data.records
// const list = data.map((item) => { // const list = data.map((item) => {
// return { // return {
@ -182,22 +191,36 @@ async function featchList() {
// return list // return list
} }
catch (error) { catch (error) {
loading = false
canloadMore = false canloadMore = false
return [] return []
} }
} }
async function loadMore() { async function loadMore() {
console.log('执行l------------------------', loading, el.value, pagination.pageNo)
if (loading || el.value == null) if (loading || el.value == null)
return return
// loading = true // loading = true
pagination.pageNo = pagination.pageNo + 1 canloadMore = false
// pagination.pageNo = pagination.pageNo + 1
const more = await featchList() const more = await featchList()
console.log('more------------------------', more) more.forEach((item) => {
listData.value.push(...more) item.calHeight = 182 * item.high / item.wide
layout() })
if (pagination.pageNo <= 2) {
listData.value = []
listData.value = listData.value.concat(more)
console.log('listData.value出来了11111111111111', listData.value)
if (pagination.pageNo == 1)
waterfallRef.value?.resize()
}
else {
listData.value = listData.value.concat(more)
console.log('listData.value出来了2222222222', listData.value)
waterfallRef.value?.mix()
}
// layout()
} }
onUpdated(() => { onUpdated(() => {
@ -211,7 +234,7 @@ onUpdated(() => {
} }
nextTick(() => { nextTick(() => {
setTimeout(() => { setTimeout(() => {
layout() // layout()
}, 50) }, 50)
}) })
}) })
@ -276,6 +299,7 @@ function imUpdateSelectIds(x: number, y: number, w: number, h: number) {
} }
function isSelected(pictureId: number) { function isSelected(pictureId: number) {
console.log('selectIds.value多少只啊啊啊啊啊啊啊啊啊啊啊啊啊', selectIds.value, pictureId)
return selectIds.value.includes(String(pictureId)) return selectIds.value.includes(String(pictureId))
} }
@ -394,11 +418,13 @@ onMounted(async () => {
async function showModal() { async function showModal() {
show.value = true show.value = true
// reset()
// pagination.pageNo = 1
// const list = await featchList()
// listData.value = list
reset() reset()
pagination.pageNo = 1 loadMore()
const list = await featchList() // layout()
listData.value = list
layout()
} }
async function onChange() { async function onChange() {
@ -411,12 +437,14 @@ async function onChange() {
// orderbyname: val, // orderbyname: val,
orderByUptime: timeRange.value, orderByUptime: timeRange.value,
} }
pagination.pageNo = 1 // pagination.pageNo = 1
canloadMore = true // canloadMore = true
const list = await featchList() // const list = await featchList()
listData.value = list // listData.value = list
isTop.value = true isTop.value = true
layout() reset()
loadMore()
// layout()
} }
async function onChangeView() { async function onChangeView() {
@ -429,12 +457,14 @@ async function onChangeView() {
// orderbyname: val, // orderbyname: val,
orderBySimilarity: similarRange.value, orderBySimilarity: similarRange.value,
} }
pagination.pageNo = 1 // pagination.pageNo = 1
canloadMore = true // canloadMore = true
const list = await featchList() // const list = await featchList()
listData.value = list // listData.value = list
isTop.value = true isTop.value = true
layout() reset()
loadMore()
// layout()
} }
function closeModal(event: MouseEvent) { function closeModal(event: MouseEvent) {
@ -446,10 +476,12 @@ async function commit() {
const res = await removeFiles({ pictureid: ids }) const res = await removeFiles({ pictureid: ids })
if (res.code === 'OK') { if (res.code === 'OK') {
message.success('移除成功') message.success('移除成功')
pagination.pageNo = 1 // pagination.pageNo = 1
const list = await featchList() // const list = await featchList()
listData.value = list // listData.value = list
layout() reset()
loadMore()
// layout()
setBatch(false) setBatch(false)
} }
} }
@ -520,7 +552,7 @@ function reset() {
selectedApproveItems.value.length = 0 selectedApproveItems.value.length = 0
loading = false loading = false
canloadMore = true canloadMore = true
layout() // layout()
} }
function validate(items: any[]) { function validate(items: any[]) {
if (items.length === 0) if (items.length === 0)
@ -590,11 +622,13 @@ function reloadList() {
} }
async function refreshHandler(filtersearchId?: any) { async function refreshHandler(filtersearchId?: any) {
// rao start // rao start
// reset()
// pagination.pageNo = 1
// const list = await featchList()
// listData.value = list
reset() reset()
pagination.pageNo = 1 loadMore()
const list = await featchList() // layout()
listData.value = list
layout()
// rao end // rao end
// reset(); // reset();
@ -602,25 +636,52 @@ async function refreshHandler(filtersearchId?: any) {
// filterId = filtersearchId; // filterId = filtersearchId;
// } // }
nextTick(() => { // nextTick(() => {
setTimeout(() => { // setTimeout(() => {
useInfiniteScroll( // useInfiniteScroll(
el as any, // el as any,
() => { // () => {
loadMore() // loadMore()
}, // },
{ distance: 10, canLoadMore: () => canloadMore }, // { distance: 10, canLoadMore: () => canloadMore },
) // )
}, 300) // }, 300)
// })
}
function finish() {
console.log('finish')
}
onBeforeMount(async () => {
const screenWidth = window.screen.width
if (screenWidth > 1920 && screenWidth <= 2560)
cols.value = 12
else if (screenWidth <= 1920 && screenWidth >= 1792)
cols.value = 8
else if (screenWidth < 1792 && screenWidth > 1440)
cols.value = 7
else if (screenWidth <= 1440)
cols.value = 6
}) })
function previewHandler(index: number, event: MouseEvent, thumburl, imgUrl) {
event.stopImmediatePropagation()
event.stopPropagation()
if (imageRef.value?.[index] && (imageRef.value[index] as any).src)
// (imageRef.value?.[index] as any).mergedOnClick()
// previewImageUrl(thumburl, imgUrl);
(imageRef.value?.[index] as any).click()
} }
watch(() => show.value, async (newVal) => { watch(() => show.value, async (newVal) => {
if (show.value) { if (show.value) {
pagination.pageNo = 1 // pagination.pageNo = 1
const list = await featchList() // const list = await featchList()
listData.value = list // listData.value = list
layout() // layout()
reset()
loadMore()
} }
}) })
</script> </script>
@ -667,18 +728,6 @@ watch(() => show.value, async (newVal) => {
<span>相似度排序</span> <span>相似度排序</span>
<SvgIcon style="margin-left: 8px" name="sort" size="12" /> <SvgIcon style="margin-left: 8px" name="sort" size="12" />
</div> </div>
<!-- <n-popselect v-model:value="timeRange" :options="timeOptions" trigger="click" @change="onChange">
<div class="wrapper-content-form-dropdown">
<span>时间排序</span>
<SvgIcon class="wrapper-content-form-dropdown-gap" name="arrow-botton" size="14" />
</div>
</n-popselect>
<n-popselect v-model:value="similarRange" :options="timeOptions" trigger="click" @change="onChangeView">
<div class="wrapper-content-form-dropdown">
<span>相似度排序</span>
<SvgIcon class="wrapper-content-form-dropdown-gap" name="arrow-botton" size="14" />
</div>
</n-popselect> -->
</div> </div>
<div> <div>
<div class="remove" @click="remove"> <div class="remove" @click="remove">
@ -709,12 +758,27 @@ watch(() => show.value, async (newVal) => {
</div> </div>
<div ref="el" class="scroll" :style="{ height: maxHeight, marginTop: '16px' }"> <div ref="el" class="scroll" :style="{ height: maxHeight, marginTop: '16px' }">
<!-- <n-scrollbar :on-scroll="scrollHandler"> --> <div v-if="viewMode != 'masonry'" class="grid" :style="{ 'grid-template-columns': `repeat(${cols}, 182px)` }">
<div ref="masonryRef" class="grid">
<div <div
v-for="(item) in listData" :key="item.pictureId" :data-id="item.pictureId" v-for="(item, index) in listData" :key="item.pictureId" :data-id="item.pictureId"
:class="{ 'grid-item-selected': isSelected(item.pictureId) }" :style="{ height: gridHeight }" :class="{ 'grid-item-selected': isSelected(item.pictureId) }" :style="{ height: gridHeight }"
class="grid-item" class="grid-item"
>
<img
:key="item.pictureId"
v-lazy="item.imgUrl"
:class="{
'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
}"
:style="{ height: `${item.calHeight}px` }"
class="img"
alt="加载错误"
@click="
($event) => {
previewHandler(index, $event, item.serverThumbnailUrl, item.imgUrl);
}
"
> >
<n-image <n-image
ref="imageRef" ref="imageRef"
@ -725,7 +789,7 @@ watch(() => show.value, async (newVal) => {
:class="{ :class="{
'img-fit': viewMode === 'horizontalVersion', 'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion' }" 'img-full': viewMode === '3:4' || viewMode === 'verticalVersion' }"
:style="{ backgroundImage: `url(${loading ? bgLoadingImg : 'none'})` }" :style="{ backgroundImage: `url(${loading ? bgLoadingImg : 'none'})`, display: 'none' }"
/> />
<n-checkbox <n-checkbox
v-if="batch && item.historyStates === 1" v-model:checked="item.checked" v-if="batch && item.historyStates === 1" v-model:checked="item.checked"
@ -742,16 +806,6 @@ watch(() => show.value, async (newVal) => {
{{ item.similarityScore }}<span class="percent-unit">%</span> {{ item.similarityScore }}<span class="percent-unit">%</span>
</div> </div>
<div class="time"> <div class="time">
<!-- <div class="time-item">
<SvgIcon class="svg-time" color="#FFF" size="16" name="camera-time" />
<span>{{ item?.photoDateTimestamp ?
formatToDateHMS(Number(item.photoDateTimestamp)) : '-' }}</span>
</div>
<div class="time-item time-item2">
<SvgIcon class="svg-time" color="#FFF" size="16" name="submit-time" />
<span>{{ item.submitDateTimestamp ?
formatToDateHMS(Number(item.submitDateTimestamp)) : '-' }}</span>
</div> -->
<div class="time-item" style="margin-bottom: 4px;"> <div class="time-item" style="margin-bottom: 4px;">
<SvgIcon color="#FFF" size="16" name="camera" style="margin-right: 4px;" /> <SvgIcon color="#FFF" size="16" name="camera" style="margin-right: 4px;" />
<span class="time-value">{{ item?.photoDateTimestamp <span class="time-value">{{ item?.photoDateTimestamp
@ -765,7 +819,67 @@ watch(() => show.value, async (newVal) => {
</div> </div>
</div> </div>
</div> </div>
<!-- </n-scrollbar> --> <waterfall v-if="viewMode === 'masonry'" ref="waterfallRef" :col="cols" :data="listData" :gutter-width="10" @finish="finish">
<div
v-for="(item, index) in listData" :key="item.pictureId" :data-id="item.pictureId"
:class="{ 'grid-item-selected': isSelected(item.pictureId) }" :style="{ height: gridHeight }"
class="grid-item"
>
<img
:key="item.pictureId"
v-lazy="item.imgUrl"
:class="{
'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
}"
:style="{ height: `${item.calHeight}px` }"
class="img"
alt="加载错误"
@click="
($event) => {
previewHandler(index, $event, item.serverThumbnailUrl, item.imgUrl);
}
"
>
<n-image
ref="imageRef"
:src="item?.serverThumbnailUrl ? item.serverThumbnailUrl : item.imgUrl"
:preview-src="item.imgUrl"
:fallback-src="bgLoadingImg"
class="img "
:class="{
'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion' }"
:style="{ backgroundImage: `url(${loading ? bgLoadingImg : 'none'})`, display: 'none' }"
/>
<n-checkbox
v-if="batch && item.historyStates === 1" v-model:checked="item.checked"
style="position:absolute;left:20px;top:20px" @click.prevent.stop
@update:checked="onCheckChange($event, item)"
/>
<img v-if="item.historyStates === 2" class="tag-status" src="@/assets/images/task/tag-pass.png" alt="">
<img
v-if="item.historyStates === 3" class="tag-status" src="@/assets/images/task/tag-not-pass.png"
alt=""
>
<div :class="{ 'percent-red': item.similarityScore === 100 }" class="percent">
{{ item.similarityScore }}<span class="percent-unit">%</span>
</div>
<div class="time">
<div class="time-item" style="margin-bottom: 4px;">
<SvgIcon color="#FFF" size="16" name="camera" style="margin-right: 4px;" />
<span class="time-value">{{ item?.photoDateTimestamp
? formatToDateHMS(Number(item.photoDateTimestamp)) : '- -' }} </span>
</div>
<div class="time-item">
<SvgIcon class="svg-time" color="#FFF" size="16" name="time" />
<span>{{ item.submitDateTimestamp
? formatToDateHMS(Number(item.submitDateTimestamp)) : '- -' }}</span>
</div>
</div>
</div>
</waterfall>
</div> </div>
</div> </div>
@ -826,9 +940,19 @@ watch(() => show.value, async (newVal) => {
} }
} }
::v-deep(.vue-waterfall) {
overflow-x: hidden;
.vue-waterfall-column {
max-width: 190px;
}
}
.img { .img {
width: 182px;
max-width: 182px;
border-radius: 7px; border-radius: 7px;
display: block; display: block;
opacity: 1 !important;
height: 100%; height: 100%;
} }
@ -846,7 +970,9 @@ watch(() => show.value, async (newVal) => {
&-m32 { &-m32 {
margin-left: 32px; margin-left: 32px;
} }
.grid-item-selected {
background-color: #dae3ff;
}
&-content { &-content {
&-form { &-form {
display: flex; display: flex;
@ -884,21 +1010,30 @@ watch(() => show.value, async (newVal) => {
&-item { &-item {
&-img { &-img {
width: 182px;
border-radius: 7px; border-radius: 7px;
display: block; display: block;
height: 100%; height: 100%;
} }
&-img-fit { &-img-fit {
width: 100%; width: 182px;
object-fit: cover; object-fit: cover;
} }
} }
.grid{
grid-gap: 0px 20px;
}
.grid-item { .grid-item {
width: 214px; box-sizing: content-box;
padding: 16px; width: 182px;
padding: 6px;
transition: 0.5s;
margin-bottom: 20px;
position: relative; position: relative;
// background-color: #fff;
.tag-status { .tag-status {
width: 46px; width: 46px;
@ -909,9 +1044,6 @@ watch(() => show.value, async (newVal) => {
} }
} }
.grid-item-selected {
background-color: #dae3ff;
}
.percent { .percent {
position: absolute; position: absolute;
@ -925,7 +1057,7 @@ watch(() => show.value, async (newVal) => {
border-radius: 6px 0px 6px 0px; border-radius: 6px 0px 6px 0px;
z-index: 5; z-index: 5;
right: 28px; right: 28px;
top: 20px; top: 0px;
color: #fff; color: #fff;
font-size: 14px; font-size: 14px;
@ -941,10 +1073,10 @@ watch(() => show.value, async (newVal) => {
.time { .time {
position: absolute; position: absolute;
width: 182px; width: 182px;
padding-left: 10px; // padding-left: 10px;
z-index: 3; z-index: 3;
left: 16px; left: 6px;
bottom: 16px; bottom: 0px;
background: linear-gradient(180deg,rgba(6,0,0,0.01),rgba(0, 0, 0, 0.44) 100%); background: linear-gradient(180deg,rgba(6,0,0,0.01),rgba(0, 0, 0, 0.44) 100%);
border-radius: 0 0 7px 7px; border-radius: 0 0 7px 7px;
.time-item { .time-item {

@ -13,6 +13,7 @@ export interface ConfigState {
isAllowDownload: boolean isAllowDownload: boolean
timeNum: number timeNum: number
filterConfig: string[] // 过滤筛选条件 filterConfig: string[] // 过滤筛选条件
collapse: boolean // 是否展示左侧筛选条件
} }
export const useAsideConfigStore = defineStore({ export const useAsideConfigStore = defineStore({
@ -21,12 +22,16 @@ export const useAsideConfigStore = defineStore({
systemConfig: null, systemConfig: null,
customConfig: null, customConfig: null,
asideValue: null, asideValue: null,
searchValue: "", searchValue: '',
isAllowDownload: true, isAllowDownload: true,
timeNum: 0, timeNum: 0,
filterConfig: [], filterConfig: [],
collapse: false,
}), }),
getters: { getters: {
getCollapse(): boolean {
return this.collapse
},
getConfig(): AsideConfig | null { getConfig(): AsideConfig | null {
return this.systemConfig return this.systemConfig
}, },
@ -50,6 +55,10 @@ export const useAsideConfigStore = defineStore({
}, },
}, },
actions: { actions: {
setCollapse(value) {
this.collapse = value
console.log('存起来啊啊 ', this.collapse)
},
setConfig(config: AsideConfig) { setConfig(config: AsideConfig) {
this.systemConfig = config this.systemConfig = config
}, },

@ -70,6 +70,8 @@ mousetrap.bind('[', collapseHandler)
function collapseHandler() { function collapseHandler() {
collapse.value = !collapse.value collapse.value = !collapse.value
console.log('执行了啊啊啊啊啊啊啊啊啊啊啊啊', collapse.value)
configStore.setCollapse(collapse.value)
} }
const asideWidth = computed(() => { const asideWidth = computed(() => {

@ -6,7 +6,7 @@ import { useInfiniteScroll } from '@vueuse/core'
import dayjs from 'dayjs' import dayjs from 'dayjs'
// import imagesloaded from 'imagesloaded' // import imagesloaded from 'imagesloaded'
import { cloneDeep, debounce, isEqual } from 'lodash-es' import { cloneDeep } from 'lodash-es'
// import Masonry from 'masonry-layout' // import Masonry from 'masonry-layout'
import { NIcon, useMessage } from 'naive-ui' import { NIcon, useMessage } from 'naive-ui'
@ -147,16 +147,6 @@ useInfiniteScroll(
) )
onBeforeMount(async () => { 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)
const screenWidth = window.screen.width const screenWidth = window.screen.width
if (screenWidth > 1920 && screenWidth <= 2560) if (screenWidth > 1920 && screenWidth <= 2560)
cols.value = 11 cols.value = 11
@ -189,7 +179,8 @@ const isAllowDownload = ref(true)
const calNum = ref(0) const calNum = ref(0)
const searchValue = ref('') const searchValue = ref('')
const isInitSeaerch = ref(false) // const isInitSeaerch = ref(false) //
const collapse = ref(1)
nextTick(() => {
configStore.$subscribe(() => { configStore.$subscribe(() => {
console.log('subscribe', 'configStore') console.log('subscribe', 'configStore')
isAllowDownload.value = configStore.isAllowDownload isAllowDownload.value = configStore.isAllowDownload
@ -197,6 +188,35 @@ configStore.$subscribe(() => {
// console.log("calNum.value----------", calNum.value); // console.log("calNum.value----------", calNum.value);
searchValue.value = configStore.getSearchValue searchValue.value = configStore.getSearchValue
console.log(configStore.getSearchValue, 'getSearchValue') console.log(configStore.getSearchValue, 'getSearchValue')
collapse.value = configStore.getCollapse ? 1 : 0
console.log('collapse.value的这个肚饿的点点滴滴的点点滴滴', collapse.value)
})
})
watch(() => collapse.value, (newVal, oldVal) => {
// let val = newVal ? 1 : 0;
if (newVal == 1) {
const screenWidth = window.screen.width
if (screenWidth > 1920 && screenWidth <= 2560)
cols.value = 12
else if (screenWidth <= 1920 && screenWidth >= 1792)
cols.value = 8
else if (screenWidth < 1792 && screenWidth > 1440)
cols.value = 7
else if (screenWidth <= 1440)
cols.value = 6
}
else if (newVal == 0) {
const screenWidth = window.screen.width
if (screenWidth > 1920 && screenWidth <= 2560)
cols.value = 11
else if (screenWidth <= 1920 && screenWidth >= 1792)
cols.value = 7
else if (screenWidth < 1792 && screenWidth > 1440)
cols.value = 6
else if (screenWidth <= 1440)
cols.value = 5
}
}) })
watch( watch(
@ -224,7 +244,6 @@ watch(
watch( watch(
() => configStore.getAsideValue, () => configStore.getAsideValue,
async (newVal, oldVal) => { async (newVal, oldVal) => {
console.log('getAsideValue变化了', newVal, oldVal, isEqual(newVal, oldVal))
if (pagination.pageNo > 1 && newVal && !(Object.entries(newVal).toString() === Object.entries(oldVal).toString())) { if (pagination.pageNo > 1 && newVal && !(Object.entries(newVal).toString() === Object.entries(oldVal).toString())) {
reset() reset()
loadMore() loadMore()
@ -330,11 +349,6 @@ async function loadMore() {
waterfallRef.value?.resize() waterfallRef.value?.resize()
} }
else { else {
// setTimeout(() => {
// const height = el.value?.scrollHeight - 1000
// console.log('listData.valueheight', height)
// el.value?.scrollTo({ top: height, behavior: 'smooth' })
// }, 50)
listData.value = listData.value.concat(more) listData.value = listData.value.concat(more)
console.log('listData.value出来了', listData.value) console.log('listData.value出来了', listData.value)
waterfallRef.value?.mix() waterfallRef.value?.mix()
@ -610,11 +624,12 @@ async function downloadImage(item) {
} }
} }
function previewHandler(index: number, event: MouseEvent) { function previewHandler(index: number, event: MouseEvent, thumburl, imgUrl) {
event.stopImmediatePropagation() event.stopImmediatePropagation()
event.stopPropagation() event.stopPropagation()
if (imageRef.value?.[index] && (imageRef.value[index] as any).src) if (imageRef.value?.[index] && (imageRef.value[index] as any).src)
// (imageRef.value?.[index] as any).mergedOnClick() // (imageRef.value?.[index] as any).mergedOnClick()
previewImageUrl(thumburl, imgUrl);
(imageRef.value?.[index] as any).click() (imageRef.value?.[index] as any).click()
} }
@ -704,11 +719,29 @@ function finish() {
console.log('finish') console.log('finish')
} }
function scroll() { const masonryRef = ref(null)
function loadImg(src) {
const promise = new Promise((resolve, reject) => {
const img = document.createElement('img')
img.src = src
img.onload = function () {
resolve(src)
}
img.onerror = function () {
reject(new Error('加载失败'))
}
})
return promise
} }
const masonryRef = ref(null) function previewImageUrl(img1, img2) {
setTimeout(async () => {
const img = document.getElementsByClassName('n-image-preview').item(0)
await loadImg(img2)
img.src = img2
}, 50)
}
defineExpose({ defineExpose({
showLoginSuccessModal, showLoginSuccessModal,
@ -750,15 +783,8 @@ defineExpose({
<div class="wrapper-content"> <div class="wrapper-content">
<div style="display: flex; justify-content: space-between"> <div style="display: flex; justify-content: space-between">
<div class="form"> <div class="form">
<!-- <n-popselect v-model:value="timeRange" :options="timeOptions" trigger="click">
<div class="dropdown">
<span>{{ timeLabel || '请选择' }}</span>
<SvgIcon class="gap" name="arrow-botton" size="14" />
</div>
</n-popselect> -->
<n-popselect v-model:value="viewMode" :options="viewOptions" trigger="click"> <n-popselect v-model:value="viewMode" :options="viewOptions" trigger="click">
<div class="dropdown"> <div class="dropdown">
<!-- <span>{{ viewLabel || '请选择' }}</span> -->
<span>视图</span> <span>视图</span>
<SvgIcon class="gap" name="arrow-botton" size="16" /> <SvgIcon class="gap" name="arrow-botton" size="16" />
</div> </div>
@ -782,7 +808,7 @@ defineExpose({
<span style="color: #507afd; font-weight: 500">{{ totalCount }}</span> </span> <span style="color: #507afd; font-weight: 500">{{ totalCount }}</span> </span>
</div> </div>
<!-- <n-spin :show="loading"> --> <n-spin :show="loading">
<div v-if="viewMode != 'masonry'" ref="el" class="scroll" :style="listStyle"> <div v-if="viewMode != 'masonry'" ref="el" class="scroll" :style="listStyle">
<div class="grid" :style="{ 'grid-template-columns': `repeat(${cols}, 182px)` }"> <div class="grid" :style="{ 'grid-template-columns': `repeat(${cols}, 182px)` }">
<div <div
@ -817,7 +843,7 @@ defineExpose({
'img-fit': viewMode === 'horizontalVersion', 'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion', 'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
}" }"
:preview-src="item.imgUrl" :preview-src="item.thumburl"
:src="item.thumburl" :src="item.thumburl"
:fallback-src="bgLoadingImg" :fallback-src="bgLoadingImg"
:style="{ backgroundImage: `url(${loading ? bgLoadingImg : 'none'})` }" :style="{ backgroundImage: `url(${loading ? bgLoadingImg : 'none'})` }"
@ -868,7 +894,7 @@ defineExpose({
class="icon-wrap" class="icon-wrap"
@click=" @click="
($event) => { ($event) => {
previewHandler(index, $event); previewHandler(index, $event, item.thumburl, item.imgUrl);
hideDownload($event); hideDownload($event);
} }
" "
@ -925,7 +951,7 @@ defineExpose({
'img-fit': viewMode === 'horizontalVersion', 'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion', 'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
}" }"
:preview-src="item.imgUrl" :preview-src="item.thumburl"
:src="item.thumburl" :src="item.thumburl"
:fallback-src="bgLoadingImg" :fallback-src="bgLoadingImg"
:style="{ backgroundImage: `url(${loading ? bgLoadingImg : 'none'})` }" :style="{ backgroundImage: `url(${loading ? bgLoadingImg : 'none'})` }"
@ -976,7 +1002,7 @@ defineExpose({
class="icon-wrap" class="icon-wrap"
@click=" @click="
($event) => { ($event) => {
previewHandler(index, $event); previewHandler(index, $event, item.thumburl, item.imgUrl);
hideDownload($event); hideDownload($event);
} }
" "
@ -1000,7 +1026,7 @@ defineExpose({
</div> </div>
</waterfall> </waterfall>
</div> </div>
<!-- </n-spin> --> </n-spin>
</div> </div>
<PackageSettingsModal ref="packageModalRef" @commit="commitHandler" /> <PackageSettingsModal ref="packageModalRef" @commit="commitHandler" />
<GeneratePackageModal ref="generateModalRef" /> <GeneratePackageModal ref="generateModalRef" />

@ -1,10 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, nextTick, onMounted, onUnmounted, onUpdated, reactive, ref, watch } from 'vue' import { computed, nextTick, onBeforeMount, onMounted, onUnmounted, onUpdated, reactive, ref, watch } from 'vue'
import Masonry from 'masonry-layout' import type Masonry from 'masonry-layout'
import { useInfiniteScroll } from '@vueuse/core' import { useInfiniteScroll } from '@vueuse/core'
import { debounce } from 'lodash-es' import { debounce } from 'lodash-es'
import imagesloaded from 'imagesloaded' import imagesloaded from 'imagesloaded'
import { useMessage } from 'naive-ui' import { useMessage } from 'naive-ui'
import { useRoute } from 'vue-router'
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn' import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn'
import { getViewportOffset, off, on } from '@/utils/domUtils' import { getViewportOffset, off, on } from '@/utils/domUtils'
@ -15,12 +16,15 @@ import { formatToDateHMS } from '@/utils/dateUtil'
import { getSimilarityList, getTaskDetailInfo } from '@/api/task/task' import { getSimilarityList, getTaskDetailInfo } from '@/api/task/task'
import emitter from '@/utils/mitt' import emitter from '@/utils/mitt'
import bgLoading from '@/assets/images/bg-loading.png' import bgLoading from '@/assets/images/bg-loading.png'
import { useRoute } from 'vue-router'
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'reject', params: any) (e: 'reject', params: any)
(e: 'approval', params: any) (e: 'approval', params: any)
}>() }>()
const imageRef = ref<ComponentElRef | null>()
const cols = ref(8)
const waterfallRef = ref(null)
const { query } = useRoute() const { query } = useRoute()
const cardStyle = { const cardStyle = {
'--n-padding-bottom': '40px', '--n-padding-bottom': '40px',
@ -60,7 +64,7 @@ const pagination = reactive({
pageSize: 30, pageSize: 30,
}) })
const loading = ref(false) const loading = ref(false)
let _masonry: null | Masonry = null const _masonry: null | Masonry = null
const show = ref(false) const show = ref(false)
const sortBy: any = { const sortBy: any = {
@ -77,52 +81,70 @@ async function computeListHeight() {
deviceHeight.value = height - 40 - 16 - 24 deviceHeight.value = height - 40 - 16 - 24
} }
onBeforeMount(async () => {
const screenWidth = window.screen.width
if (screenWidth > 1920 && screenWidth <= 2560)
cols.value = 12
else if (screenWidth <= 1920 && screenWidth >= 1792)
cols.value = 8
else if (screenWidth < 1792 && screenWidth > 1440)
cols.value = 7
else if (screenWidth <= 1440)
cols.value = 6
})
useWindowSizeFn(computeListHeight) useWindowSizeFn(computeListHeight)
const layout = debounce(() => { function finish() {
if (!show.value) console.log('finish')
return }
if (_masonry !== null) // const layout = debounce(() => {
(_masonry as any).destroy() // if (!show.value)
// return
_masonry = new Masonry(masonryRef.value as any, { // if (_masonry !== null)
itemSelector: '.grid-item', // (_masonry as any).destroy()
gutter: 17,
columnWidth: 214,
percentPosition: true,
stagger: 10,
})
_imagesload = imagesloaded('.grid-item') // _masonry = new Masonry(masonryRef.value as any, {
// itemSelector: '.grid-item',
// gutter: 17,
// columnWidth: 214,
// percentPosition: true,
// stagger: 10,
// })
_imagesload.on('done', (instance) => { // _imagesload = imagesloaded('.grid-item')
(_masonry as any).layout()
if (!el.value)
return
loading.value = false
})
_imagesload.on('fail', (instance) => { // _imagesload.on('done', (instance) => {
message.error('图片错误') // (_masonry as any).layout()
loading.value = false // if (!el.value)
}) // return
}, 300) // loading.value = false
// })
watch(viewMode, () => { // _imagesload.on('fail', (instance) => {
layout() // message.error('')
// loading.value = false
// })
// }, 300)
watch(() => viewMode.value, () => {
reset()
loadMore()
// layout()
}) })
let canloadMore = true let canloadMore = true
// useInfiniteScroll( useInfiniteScroll(
// el as any, el as any,
// () => { () => {
// console.log(123456) console.log(123456)
// loadMore() loadMore()
// }, },
// { distance: 10, canLoadMore: () => canloadMore }, { distance: 10, canLoadMore: () => canloadMore },
// ) )
async function loadMore() { async function loadMore() {
console.log('loadMore') console.log('loadMore')
@ -132,18 +154,32 @@ async function loadMore() {
if (!taskId.value) if (!taskId.value)
return return
canloadMore = false
// pagination.pageNo = pagination.pageNo + 1
const more = await fetchList() const more = await fetchList()
listData.value.push(...more) more.forEach((item) => {
nextTick(() => { item.calHeight = 182 * item.high / item.wide
layout()
}) })
if (pagination.pageNo == 1) {
listData.value = []
listData.value = listData.value.concat(more)
console.log('listData.value出来了11111111111111', listData.value)
// if(pagination.pageNo == 1) {
waterfallRef.value?.resize()
// }
}
else {
listData.value = listData.value.concat(more)
console.log('listData.value出来了2222222222', listData.value)
waterfallRef.value?.mix()
}
} }
async function fetchList() { async function fetchList() {
loading.value = true loading.value = true
try { try {
pagination.pageNo += 1 pagination.pageNo += 1
const { data, pageCount, total } = await getSimilarityList( const { data, pageCount, total, current } = await getSimilarityList(
{ {
...pagination, ...pagination,
...sortBy, ...sortBy,
@ -151,12 +187,15 @@ async function fetchList() {
pictureId: taskDetailInfo.value.ocrPicture.id, pictureId: taskDetailInfo.value.ocrPicture.id,
}, },
) )
// pagination.pageNo = current
canloadMore = pageCount >= pagination.pageNo && pageCount > 0 canloadMore = pageCount >= pagination.pageNo && pageCount > 0
console.log('canloadMore的值为', canloadMore, pageCount, pagination.pageNo)
totalCount.value = total totalCount.value = total
loading.value = false
return data return data
} }
catch (error) { catch (error) {
loading.value = false
canloadMore = false canloadMore = false
return [] return []
} }
@ -341,7 +380,7 @@ function reset() {
listData.value.length = 0 listData.value.length = 0
loading.value = false loading.value = false
canloadMore = true canloadMore = true
layout() // layout()
} }
function onChange() { function onChange() {
@ -349,22 +388,13 @@ function onChange() {
} }
async function refreshHandler() { async function refreshHandler() {
reset() // reset()
if (!taskId.value) if (!taskId.value)
return return
const taskPackage = taskStore.getApprovalList[taskStore.getCurrentIndex] || {} const taskPackage = taskStore.getApprovalList[taskStore.getCurrentIndex] || {}
taskDetailInfo.value = await getTaskDetailInfo(taskId.value, taskPackage.packageid || query.packageid, taskPackage?.taskIndex || query.taskindex) taskDetailInfo.value = await getTaskDetailInfo(taskId.value, taskPackage.packageid || query.packageid, taskPackage?.taskIndex || query.taskindex)
nextTick(() => { reset()
setTimeout(() => {
useInfiniteScroll(
el as any,
() => {
loadMore() loadMore()
},
{ distance: 10, canLoadMore: () => canloadMore },
)
}, 300)
})
} }
watch(() => taskStore.activeId, async (newValue, oldValue) => { watch(() => taskStore.activeId, async (newValue, oldValue) => {
@ -375,9 +405,39 @@ watch(() => taskStore.activeId, async (newValue, oldValue) => {
const listStyle = computed(() => { const listStyle = computed(() => {
return { return {
height: `${deviceHeight.value}px`, height: `${deviceHeight.value - 100}px`,
}
})
function previewHandler(index: number, event: MouseEvent, thumburl, imgUrl) {
event.stopImmediatePropagation()
event.stopPropagation()
if (imageRef.value?.[index] && (imageRef.value[index] as any).src)
previewImageUrl(thumburl, imgUrl);
(imageRef.value?.[index] as any).click()
}
function loadImg(src) {
const promise = new Promise((resolve, reject) => {
const img = document.createElement('img')
img.src = src
img.onload = function () {
resolve(src)
}
img.onerror = function () {
reject(new Error('加载失败'))
} }
}) })
return promise
}
function previewImageUrl(img1, img2) {
setTimeout(async () => {
const img = document.getElementsByClassName('n-image-preview').item(0)
await loadImg(img2)
img.src = img2
}, 50)
}
function switchBatch() { function switchBatch() {
setBatch(!batch.value) setBatch(!batch.value)
@ -416,13 +476,13 @@ defineExpose({
closeModal, closeModal,
}) })
onUpdated(() => { // onUpdated(() => {
nextTick(() => { // nextTick(() => {
setTimeout(() => { // setTimeout(() => {
layout() // // layout()
}, 50) // }, 50)
}) // })
}) // })
</script> </script>
<template> <template>
@ -549,17 +609,32 @@ onUpdated(() => {
<n-spin :show="loading"> <n-spin :show="loading">
<div ref="el" class="scroll" :style="listStyle"> <div ref="el" class="scroll" :style="listStyle">
<!-- <n-scrollbar :on-scroll="scrollHandler"> --> <div v-if="viewMode != 'masonry'" class="grid" :style="{ 'grid-template-columns': `repeat(${cols}, 182px)` }">
<div ref="masonryRef" class="grid">
<div <div
v-for="(item, index) in listData" v-for="(item, index) in listData"
:key="index" :key="index"
:style="{ height: gridHeight }" :style="{ height: gridHeight }"
class="grid-item" class="grid-item"
>
<img
:key="item.pictureId"
v-lazy="item.serverThumbnailUrl"
:class="{
'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
}"
:style="{ height: `${item.calHeight}px` }"
class="img"
alt="加载错误"
@click="
($event) => {
previewHandler(index, $event, item.serverThumbnailUrl, item.imgUrl);
}
"
> >
<n-image <n-image
ref="imageRef"
class="img" class="img"
:class="{ :class="{
'img-fit': viewMode === 'horizontalVersion', 'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion', 'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
@ -567,7 +642,7 @@ onUpdated(() => {
:src="item.serverThumbnailUrl ? item.serverThumbnailUrl : item.imgUrl" :src="item.serverThumbnailUrl ? item.serverThumbnailUrl : item.imgUrl"
:fallback-src="bgLoadingImg" :fallback-src="bgLoadingImg"
:style="{ backgroundImage: `url(${loading ? bgLoadingImg : 'none'})` }" :style="{ backgroundImage: `url(${loading ? bgLoadingImg : 'none'})`, display: 'none' }"
/> />
<div class="small-mark" /> <div class="small-mark" />
<div class="time"> <div class="time">
@ -594,7 +669,67 @@ onUpdated(() => {
</div> </div>
</div> </div>
</div> </div>
<!-- </n-scrollbar> -->
<waterfall v-if="viewMode === 'masonry'" ref="waterfallRef" :col="cols" :data="listData" :gutter-width="10" @finish="finish">
<div
v-for="(item, index) in listData"
:key="index"
:style="{ height: gridHeight }"
class="grid-item"
>
<img
:key="item.pictureId"
v-lazy="item.serverThumbnailUrl"
:class="{
'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
}"
:style="{ height: `${item.calHeight}px` }"
class="img"
alt="加载错误"
@click="
($event) => {
previewHandler(index, $event, item.serverThumbnailUrl, item.imgUrl);
}
"
>
<n-image
ref="imageRef"
class="img"
:class="{
'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
}"
:src="item.serverThumbnailUrl ? item.serverThumbnailUrl : item.imgUrl"
:fallback-src="bgLoadingImg"
:style="{ backgroundImage: `url(${loading ? bgLoadingImg : 'none'})`, display: 'none' }"
/>
<div class="small-mark" />
<div class="time">
<div v-if="item.photoDateTimestamp" class="time-item">
<SvgIcon class="svg-time" color="#FFF" size="14" name="camera-time" />
<span>{{ formatToDateHMS(Number(item.photoDateTimestamp) || 0) }}</span>
</div>
<div v-if="item.submitDateTimestamp" class="time-item time-item2">
<SvgIcon class="svg-time" color="#FFF" size="14" name="submit-time" />
<span>{{ formatToDateHMS(Number(item.submitDateTimestamp) || 0) }}</span>
</div>
</div>
<img v-if="item.historyStates === 2" class="tag-status" src="@/assets/images/task/tag-pass.png" alt="">
<img v-if="item.historyStates === 3" class="tag-status" src="@/assets/images/task/tag-not-pass.png" alt="">
<div class="check">
<n-checkbox
v-show="batch && item.historyStates === 1"
v-model:checked="item.checked" @click.prevent
@update:checked="onCheckChange($event, item)"
/>
</div>
<div :class="{ 'percent-red': item.similarityScore === 100 }" class="percent">
{{ item.similarityScore }}<span class="percent-unit">%</span>
</div>
</div>
</waterfall>
</div> </div>
</n-spin> </n-spin>
</div> </div>
@ -634,13 +769,13 @@ onUpdated(() => {
} }
.small-mark{ .small-mark{
width: 100%; width: 182px;
height: 56px; height: 56px;
background: linear-gradient(180deg,rgba(0,0,0,0.01), rgba(0,0,0,0.44) 88%); background: linear-gradient(180deg,rgba(0,0,0,0.01), rgba(0,0,0,0.44) 88%);
//border-radius: 0px 8px 8px 8px; //border-radius: 0px 8px 8px 8px;
position: absolute; position: absolute;
left: 0; left: 6px;
bottom: 0; bottom: 6px;
z-index: 0; z-index: 0;
border-radius: 0 0 8px 8px; border-radius: 0 0 8px 8px;
} }
@ -649,15 +784,15 @@ onUpdated(() => {
width: 46px; width: 46px;
height: 22px; height: 22px;
position: absolute; position: absolute;
left: -4px; left: 3px;
top: 4px; top: 6px;
} }
.time { .time {
position: absolute; position: absolute;
z-index: 3; z-index: 3;
left: 3px; left: 6px;
bottom: 3px; bottom: 6px;
.time-item{ .time-item{
display: flex; display: flex;
align-items: center; align-items: center;
@ -835,11 +970,12 @@ onUpdated(() => {
} }
.img { .img {
width: 182px;
max-width: 182px;
border-radius: 7px; border-radius: 7px;
display: block; display: block;
// height: calc(100% - 25px); opacity: 1 !important;
height: 100%; height: 100%;
width: 100%;
} }
.img-full { .img-full {
@ -853,19 +989,24 @@ onUpdated(() => {
} }
} }
.grid{
grid-gap: 0px 20px;
}
.grid-item { .grid-item {
width: 214px; box-sizing: content-box;
// padding: 16px; width: 182px;
// width: 182px; padding: 6px;
transition: 0.5s;
margin-bottom: 20px;
position: relative; position: relative;
margin-bottom: 32px;
transition: 0.5s; transition: 0.5s;
.check{ .check{
position: absolute; position: absolute;
z-index: 3; z-index: 3;
left: 4px; left: 6px;
top: 4px; top: 6px;
} }
.percent { .percent {
@ -879,8 +1020,8 @@ onUpdated(() => {
background: #6f92fd; background: #6f92fd;
border-radius: 6px 0px 6px 0px; border-radius: 6px 0px 6px 0px;
z-index: 5; z-index: 5;
right: 4px; right: 6px;
top: 4px; top: 6px;
color: #fff; color: #fff;
font-size: 14px; font-size: 14px;
} }

Loading…
Cancel
Save