ImageTask.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <template>
  2. <el-card class="dr-task" body-class="task-card" shadow="never">
  3. <template #header>绘画任务</template>
  4. <ImageTaskCard
  5. v-for="image in imageList"
  6. :key="image"
  7. :image-detail="image"
  8. @on-btn-click="handlerImageBtnClick" />
  9. </el-card>
  10. <!-- 图片 detail 抽屉 -->
  11. <ImageDetailDrawer
  12. :show="showTaskDetail"
  13. @handler-drawer-close="handlerDrawerClose"
  14. />
  15. </template>
  16. <script setup lang="ts">
  17. import {ImageApi, ImageDetailVO} from '@/api/ai/image';
  18. import ImageDetailDrawer from './ImageDetailDrawer.vue'
  19. import ImageTaskCard from './ImageTaskCard.vue'
  20. import {bool} from "vue-types";
  21. const message = useMessage() // 消息弹窗
  22. const imageList = ref<ImageDetailVO[]>([]) // image 列表
  23. const imageListInterval = ref<any>() // image 列表定时器,刷新列表
  24. const showTaskDetail = ref<bool>(false) // 是否显示 task 详情
  25. /**
  26. * 图片人物 - detail
  27. */
  28. const handlerTaskDetail = async () => {
  29. showTaskDetail.value = !showTaskDetail.value
  30. }
  31. /**
  32. * 抽屉 - close
  33. */
  34. const handlerDrawerClose = async () => {
  35. showTaskDetail.value = false
  36. }
  37. /**
  38. * 任务 - detail
  39. */
  40. const handlerDrawerOpen = async () => {
  41. showTaskDetail.value = true
  42. }
  43. /**
  44. * 获取 - image 列表
  45. */
  46. const getImageList = async () => {
  47. const { list } = await ImageApi.getImageList({pageNo: 1, pageSize: 20})
  48. imageList.value = list
  49. }
  50. /**
  51. * 图片 - btn click
  52. */
  53. const handlerImageBtnClick = async (type, imageDetail: ImageDetailVO) => {
  54. if (type === 'more') {
  55. await handlerDrawerOpen()
  56. } else if (type === 'delete') {
  57. await message.confirm(`是否删除照片?`)
  58. await ImageApi.deleteImage(imageDetail.id)
  59. await getImageList()
  60. await message.success("删除成功!")
  61. } else if (type === 'download') {
  62. downloadImage(imageDetail.picUrl)
  63. }
  64. }
  65. /**
  66. * 下载 - image
  67. */
  68. const downloadImage = async (imageUrl) => {
  69. const image = new Image()
  70. image.setAttribute('crossOrigin', 'anonymous')
  71. image.src = imageUrl
  72. image.onload = () => {
  73. const canvas = document.createElement('canvas')
  74. canvas.width = image.width
  75. canvas.height = image.height
  76. const ctx = canvas.getContext('2d')
  77. ctx.drawImage(image, 0, 0, image.width, image.height)
  78. const url = canvas.toDataURL('image/png')
  79. const a = document.createElement('a')
  80. a.href = url
  81. a.download = 'image.png'
  82. a.click()
  83. }
  84. }
  85. //
  86. defineExpose({getImageList})
  87. //
  88. onMounted(async () => {
  89. // 获取 image 列表
  90. await getImageList()
  91. // 自动刷新 image 列表
  92. imageListInterval.value = setInterval(async () => {
  93. await getImageList()
  94. }, 3000)
  95. })
  96. //
  97. onUnmounted(async () => {
  98. })
  99. </script>
  100. <style lang="scss">
  101. .task-card {
  102. display: flex;
  103. flex-direction: row;
  104. flex-wrap: wrap;
  105. height: 100%;
  106. overflow: auto;
  107. >div {
  108. margin-right: 20px;
  109. margin-bottom: 20px;
  110. }
  111. }
  112. </style>
  113. <style scoped lang="scss">
  114. .dr-task {
  115. width: 100%;
  116. height: 100%;
  117. }
  118. </style>