mcwl-pc/app/components/WorkFlowList.vue

195 lines
5.1 KiB
Vue

<script setup lang="ts">
import { Download, Play } from 'lucide-vue-next'
import { nextTick, onMounted, onUnmounted, ref } from 'vue'
// import { useRouter } from 'vue-router'
const props = defineProps({
params: {
type: Object,
default: () => {},
},
})
const emit = defineEmits(['workFlowTotal'])
const modalStore = useModalStore()
// const router = useRouter()
const loading = ref(false)
const finished = ref(false)
const total = ref(0) // 总条数
const loadingTrigger = ref(null)
const observer = ref<IntersectionObserver | null>(null)
const listParams = ref({
...props.params,
pageNumber: 1,
pageSize: 20,
name: modalStore.searchQuery,
isCollect: 1,
})
function initPageNUm() {
listParams.value.pageNumber = 1
finished.value = false // 重置加载完成状态
listParams.value = Object.assign({}, listParams.value, props.params)
getDataList()
}
const dataList = ref([])
async function getDataList() {
if (loading.value || finished.value)
return
loading.value = true
try {
const res = await request.post('/WorkFlow/workFlowList', { ...listParams.value })
if (res.code === 200) {
// 如果是第一页,直接赋值,否则追加数据
if (listParams.value.pageNumber === 1) {
dataList.value = res.data.list
}
else {
dataList.value = [...dataList.value, ...res.data.list]
}
total.value = res.data.total // 假设接口返回了总条数
// 判断是否加载完所有数据
if (dataList.value.length >= total.value) {
finished.value = true
}
// 自动增加页码
listParams.value.pageNumber++
emit('workFlowTotal', total.value)
}
}
catch (err) {
dataList.value = []
finished.value = true
console.log(err)
}
finally {
loading.value = false
}
}
getDataList()
// 跳转详情
function toDetail(item: any) {
// router.push(`/workflow-details/${item.id}`)
const baseUrl = window.location.origin
window.open(`${baseUrl}/workflow-details/${item.id}`, '_blank', 'noopener,noreferrer')
}
onMounted(() => {
window.addEventListener('scroll', topedRefresh)
observer.value = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting && !loading.value && !finished.value) {
getDataList()
}
},
{
threshold: 0.1,
},
)
if (loadingTrigger.value) {
observer.value.observe(loadingTrigger.value)
}
})
onUnmounted(() => {
window.removeEventListener('scroll', topedRefresh)
if (observer.value) {
observer.value.disconnect()
}
})
async function topedRefresh() {
if (import.meta.client) {
await nextTick()
window.scrollTo({
top: 0,
behavior: 'smooth',
})
}
initPageNUm()
}
defineExpose({
initPageNUm,
})
</script>
<template>
<div class="flex flex-wrap w-full">
<div class="grid grid-cols-2 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-7 gap-4 p-4">
<div
v-for="item in dataList"
:key="item.id"
class="relative rounded-lg overflow-hidden"
>
<!-- 图片 -->
<div class="relative border border-solid border-[#e5e7eb] h-[300px] overflow-hidden rounded-lg" @click="toDetail(item)">
<img
:src="item.coverPath"
class="w-full h-full object-cover rounded-lg cursor-pointer ransform transition-transform duration-300 hover:scale-110"
alt=""
>
<!-- 左上角标签 -->
<!-- <div
class="absolute top-2 left-2 bg-black/50 text-white text-xs px-2 py-1 rounded"
>
{{ item.type }}
</div> -->
<!-- 底部数据统计 -->
<div
class="absolute bottom-0 left-0 right-0 flex items-center gap-2 p-2 text-xs text-white"
>
<div class="flex items-center">
<component :is="Play" class="h-[14px] w-[14px] text-white menu-icon m-1" />
{{ item.useNumber || 0 }}
</div>
<div class="flex items-center">
<component
:is="Download"
class="h-[14px] w-[14px] text-white menu-icon m-1"
/>
{{ item.downloadNumber || 0 }}
</div>
</div>
</div>
<!-- 作者信息条 -->
<div class="mt-1 px-2 py-1">
<div>
<span class="text-[#19191c] text-[14px] max-w-xs truncate ">
{{ item.workflowName }}
</span>
</div>
<div class="flex mt-1">
<img :src="item.avatar" class="w-4 h-4 rounded-full mr-2" alt="">
<span class="text-xs text-gray-500 truncate">{{ item.nickName }}</span>
</div>
</div>
</div>
</div>
<div v-if="!loading && dataList.length === 0" class="w-full flex justify-center">
<Empty />
</div>
<div
ref="loadingTrigger"
class="h-20 w-full text-gray-500 flex justify-center items-center"
>
<div v-if="loading">
加载中...
</div>
<div v-if="finished && dataList.length >= 20">
</div>
</div>
</div>
</template>
<style scoped></style>