ImageTaskCard.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <template>
  2. <el-card body-class="" class="image-card">
  3. <div class="image-operation">
  4. <div>
  5. <el-button type="primary" text bg v-if="imageDetail?.status === 10">生成中</el-button>
  6. <el-button text bg v-else-if="imageDetail?.status === 20">已完成</el-button>
  7. <el-button type="danger" text bg v-else-if="imageDetail?.status === 30">异常</el-button>
  8. </div>
  9. <!-- TODO @fan:1)按钮要不调整成详情、下载、再次生成、删除?;2)如果是再次生成,就把当前的参数填写到左侧的框框里? -->
  10. <div>
  11. <el-button class="btn" text :icon="Download"
  12. @click="handlerBtnClick('download', imageDetail)"/>
  13. <el-button class="btn" text :icon="Delete" @click="handlerBtnClick('delete', imageDetail)"/>
  14. <el-button class="btn" text :icon="More" @click="handlerBtnClick('more', imageDetail)"/>
  15. </div>
  16. </div>
  17. <div class="image-wrapper" ref="cardImageRef">
  18. <!-- TODO @fan:要不加个点击,大图预览? -->
  19. <img class="image" :src="imageDetail?.picUrl"/>
  20. <div v-if="imageDetail?.status === 30">{{imageDetail?.errorMessage}}</div>
  21. </div>
  22. </el-card>
  23. </template>
  24. <script setup lang="ts">
  25. import {Delete, Download, More} from "@element-plus/icons-vue";
  26. import {ImageDetailVO} from "@/api/ai/image";
  27. import {PropType} from "vue";
  28. import {ElLoading} from "element-plus";
  29. const cardImageRef = ref<any>() // 卡片 image ref
  30. const cardImageLoadingInstance = ref<any>() // 卡片 image ref
  31. const props = defineProps({
  32. imageDetail: {
  33. type: Object as PropType<ImageDetailVO>,
  34. require: true
  35. }
  36. })
  37. /**
  38. * 按钮 - 点击事件
  39. */
  40. const handlerBtnClick = async (type, imageDetail: ImageDetailVO) => {
  41. emits('onBtnClick', type, imageDetail)
  42. }
  43. const handlerLoading = async (status: number) => {
  44. // TODO @fan:这个搞成 Loading 组件,然后通过数据驱动,这样搞可以哇?
  45. if (status === 10) {
  46. cardImageLoadingInstance.value = ElLoading.service({
  47. target: cardImageRef.value,
  48. text: '生成中...'
  49. })
  50. } else {
  51. if (cardImageLoadingInstance.value) {
  52. cardImageLoadingInstance.value.close();
  53. cardImageLoadingInstance.value = null;
  54. }
  55. }
  56. }
  57. // watch
  58. const { imageDetail } = toRefs(props)
  59. watch(imageDetail, async (newVal, oldVal) => {
  60. await handlerLoading(newVal.status as string)
  61. })
  62. // emits
  63. const emits = defineEmits(['onBtnClick'])
  64. //
  65. onMounted(async () => {
  66. await handlerLoading(props.imageDetail.status as string)
  67. })
  68. </script>
  69. <style scoped lang="scss">
  70. .image-card {
  71. width: 320px;
  72. height: auto;
  73. border-radius: 10px;
  74. position: relative;
  75. display: flex;
  76. flex-direction: column;
  77. .image-operation {
  78. display: flex;
  79. flex-direction: row;
  80. justify-content: space-between;
  81. .btn {
  82. //border: 1px solid red;
  83. padding: 10px;
  84. margin: 0;
  85. }
  86. }
  87. .image-wrapper {
  88. overflow: hidden;
  89. margin-top: 20px;
  90. height: 280px;
  91. flex: 1;
  92. .image {
  93. width: 100%;
  94. border-radius: 10px;
  95. }
  96. }
  97. }
  98. </style>