<script lang="ts" setup>
import { EllipsisHorizontal, EyeOutline as EyeOutlineIcon } from '@vicons/ionicons5'
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 { cloneDeep, debounce } from 'lodash-es'

// import Masonry from 'masonry-layout'
import { NIcon, useMessage } from 'naive-ui'
import type { Component } from 'vue'
import {
  computed,
  h,
  nextTick,
  onBeforeMount,
  onMounted,
  onUnmounted,
  onUpdated,
  reactive,
  ref,
  unref,
  watch,
} from 'vue'
import CheckingTaskModal from './modal/CheckingTaskModal.vue'
import FinishPackageModal from './modal/FinishPackageModal.vue'
import GeneratePackageModal from './modal/GeneratePackageModal.vue'
import LoginSuccessModal from './modal/LoginSuccessModal.vue'
import PackageSettingsModal from './modal/PackageSettingsModal.vue'
import QueryRepeatedTasksModal from './modal/QueryRepeatedTasksModal.vue'
import type { PictureSortParam } from '/#/api'
import defaultAvatar from '@/assets/icons/avatar.svg'
import baseImg from '@/assets/images/baseImg.png'
import { getImgUrl } from '@/utils/urlUtils'
import emitter from '@/utils/mitt'
import { hideDownload } from '@/utils/image'
import { getViewportOffset } from '@/utils/domUtils'
import { useConfig } from '@/store/modules/asideConfig'
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn'
import { timeOptions, viewOptions } from '@/config/home'
import avatar from '@/assets/images/avatar.jpg'
import {
  createPackage,
  getCheckDuplicateStatus,
  getLastCheckNo,
  getPictureList,
  oneClickCheckTaskPackage,
  queryPageListByCheckNo,
  removeCheckDuplicate,
} from '@/api/home/main'

import bgLoading from '@/assets/images/bg-loading.png'

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)
const el = ref<HTMLDivElement | null>(null)
const waterfallRef = ref(null)
const viewMode = ref('masonry')
const pagination = reactive({
  pageNo: 0,
  pageSize: 30,
})
const configStore = useConfig()
const packageModalRef = ref(null)
const generateModalRef = ref(null)
const queryRepeatedTasksModalRef = ref(null)
const LoginSuccessModalRef = ref(null)
const checkingTaskModalRef = ref(null)
const finishPackageModal = ref(null)
const loading = ref(false)
const message = useMessage()
const totalCount = ref(0)
const sortBy: PictureSortParam = {
  orderbyname: 'desc',
  orderbyvalue: 'pictureResult',
}
const imageRef = ref<ComponentElRef | null>()
const checkDuplicateNo = ref('')
const checkTaskStatus = ref(null) // 1.执行中 2.执行完毕  3.执行失败
const isRefresh = ref(true) // 生成任务包前，点击刷新数据，并将【一键查重】切换按钮为【生成任务包】
const bgLoadingImg = ref(bgLoading)
const cols = ref(7)

let canloadMore = true
let filterId = null

async function computeListHeight() {
  const headEl = document.querySelector('.wrapper-content')!
  const { bottomIncludeBody } = getViewportOffset(headEl)
  const height = bottomIncludeBody
  deviceHeight.value = height - 40 - 16 - 24
}

useWindowSizeFn(computeListHeight)

const listStyle = computed(() => {
  return {
    height: `${deviceHeight.value}px`,
  }
})

// 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,
  () => {
    loadMore()
  },
  { distance: 10, canLoadMore: () => canloadMore },
)

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
  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
})

onUpdated(() => {
  // nextTick(() => {
  //   setTimeout(() => {
  //     layout()
  //   }, 50)
  // })
})

const timeRange = ref('')
const timeLabel = computed(() => {
  const item = timeOptions.find((option) => {
    return option.value === timeRange.value
  })

  return item?.label
})

