ImageTaskCard.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <template>
  2. <el-card body-class="" class="image-card">
  3. <div class="image-operation">
  4. <div>
  5. <el-button type="" text bg v-if="imageDetail.status === 'in_progress'">生成中</el-button>
  6. <el-button type="" text bg v-else-if="imageDetail.status === 'fail'">已完成</el-button>
  7. <el-button type="" text bg v-else-if="imageDetail.status === 'complete'">已完成</el-button>
  8. </div>
  9. <div>
  10. <el-button class="btn" text :icon="Download"
  11. @click="handlerBtnClick('download', imageDetail)"/>
  12. <el-button class="btn" text :icon="Delete" @click="handlerBtnClick('delete', imageDetail)"/>
  13. <el-button class="btn" text :icon="More" @click="handlerBtnClick('more', imageDetail)"/>
  14. </div>
  15. </div>
  16. <div class="image-wrapper" ref="cardImageRef">
  17. <img class="image" :src="imageDetail?.picUrl"/>
  18. </div>
  19. </el-card>
  20. </template>
  21. <script setup lang="ts">
  22. import {Delete, Download, More} from "@element-plus/icons-vue";
  23. import {ImageDetailVO} from "@/api/ai/image";
  24. import {PropType} from "vue";
  25. import {ElLoading} from "element-plus";
  26. const cardImageRef = ref<any>() // 卡片 image ref
  27. const cardImageLoadingInstance = ref<any>() // 卡片 image ref
  28. const props = defineProps({
  29. imageDetail: {
  30. type: Object as PropType<ImageDetailVO>,
  31. require: true
  32. }
  33. })
  34. /**
  35. * 按钮 - 点击事件
  36. */
  37. const handlerBtnClick = async (type, imageDetail: ImageDetailVO) => {
  38. emits('onBtnClick', type, imageDetail)
  39. }
  40. const handlerLoading = async (status: string) => {
  41. if (status === 'in_progress') {
  42. cardImageLoadingInstance.value = ElLoading.service({
  43. target: cardImageRef.value,
  44. text: '生成中...'
  45. })
  46. } else {
  47. if (cardImageLoadingInstance.value) {
  48. cardImageLoadingInstance.value.close();
  49. cardImageLoadingInstance.value = null;
  50. }
  51. }
  52. }
  53. // watch
  54. const { imageDetail } = toRefs(props)
  55. watch(imageDetail, async (newVal, oldVal) => {
  56. await handlerLoading(newVal.status as string)
  57. })
  58. // emits
  59. const emits = defineEmits(['onBtnClick'])
  60. //
  61. onMounted(async () => {
  62. await handlerLoading(props.imageDetail.status as string)
  63. })
  64. </script>
  65. <style scoped lang="scss">
  66. .image-card {
  67. width: 320px;
  68. height: auto;
  69. border-radius: 10px;
  70. position: relative;
  71. display: flex;
  72. flex-direction: column;
  73. .image-operation {
  74. display: flex;
  75. flex-direction: row;
  76. justify-content: space-between;
  77. .btn {
  78. //border: 1px solid red;
  79. padding: 10px;
  80. margin: 0;
  81. }
  82. }
  83. .image-wrapper {
  84. overflow: hidden;
  85. margin-top: 20px;
  86. height: 280px;
  87. flex: 1;
  88. .image {
  89. width: 100%;
  90. border-radius: 10px;
  91. }
  92. }
  93. }
  94. </style>