feat: 工单拖动加载;更换缩略图

bak
elseif 1 year ago
parent eec99c21e7
commit ceb473d4b2

@ -77,6 +77,7 @@ export async function getTaskDetailPictureList(packageid: string, taskchildpictu
})
const { data: { records, pages, total } } = res
debugger
// 精简一下数据
const list = records.map((item) => {
@ -87,6 +88,7 @@ export async function getTaskDetailPictureList(packageid: string, taskchildpictu
assignee: item.assignee,
pictureid: item.pictureid,
imgurl: item.ocrPicture.imgurl,
thumburl: item.serverThumbnailUrl || item.ocrPicture.imgurl,
iztrueorfalse: item.iztrueorfalse,
states: item.states,
history: hasHistory(item.ocpictureid, item.picturecompare),

@ -26,7 +26,7 @@ const el = ref<HTMLDivElement | null>(null)
const viewMode = ref('masonry')
const pagination = reactive({
pageNo: 0,
pageSize: 50,
pageSize: 30,
})
const configStore = useConfig()
const packageModalRef = ref(null)
@ -136,6 +136,7 @@ async function featchList() {
const list = data.map((item) => {
return {
imgUrl: item.imgurl,
thumburl: item.serverThumbnailUrl || item.imgurl,
upname: item.upname,
ocrPictureclass: item.ocrPictureclass,
uphead: item.uphead,
@ -216,7 +217,7 @@ watch(() => configStore.asideValue, (newVal, oldVal) => {
function reset() {
pagination.pageNo = 0
pagination.pageSize = 50
pagination.pageSize = 30
listData.value.length = 0
loading.value = false
canloadMore = true
@ -241,6 +242,10 @@ async function refreshHandler(filtersearchId?: any) {
function getAvatar(url: string): string {
return url ? getImgUrl(url) : avatar
}
const totalCount = computed(() => {
return listData.value.length
})
</script>
<template>
@ -253,19 +258,22 @@ function getAvatar(url: string): string {
<SvgIcon style="cursor: pointer;" size="105" name="yijianchachong" @click="oneCheck" />
</div>
<div class="wrapper-content">
<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">
<div class="dropdown">
<span>{{ viewLabel || '请选择' }}</span>
<SvgIcon class="gap" name="arrow-botton" size="14" />
</div>
</n-popselect>
<div style="display: flex;justify-content: space-between;">
<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">
<div class="dropdown">
<span>{{ viewLabel || '请选择' }}</span>
<SvgIcon class="gap" name="arrow-botton" size="14" />
</div>
</n-popselect>
</div>
<span>{{ totalCount }}</span>
</div>
<n-spin :show="loading">
<div ref="el" class="scroll" :style="listStyle">
@ -279,7 +287,7 @@ function getAvatar(url: string): string {
> -->
<n-image
class="img" :img-props="{ onClick: hideDownload }"
:class="{ 'img-fit': viewMode !== 'masonry' }" :src="item.imgUrl"
:class="{ 'img-fit': viewMode !== 'masonry' }" :src="item.thumburl"
/>
<div class="info">
<div class="left">

@ -369,7 +369,7 @@ function getPercent(pictureid: string) {
</div>
<div class="list">
<div v-for="(item, index) in taskDetailPictureList" :key="index" class="item">
<div class="img-wrapper" :style="{ 'background-image': `url(${item.imgurl})` }" />
<div class="img-wrapper" :style="{ 'background-image': `url(${item.thumburl})` }" />
<div class="check">
<n-checkbox
v-show="batch"

@ -27,7 +27,7 @@ const { isLoading } = useInfiniteScroll(
() => {
loadMore()
},
{ distance: 10, interval: 300, canLoadMore: () => {
{ distance: 10, interval: 800, canLoadMore: () => {
// console.log('canloadmore excuted!')
return canloadMore.value
} },

@ -1,7 +1,9 @@
<script lang="ts" setup>
import { computed, onUnmounted, reactive, ref, unref, watch } from 'vue'
import { computed, onMounted, onUnmounted, onUpdated, reactive, ref, unref, watch } from 'vue'
import { useDialog, useMessage } from 'naive-ui'
import { clone, pickBy } from 'lodash-es'
import { clone, debounce, pickBy } from 'lodash-es'
import { useInfiniteScroll } from '@vueuse/core'
import imagesloaded from 'imagesloaded'
import ConfrimModal from '../modal/ConfrimModal.vue'
import type { PictureSortParam, SetTFParam } from '/#/api'
import { useWorkOrder } from '@/store/modules/workOrder'
@ -15,6 +17,7 @@ const selectItems = ref<any[]>([])
const message = useMessage()
const dialog = useDialog()
const totalCount = ref(0)
let _imagesload: any
function setBatch(value: boolean) {
batch.value = value
@ -59,6 +62,11 @@ const taskDetailInfo = ref<any>({})
const taskDetailPictureList = ref<any[]>([])
const confrimModalRef = ref(null)
const imageRef = ref<ComponentElRef | null>()
const listData = ref<any[]>([])
const loading = ref(false)
const el = ref<HTMLDivElement | null>(null)
let canloadMore = true
let processItems: any[] = []
@ -184,16 +192,86 @@ function backHandler() {
workStore.back()
}
function reset() {
taskpagination.pageNo = 0
taskpagination.pageSize = 20
listData.value.length = 0
loading.value = false
canloadMore = true
}
async function refreshHandler() {
reset()
useInfiniteScroll(
el as any,
() => {
loadMore()
},
{ distance: 10, canLoadMore: () => canloadMore },
)
}
async function loadMore() {
if (loading.value || el.value == null)
return
const more = await featchList()
listData.value.push(...more)
}
async function featchList() {
loading.value = true
try {
taskpagination.pageNo += 1
const taskId = selectTask.value.id
const { data, total, pageCount } = await getTaskDetailPictureList(workStore.activeId, taskId, { ...taskpagination, ...sortBy })
totalCount.value = total
canloadMore = pageCount >= taskpagination.pageNo && pageCount > 0
return data
}
catch (error) {
canloadMore = false
return []
}
}
const layout = debounce(() => {
if (el.value == null)
return
_imagesload = imagesloaded('.grid-item')
_imagesload.on('done', (instance) => {
if (!el.value)
return
const scrollHeight = el.value!.scrollHeight
const clientHeight = el.value!.clientHeight
const top = scrollHeight - clientHeight - 100
el.value!.scrollTo({ top, behavior: 'instant' })
loading.value = false
})
_imagesload.on('fail', (instance) => {
message.error('图片错误')
loading.value = false
})
}, 300)
onUpdated(() => {
layout()
})
watch(() => workStore.activeId, async (newValue, oldValue) => {
const taskId = workStore.getActiveId
const packageid = workStore.getActiveId
if (isEmpty(taskId))
if (isEmpty(packageid))
return
const res = await getPackageTaskList(newValue, packagepagination)
const { data } = res
taskList.value = data
if (taskList.value.length > 0)
handleSelect(taskList.value[0])
})
@ -208,9 +286,15 @@ async function handleSelect(item: any) {
const taskId = item.id
taskDetailInfo.value = await getTaskDetailInfo(taskId, workStore.activeId)
const { data, total } = await getTaskDetailPictureList(workStore.activeId, taskId, { ...taskpagination, ...sortBy })
taskDetailPictureList.value = data
totalCount.value = total
const packageid = workStore.getActiveId
if (isEmpty(packageid))
return
// const { data, total } = await getTaskDetailPictureList(workStore.activeId, taskId, { ...taskpagination, ...sortBy })
// taskDetailPictureList.value = data
// totalCount.value = total
refreshHandler()
}
async function sortHandler(orderby: 'pictureResult' | 'fromuptime') {
@ -292,8 +376,6 @@ function previewHandler(event: MouseEvent) {
if (imageRef.value)
(imageRef.value as any).mergedOnClick()
}
const count = computed(() => taskDetailPictureList.value.length)
</script>
<template>
@ -334,110 +416,115 @@ const count = computed(() => taskDetailPictureList.value.length)
</div>
</div>
</div>
<div class="wrapper-detail">
<div
class="left" :style="{ 'background-image': `url(${taskDetailInfo?.ocrPicture?.imgurl})` }"
@click="previewHandler"
>
<div class="mark">
<SvgIcon v-show="taskDetailInfo?.iztrueorfalse === 0" size="128" name="jia" />
</div>
<div class="mark">
<SvgIcon v-show="taskDetailInfo?.iztrueorfalse === 1" size="128" name="zhen" />
</div>
<div class="info">
<n-grid x-gap="16" y-gap="0" :cols="12">
<n-gi span="4">
<span style="color:#8b8d8f;">
<SvgIcon name="m1" />
</span>
</n-gi>
<n-gi span="8" style="display: flex;align-items: left;flex-direction: column;justify-content: center;">
<span>{{ mark }}</span>
<span>图片标记</span>
</n-gi>
<n-gi span="4">
<span style="color:#8b8d8f;">
<SvgIcon name="m2" />
</span>
</n-gi>
<n-gi span="8" style="display: flex;align-items: left;flex-direction: column;justify-content: center;">
<span>{{ totalCount }}</span>
<span>相似匹配</span>
</n-gi>
</n-grid>
</div>
<div style="display: none;">
<n-image ref="imageRef" :img-props="{ onClick: hideDownload }" :src="taskDetailInfo?.ocrPicture?.imgurl" />
</div>
</div>
<div class="right">
<n-scrollbar style="max-height: 100%;">
<span class="name">图片名称</span>
<div class="tags">
<div class="tag tag-actived">
重复图片
<n-spin :show="loading">
<div ref="el" class="scroll">
<div class="wrapper-detail">
<div
class="left" :style="{ 'background-image': `url(${taskDetailInfo?.ocrPicture?.imgurl})` }"
@click="previewHandler"
>
<div class="mark">
<SvgIcon v-show="taskDetailInfo?.iztrueorfalse === 0" size="128" name="jia" />
</div>
<div class="tag">
基线任务
<div class="mark">
<SvgIcon v-show="taskDetailInfo?.iztrueorfalse === 1" size="128" name="zhen" />
</div>
<div class="info">
<n-grid x-gap="16" y-gap="0" :cols="12">
<n-gi span="4">
<span style="color:#8b8d8f;">
<SvgIcon name="m1" />
</span>
</n-gi>
<n-gi span="8" style="display: flex;align-items: left;flex-direction: column;justify-content: center;">
<span>{{ mark }}</span>
<span>图片标记</span>
</n-gi>
<n-gi span="4">
<span style="color:#8b8d8f;">
<SvgIcon name="m2" />
</span>
</n-gi>
<n-gi span="8" style="display: flex;align-items: left;flex-direction: column;justify-content: center;">
<span>{{ totalCount }}</span>
<span>相似匹配</span>
</n-gi>
</n-grid>
</div>
<div style="display: none;">
<n-image ref="imageRef" :img-props="{ onClick: hideDownload }" :src="taskDetailInfo?.ocrPicture?.imgurl" />
</div>
</div>
<n-divider />
<div class="property">
<span class="property-name top" style="font-weight: bold;color: #333333;">拜访终端
</span>
<span style="font-weight: bold;color: #333333;font-size: 16px;">拜访终端</span>
</div>
<div v-for="(key) in Object.keys(propertys)" :key="key" class="property">
<span class="property-name">{{ fieldMap[key] }}</span>
<span class="property-content ">{{ propertys[key] }}</span>
<div class="right">
<n-scrollbar style="max-height: 100%;">
<span class="name">图片名称</span>
<div class="tags">
<div class="tag tag-actived">
重复图片
</div>
<div class="tag">
基线任务
</div>
</div>
<n-divider />
<div class="property">
<span class="property-name top" style="font-weight: bold;color: #333333;">拜访终端
</span>
<span style="font-weight: bold;color: #333333;font-size: 16px;">拜访终端</span>
</div>
<div v-for="(key) in Object.keys(propertys)" :key="key" class="property">
<span class="property-name">{{ fieldMap[key] }}</span>
<span class="property-content ">{{ propertys[key] }}</span>
</div>
</n-scrollbar>
</div>
</n-scrollbar>
</div>
</div>
<div style="display: flex;justify-content: space-between;padding: 12px 0px;">
<div><span style="font-size: 21px;font-weight: bold;">相似图片</span><span>({{ count }})</span></div>
<div style="display: flex;align-items: center;" @click="sortHandler('fromuptime')">
<div style="cursor: pointer;">
<span>按时间排序</span>
<SvgIcon style="margin-left: 8px;" name="sort" size="12" />
</div>
<div style="margin-left: 15px;cursor: pointer" @click="sortHandler('pictureResult')">
<span>相似度排序</span>
<SvgIcon style="margin-left: 8px;" name="sort" size="12" />
</div>
</div>
</div>
<div class="wrapper-list">
<div
v-for="(item, index) in taskDetailPictureList" :key="index" :class="{ 'item-selected': item === selectTask }"
class="item" @click="handleSelect(item)" @mouseover="overTaskHandelr(item)" @mouseleave="leaveTaskHandler"
>
<div class="img-wrapper" :style="{ 'background-image': `url(${item.imgurl})` }" />
<div class="check">
<n-checkbox
v-show="batch" v-model:checked="item.checked" @click.stop
@update:checked="onCheckChange($event, item)"
/>
</div>
<div class="percent">
<SvgIcon size="42" name="tag" />
<div class="val">
{{ getPercent(item.pictureid) }}
<div style="display: flex;justify-content: space-between;padding: 12px 0px;">
<div><span style="font-size: 21px;font-weight: bold;">相似图片</span><span>({{ totalCount }})</span></div>
<div style="display: flex;align-items: center;" @click="sortHandler('fromuptime')">
<div style="cursor: pointer;">
<span>按时间排序</span>
<SvgIcon style="margin-left: 8px;" name="sort" size="12" />
</div>
<div style="margin-left: 15px;cursor: pointer" @click="sortHandler('pictureResult')">
<span>相似度排序</span>
<SvgIcon style="margin-left: 8px;" name="sort" size="12" />
</div>
</div>
</div>
<div class="mark">
<SvgIcon v-show="item.iztrueorfalse === 0" name="jia" />
</div>
<div class="mark">
<SvgIcon v-show="item.iztrueorfalse === 1" name="zhen" />
</div>
<div v-show="overTask && overTask.id === item.id" class="action">
<SvgIcon style="cursor: pointer;" name="t1" @click.stop="trueHandler" />
<SvgIcon style="cursor: pointer;" name="t2" @click.stop="falseHandler" />
<div class="wrapper-list">
<div
v-for="(item, index) in listData" :key="index" :class="{ 'item-selected': item === selectTask }"
class="grid-item" @click="handleSelect(item)" @mouseover="overTaskHandelr(item)"
@mouseleave="leaveTaskHandler"
>
<div class="img-wrapper" :style="{ 'background-image': `url(${item.thumburl})` }" />
<div class="check">
<n-checkbox
v-show="batch" v-model:checked="item.checked" @click.stop
@update:checked="onCheckChange($event, item)"
/>
</div>
<div class="percent">
<SvgIcon size="42" name="tag" />
<div class="val">
{{ getPercent(item.pictureid) }}
</div>
</div>
<div class="mark">
<SvgIcon v-show="item.iztrueorfalse === 0" name="jia" />
</div>
<div class="mark">
<SvgIcon v-show="item.iztrueorfalse === 1" name="zhen" />
</div>
<div v-show="overTask && overTask.id === item.id" class="action">
<SvgIcon style="cursor: pointer;" name="t1" @click.stop="trueHandler" />
<SvgIcon style="cursor: pointer;" name="t2" @click.stop="falseHandler" />
</div>
</div>
</div>
</div>
</div>
</n-spin>
<ConfrimModal ref="confrimModalRef" @commit="setFalse" />
</div>
</template>
@ -453,8 +540,11 @@ const count = computed(() => taskDetailPictureList.value.length)
background: #FFF;
border-radius: 3px;
border: 1px solid rgb(239, 239, 245);
height: calc(100vh - 88px);
overflow-y: scroll;
.scroll {
height: calc(100vh - 88px - 72px);
overflow-y: scroll;
}
&-header {
display: flex;
@ -635,7 +725,7 @@ const count = computed(() => taskDetailPictureList.value.length)
background-color: #FFF;
}
.item {
.grid-item {
box-sizing: border-box;
border-radius: 8px;
padding: 9px 10px;

Loading…
Cancel
Save