const isAllowDownload = ref(true)
const calNum = ref(0)
const searchValue = ref('')
const isInitSeaerch = ref(false) // 是否初始化搜索

configStore.$subscribe(() => {
  console.log('subscribe', 'configStore')
  isAllowDownload.value = configStore.isAllowDownload
  calNum.value = configStore.getTimeNum
  // console.log("calNum.value----------", calNum.value);
  searchValue.value = configStore.getSearchValue
  console.log(configStore.getSearchValue, 'getSearchValue')
})

watch(
  () => searchValue.value,
  async (newVal, oldVal) => {
    if (newVal) {
      isInitSeaerch.value = true
      pagination.pageNo = 0
      const more = await featchList()
      listData.value = more
      isInitSeaerch.value = false
      // configStore.setSearchValue("");
    }
    else {
      isInitSeaerch.value = true
      pagination.pageNo = 0
      const more = await featchList()
      listData.value = more
      isInitSeaerch.value = false
    }
  },
)

watch(
  () => configStore.getAsideValue,
  async (newVal, oldVal) => {
    if (newVal) {
      reset()
      loadMore()
    }
  },
)

async function featchList(userSearchId?: string) {
  loading.value = true
  try {
    const contentParams = {
      search_month: timeRange.value,
      search_history: 0,
      userSearchId,
    }

    pagination.pageNo += 1
    const searchValue = configStore.getSearchValue // rao
    const asideParams = unref(configStore.getAsideValue)
    const params = filterId ? { userSearchId: filterId } : cloneDeep(asideParams)
    let result = {
      pageCount: 0,
      data: [],
      total: 0,
      current: 1,
    }
    const sortObj: any = {} // rao start
    if (sortBy.orderbyvalue == 'pictureResult')
      sortObj.ordertype = sortBy.orderbyname
    else if (sortBy.orderbyvalue == 'fromuptime')
      sortObj.orderByTime = sortBy.orderbyname

    if (params.izsimilarity && typeof params.izsimilarity != 'string')
      params.izsimilarity = params.izsimilarity.join('-')

    // rao end

    if (checkTaskStatus.value === 2 && isRefresh) {
      result = await queryPageListByCheckNo({
        ...pagination,
        ...contentParams,
        ...params,
        ...sortObj,
        checkDuplicateNo: checkDuplicateNo.value,
        upUserName: searchValue,
      })
    }
    else {
      result = await getPictureList({
        ...pagination,
        ...contentParams,
        ...params,
        ...sortObj,
        upUserName: searchValue,
      })
    }
    const { data, pageCount, total, current } = result
    pagination.pageNo = current
    totalCount.value = total
    canloadMore = pageCount >= pagination.pageNo && pageCount > 0

    const list = data.map((item) => {
      return {
        id: item.id,
        calHeight: 0,
        imgUrl: item.imgurl,
        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()
  more.forEach((item) => {
    item.calHeight = 182 * item.high / item.wide
  })
  // listData.value.push(...more)
  if (pagination.pageNo == 1) {
    listData.value = []
    listData.value = listData.value.concat(more)
    console.log('listData.value出来了', listData.value)
    waterfallRef.value?.resize()
  }
  else {
    // setTimeout(() => {
    //   const height = el.value?.scrollHeight - 1000
    //   console.log('listData.value出来了height', height)
    //   el.value?.scrollTo({ top: height, behavior: 'smooth' })
    // }, 50)
    listData.value = listData.value.concat(more)
    console.log('listData.value出来了', listData.value)
    waterfallRef.value?.mix()
  }
}

const gridHeight = computed(() => {
  let height = 0
  if (viewMode.value === 'masonry')
    height = 0
  else if (viewMode.value === 'horizontalVersion')
    height = 145
  else if (viewMode.value === 'verticalVersion')
    height = 300
  else if (viewMode.value === '3:4')
    height = 240

  return height
})

watch(() => viewMode.value, (newVal, oldVal) => {
  reset()
  loadMore()
})

const gridMinHeight = computed(() => {
  let height = ''
  if (viewMode.value === 'masonry' && loading.value)
    height = '145px'
  else
    height = ''

  return height
})

async function oneCheck() {
  const asideVal = cloneDeep(configStore.getAsideValue)
  asideVal.upUserName = searchValue.value

  if (asideVal.izyear && asideVal.izyear.length == 2) {
    asideVal.izyear = `${dayjs(asideVal.izyear[0]).format('YYYY/MM/DD')}-${dayjs(
      asideVal.izyear[1],
    ).format('YYYY/MM/DD')}`
  }
  if (asideVal.izsimilarity && typeof asideVal.izsimilarity != 'string')
    asideVal.izsimilarity = asideVal.izsimilarity.join('-')

  const tasksLoadingModal = queryRepeatedTasksModalRef.value as any

  console.log('calNum.value111111111111111', calNum.value, checkTaskStatus.value)
  if (calNum.value == 0 && isRefresh.value) {
    if (timer.value)
      clearInterval(timer.value)

    timer.value = setInterval(() => {
      if (checkDuplicateNo.value) {
        getCheckDuplicateStatus(checkDuplicateNo.value).then((res) => {
          if (res.code === 'OK') {
            checkTaskStatus.value = res.data.status
            if (calNum.value < 90)
              calNum.value = calNum.value + 10

            configStore.setTimeNum(calNum.value)
            if (checkTaskStatus.value === 2 || checkTaskStatus.value === 3) {
              if (checkTaskStatus.value === 2)
                message.success('任务执行完毕，正在刷新数据...')
              else message.error('查询异常')

              tasksLoadingModal.closeOnlyModal()
              configStore.setTimeNum(100)
              if (timer.value)
                clearInterval(timer.value)

              setTimeout(() => {
                configStore.setTimeNum(0)
              }, 1000)
              reset()
              loadMore()
            }
          }
          else {
            if (timer.value)
              clearInterval(timer.value)
          }
        })
      }
    }, 1000)
  }
  // 查重任务编号,状态不为空,或者状态执行中..
  if (checkDuplicateNo.value && checkTaskStatus.value && checkTaskStatus.value === 1) {
    // 暂时rao
    tasksLoadingModal.showModal()
    return
  }
  // 调用查重任务开启流程
  oneClickCheckTaskPackage(asideVal).then((res) => {
    if (res.code === 'OK') {
      checkDuplicateNo.value = res.data.checkDuplicateNo
      checkTaskStatus.value = res.data.status
      tasksLoadingModal.showModal() // 暂时rao
    }
    else {
      message.error(res.message || '查重失败')
    }
  })
}

/**
 * 显示添加任务包
 */
async function showAddPackage() {
  const modal = packageModalRef.value as any
  modal.showModal()
}

// 查重任务加载提示框,关闭回调
async function tasksLoadingCloseCallback() {
  const checkingTaskModal = checkingTaskModalRef.value as any
  checkingTaskModal.showModal()
  if (isRefresh.value)
    refresh(true)
}

async function showLoginSuccessModal() {
  const modal = LoginSuccessModalRef.value as any
  modal.showModal()
}
async function closeLoginSuccessModal() {
  const modal = LoginSuccessModalRef.value as any
  modal.closeModal()
}
// 包id
const packageIdRef = ref('')

async function commitHandler(settingParam) {
  const params = {
    name: settingParam.packagename,
    checkDuplicateNo: checkDuplicateNo.value,
  }
  const modal = generateModalRef.value as any
  const finishModal = finishPackageModal.value as any
  modal.showModal()
  createPackage(params).then((res) => {
    if (res.code === 'OK') {
      message.success(res.message)
      packageIdRef.value = res.data.id
      modal.closeModal()
      finishModal.showModal()
      // 清空查重任务状态和编号
      checkDuplicateNo.value = ''
      checkTaskStatus.value = null
    }
  })
  const asideVal = configStore.getAsideValue
  const finalParam = { ...asideVal }
  finalParam.buessinessno = settingParam.packagename
  finalParam.search_history = settingParam.comparehistory ? 1 : 0
}

onMounted(() => {
  emitter.on('filter', refreshHandler)
  // emitter.on("filter", (searchId)=>{
  //   console.log("emitter on filter" + searchId)
  //   reset()
  //   featchList(searchId)
  // })
  // 一件键重——获取任务编号
  getLastCheckNo().then((res) => {
    if (res.code === 'OK')
      checkDuplicateNo.value = res.data
  })
  nextTick(() => {
    computeListHeight()
    // 登录后展示成功
    // showLoginSuccessModal()
  })
})

onUnmounted(() => {
  emitter.off('filter', refreshHandler)
})

watch(timeRange, () => {
  refreshHandler()
})

watch(
  () => configStore.asideValue,
  (newVal, oldVal) => {
    refreshHandler()
  },
  { deep: true },
)

function reset(val?) {
  pagination.pageNo = 0
  pagination.pageSize = 30
  listData.value = []
  listData.value.length = 0
  loading.value = false
  canloadMore = true
  filterId = null
  // layout()
}

async function refreshHandler(filtersearchId?: any) {
  reset(true)

  if (filtersearchId)
    filterId = filtersearchId
  loadMore(true)
  // nextTick(() => {
  //   setTimeout(() => {
  //     useInfiniteScroll(
  //       el as any,
  //       () => {
  //         loadMore()
  //       },
  //       { distance: 10, canLoadMore: () => canloadMore },
  //     )
  //   }, 300)
  // })
}

function getAvatar(url: string): string {
  return url ? getImgUrl(url) : avatar
}

function sortHandler(orderby: 'pictureResult' | 'fromuptime') {
  sortBy.orderbyvalue = orderby
  sortBy.orderbyname = sortBy.orderbyname === 'asc' ? 'desc' : 'asc'

  refreshHandler()
}
async function downloadImage(item) {
  if (!item.imgUrl) {
    message.error('请输入有效的图片链接地址')
    return
  }
  try {
    // 使用 fetch 发送 GET 请求获取图片
    const response = await fetch(item.imgUrl, {
      method: 'GET',
      mode: 'cors', // 确保跨域请求被正确处理
      cache: 'default',
    })
    // 检查响应状态码，确保请求成功
    if (!response.ok)
      throw new Error(`HTTP error! Status: ${response.status}`)

    // 读取 Blob 数据
    const blob = await response.blob()

    // 创建一个新的a标签
    const link = document.createElement('a')
    link.href = URL.createObjectURL(blob)
    link.download = item.imgName // 设置下载的文件名
    link.style.display = 'none' // 隐藏链接

    // 将链接添加到 DOM 中
    document.body.appendChild(link)

    // 触发下载
    link.click()

    // 清理
    URL.revokeObjectURL(link.href)
    document.body.removeChild(link)
  }
  catch (error) {
    console.error('下载图片时发生错误:', error)
  }
}

function previewHandler(index: number, event: MouseEvent) {
  event.stopImmediatePropagation()
  event.stopPropagation()
  if (imageRef.value?.[index] && (imageRef.value[index] as any).src)
    // (imageRef.value?.[index] as any).mergedOnClick()
    (imageRef.value?.[index] as any).click()
}

/**
 * 检查查重状态
 */
function refresh(val?: any) {
  // delete asideVal.izsimilarity
  const checkingTaskModal = checkingTaskModalRef.value as any
  if (checkDuplicateNo.value) {
    getCheckDuplicateStatus(checkDuplicateNo.value).then((res) => {
      if (res.code === 'OK') {
        checkTaskStatus.value = res.data.status // 1.执行中 2.执行完毕
        // if (isRefresh.value === false) {
        //   const modal = packageModalRef.value as any
        //   modal.showModal()
        //   return
        // }

        if (
          (checkTaskStatus.value === 2 || checkTaskStatus.value === 3)
          && isRefresh.value
        ) {
          configStore.setTimeNum(100)
          checkingTaskModal.closeModal()
          isRefresh.value = false
          if (checkTaskStatus.value === 2)
            message.success('任务执行完毕，正在刷新数据...')
          else message.error('查询异常')

          if (timer.value)
            clearInterval(timer.value)

          reset()
          loadMore()
          configStore.setTimeNum(0)
        }
        // else if (checkTaskStatus.value === 1) {
        //   return;
        // }
      }
    })
  }
}
/**
 * 取消查重任务
 */
function cancel() {
  if (checkTaskStatus.value === 1) {
    removeCheckDuplicate(checkDuplicateNo.value).then((res) => {
      if (res.code === 'OK') {
        checkDuplicateNo.value = ''
        checkTaskStatus.value = null
        message.success('查重任务取消成功')
      }
    })
  }
}

function renderIcon(icon: Component) {
  return () => {
    return h(NIcon, null, {
      default: () => h(icon),
    })
  }
}

const dropdownOptions = ref([
  {
    label: '导入任务数据',
    key: 'profile',
    icon: renderIcon(UploadIcon),
  },
  {
    label: '导出任务数据',
    key: 'editProfile',
    icon: renderIcon(DownloadIcon),
  },
  {
    label: '查看导入记录',
    key: 'logout',
    icon: renderIcon(EyeOutlineIcon),
  },
])

function finish() {
  console.log('finish')
}

function scroll() {

}

const masonryRef = ref(null)

defineExpose({
  showLoginSuccessModal,
  closeLoginSuccessModal,
})
</script>

<template>
  <div class="wrapper">
    <div class="wrapper-header">
      <div class="left">
        <SvgIcon size="32" name="magnifying" />
        <span class="font" style="margin-left: 19.2px">AI一键查重</span>
      </div>
      <div class="flex-btn-icon">
        <SvgIcon
          v-show="checkTaskStatus !== 2"
          style="cursor: pointer"
          size="105"
          name="yijianchachong"
          @click="oneCheck"
        />
        <SvgIcon
          v-show="checkTaskStatus === 2"
          style="cursor: pointer"
          size="105"
          name="shengchengrenwubao"
          @click="showAddPackage"
        />
        <n-dropdown trigger="hover" placement="bottom-start" :options="dropdownOptions">
          <span class="expand-icon">
            <Icon style="position: relative; top: 2px">
              <EllipsisHorizontal style="color: #507afd" />
            </Icon>
          </span>
        </n-dropdown>
      </div>
    </div>
    <div class="wrapper-content" style="margin-bottom: 16px;">
      <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> -->
              <span>视图</span>
              <SvgIcon class="gap" name="arrow-botton" size="16" />
            </div>
          </n-popselect>
          <div
            style="margin-left: 15px; cursor: pointer; color: #323233"
            @click="sortHandler('fromuptime')"
          >
            <span>时间排序</span>
            <SvgIcon style="margin-left: 8px" name="sort" size="16" />
          </div>
          <div
            style="margin-left: 15px; cursor: pointer; color: #323233"
            @click="sortHandler('pictureResult')"
          >
            <span>相似度排序</span>
            <SvgIcon style="margin-left: 8px" name="sort" size="16" />
          </div>
        </div>
        <span style="font-size: 16px; color: #333">共
          <span style="color: #507afd; font-weight: 500">{{ totalCount }}</span> 项</span>
      </div>

      <!-- <n-spin :show="loading"> -->
      <div v-if="viewMode != 'masonry'" ref="el" class="scroll" :style="listStyle">
        <div class="grid" :style="{ 'grid-template-columns': `repeat(${cols}, 182px)` }">
          <div
            v-for="(item, index) in listData"
            :key="item.id"
            :style="{ height: `${gridHeight}px` }"
            class="grid-item"
          >
            <img
              :key="item.id"
              v-lazy="item.thumburl"
              :class="{
                'img-fit': viewMode === 'horizontalVersion',
                'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
              }"
              :style="{ height: `${viewMode === 'masonry' ? `${item.calHeight}px` : `${gridHeight - 25}px`}` }"
              class="img"
              alt="加载错误"
            >

            <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>
              <div class="left">
                <n-avatar
                  :src="(item.uphead && getAvatar(item.uphead)) || defaultAvatar"
                  class="avatar"
                  round
                />
                <span>{{ item.upname }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div v-if="viewMode === 'masonry'" ref="el" class="scroll" :style="listStyle">
        <waterfall ref="waterfallRef" :col="cols" :data="listData" :gutter-width="10" @finish="finish">
          <div
            v-for="(item, index) in listData"
            :key="item.id"
            class="grid-item"
          >
            <img
              :key="item.id"
              v-lazy="item.thumburl"
              :class="{
                'img-fit': viewMode === 'horizontalVersion',
                'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
              }"
              :style="{ height: `${item.calHeight}px` }"
              class="img"
              alt="加载错误"
            >

            <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>
              <div class="left">
                <n-avatar
                  :src="(item.uphead && getAvatar(item.uphead)) || defaultAvatar"
                  class="avatar"
                  round
                />
                <span>{{ item.upname }}</span>
              </div>
            </div>
          </div>
        </waterfall>
      </div>
      <!-- </n-spin> -->
    </div>
    <PackageSettingsModal ref="packageModalRef" @commit="commitHandler" />
    <GeneratePackageModal ref="generateModalRef" />
    <QueryRepeatedTasksModal
      ref="queryRepeatedTasksModalRef"
      @close-callback="tasksLoadingCloseCallback"
    />
    <LoginSuccessModal ref="LoginSuccessModalRef" />
    <FinishPackageModal :id="packageIdRef" ref="finishPackageModal" />
    <CheckingTaskModal ref="checkingTaskModalRef" @refresh="refresh" @cancel="cancel" />
    <!-- <div class="close_box" v-show="showClose" @click="showClose = false">
      <SvgIcon size="24" name="close-none-border" />
    </div> -->
  </div>
</template>

<style lang="less" scoped>
.wrapper {
  display: flex;
  flex: 1;
  flex-direction: column;
  box-sizing: border-box;
  margin-left: 16px;
  width: 100%;

  &-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: #fff;
    padding: 0px 16px 0px 15px;
    box-sizing: border-box;
    height: 64px;
    border: 1px solid rgb(239, 239, 245);
    border-radius: 3px;
    width: 100%;

    .left {
      display: flex;
      align-items: center;
    }

    .font {
      font-size: 18px;
      font-weight: bold;
      color: #333333;
      line-height: 25px;
      width: 89px;
      height: 25px;
      white-space: nowrap;
      // margin-left: 12px;
    }
  }

  &-content {
    flex: 1;
    padding: 16px 16px 0px 16px;
    margin-top: 16px;
    background: #fff;
    border-radius: 3px;
    border: 1px solid rgb(239, 239, 245);

    .form {
      display: flex;
      align-items: center;
      font-size: 14px;
      padding-bottom: 16px;
    }

    .grid{
      grid-gap: 10px 10px;
    }

    .img {
      width: 182px;
      max-width: 182px;
      border-radius: 7px;
      display: block;
      opacity: 1 !important;
      // height: calc(100% - 25px);
    }

    .img-fit {
      width: 182px;
      overflow: hidden;
    }

    .img-full {
      width: 182px;
      overflow: hidden;

      ::v-deep(img) {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }
    }

    .info {
      display: flex;
      justify-content: space-between;
      margin-top: 4px;
      position: relative;
      color: #666666;
      font-size: 16px;

      .left {
        display: flex;
        align-items: center;
      }

      .right {
        display: flex;
        align-items: center;
      }

      .avatar {
        width: 20px;
        height: 20px;
        margin-right: 5px;
      }
    }

    .dropdown {
      display: flex;
      flex-direction: row;
      align-items: center;
      margin-right: 24px;
      color: #323233;

      .gap {
        margin-left: 5px;
      }
    }

    .grid-item {
      width: 182px;
      border-radius: 7px;
      margin-bottom: 10px;
      overflow-x: visible;
      position: relative;
      transition: 0.5s;
      margin: 0 6px 10px 6px;

      .tag-status {
        width: 46px;
        height: 22px;
        position: absolute;
        left: -3px;
        top: 10px;
      }

      .glass {
        position: absolute;
        display: none !important;
        background-color: #fff;
        border-radius: 6px;
        padding: 3px;
        top: 10px;
        right: 10px;
        width: 22px;
        height: 22px;
      }

      .footer {
        display: none;
        width: 100%;
        height: 40px;
        position: absolute;
        top: -45px;
        justify-content: space-between;
        align-items: center;
        padding: 0 10px;
        background: rgba(0, 0, 0, 0.35);
        border-radius: 7px;

        .img-name {
          // width: 70%;
          font-size: 12px;
          width: 115px;
          height: 20px;
          color: #fff;
          /* 设置文本溢出时的样式为省略号 */
          text-overflow: ellipsis;
          /* 隐藏超出容器的文本 */
          overflow: hidden;
          /* 确保文本不换行 */
          white-space: nowrap;
        }

        .icon-wrap {
          width: 22px;
          height: 22px;
          line-height: 22px;
          text-align: center;
          background-color: #fff;
          border-radius: 6px;
        }
      }

      &:hover {
        .percent {
          display: none;
        }

        .glass {
          display: block !important;
        }

        .info .footer {
          display: flex;
        }
      }
    }

    .percent {
      position: absolute;
      text-align: center;
      z-index: 3;
      right: 10px;
      top: -8px;
      color: #fff;

      .val {
        position: absolute;
        left: 0;
        top: 0;
        display: block;
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 12px;
        font-family: PingFang SC, PingFang SC-Semibold;
        font-weight: Semibold;
        text-align: left;
        color: #ffffff;
        line-height: 24px;
      }
    }

    .scroll {
      overflow-y: scroll;
      // 滚动条整体部分
      &::-webkit-scrollbar {
        width: 6px;
        height: 6px;
        background: #f1f1f1;
        visibility: hidden;
      }
      /* 定义滚动条轨道的样式 */
      &::-webkit-scrollbar-track {
        background-color: #e1e1e1;
        border-radius: 10px; /* 圆角 */
        visibility: hidden;
      }
      &:hover {
        &::-webkit-scrollbar {
          visibility: visible;
        }
        &::-webkit-scrollbar-track {
          visibility: visible;
        }
        &::-webkit-scrollbar-thumb {
          visibility: visible;
        }
      }
      /* 定义滚动条滑块的样式 */
      &::-webkit-scrollbar-thumb {
        background-color: #888;
        border-radius: 10px; /* 圆角 */
        visibility: hidden;
      }

      /* 滑块hover时的样式 */
      &::-webkit-scrollbar-thumb:hover {
        background-color: #555;
      }
    }
  }
  .flex-btn-icon {
    display: flex;
    align-items: center;
  }

  .expand-icon {
    display: block;
    margin-left: 10px;
    width: 30px;
    height: 30px;
    line-height: 30px;
    background: linear-gradient(
      144deg,
      rgba(115, 167, 249, 0.1) 0%,
      rgba(62, 110, 241, 0.1) 96%
    );
    border-radius: 8px;
    text-align: center;
  }
}
.close_box {
  position: absolute;
  right: 10%;
  top: 20%;
  z-index: 10000000000000000000;
}
</style>
