LoadingDialog.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <template>
  2. <el-dialog
  3. v-model="visible"
  4. :show-close="!requesting"
  5. :close-on-click-modal="false"
  6. :close-on-press-escape="false"
  7. width="700px"
  8. custom-class="loading-dialog-EL"
  9. align-center
  10. append-to-body
  11. >
  12. <div class="loading-content">
  13. <ProgressSteps
  14. v-if="useNewProgress && progressSteps.length > 0"
  15. :steps="progressSteps"
  16. :disabled-button="disabledButton"
  17. :use-new-progress="useNewProgress"
  18. @complete="handleButtonClick"
  19. :on-open-folder="onOpenFolder"
  20. :message="message"
  21. />
  22. <div v-else class="progress-container">
  23. <div class="progress-bar">
  24. <div
  25. class="progress-inner"
  26. :style="{ width: `${progress}%` }"
  27. ></div>
  28. </div>
  29. <span class="progress-text">{{ progress.toFixed(2) }}%</span>
  30. </div>
  31. <div class="message" style="display: none">{{ message }}</div>
  32. <slot name="errList"></slot>
  33. <slot name="progressMessages"></slot>
  34. <el-button
  35. v-if="!disabledButton && !useNewProgress"
  36. :disabled="disabledButton"
  37. type="primary"
  38. class="action-button button--primary1 mar-top-20"
  39. @click="handleButtonClick"
  40. >
  41. {{ buttonText }}
  42. </el-button>
  43. <el-button
  44. v-if="message === allFailedText"
  45. type="primary"
  46. class="action-button button--primary1 mar-top-20"
  47. @click="visible = false"
  48. >
  49. {{ message }}
  50. </el-button>
  51. </div>
  52. </el-dialog>
  53. </template>
  54. <script setup lang="ts">
  55. import { ref, defineProps, defineEmits , watch } from 'vue'
  56. import ProgressSteps from './ProgressSteps.vue'
  57. import i18n from '@/locales'
  58. interface StepData {
  59. goods_art_no: string
  60. msg_type: string
  61. name: string
  62. status: string
  63. current: number
  64. total: number
  65. error: number
  66. folder?: string
  67. }
  68. interface Props {
  69. modelValue: boolean
  70. progress?: number
  71. message?: string
  72. disabledButton?: boolean
  73. buttonText?: string
  74. requesting?: boolean
  75. useNewProgress?: boolean
  76. progressSteps?: StepData[]
  77. onOpenFolder?: (folder: string) => void
  78. }
  79. const props = withDefaults(defineProps<Props>(), {
  80. progress: 0,
  81. message: '',
  82. disabledButton: true,
  83. buttonText: '',
  84. requesting: false,
  85. useNewProgress: false,
  86. progressSteps: () => [],
  87. onOpenFolder: () => {}
  88. })
  89. // 使用 i18n 默认值
  90. const defaultMessage = i18n.global.t('loadingDialog.processing')
  91. const defaultButtonText = i18n.global.t('loadingDialog.processComplete')
  92. const allFailedText = i18n.global.t('loadingDialog.allFailed')
  93. const emit = defineEmits<{
  94. (e: 'update:modelValue', value: boolean): void
  95. (e: 'button-click'): void
  96. }>()
  97. const visible = ref(props.modelValue)
  98. watch(() => visible.value, (newVal) => {
  99. emit('update:modelValue', newVal)
  100. })
  101. watch(() => props.modelValue, (newVal) => {
  102. visible.value = newVal
  103. })
  104. const handleButtonClick = () => {
  105. emit('button-click')
  106. }
  107. </script>
  108. <style lang="scss">
  109. .loading-dialog-EL{
  110. border-radius: 10px;
  111. .el-dialog__header {
  112. display: none;
  113. padding: 0;
  114. }
  115. .el-dialog__body {
  116. background-size: cover;
  117. background-position: center;
  118. background-repeat: no-repeat;
  119. padding: 20px 20px;
  120. }
  121. }
  122. </style>
  123. <style lang="scss" scoped>
  124. .loading-dialog {
  125. :deep(.el-dialog__header) {
  126. display: none;
  127. padding: 0;
  128. }
  129. :deep(.el-dialog__body) {
  130. padding:0;
  131. }
  132. }
  133. .loading-content {
  134. display: flex;
  135. flex-direction: column;
  136. align-items: center;
  137. text-align: center;
  138. }
  139. .progress-container {
  140. width: 100%;
  141. margin-bottom: 10px;
  142. display: flex;
  143. align-items: center;
  144. gap: 10px;
  145. .progress-bar {
  146. flex: 1;
  147. height: 6px;
  148. background: #E4E7ED;
  149. border-radius: 3px;
  150. overflow: hidden;
  151. .progress-inner {
  152. height: 100%;
  153. background: linear-gradient(90deg, #2FB0FF,#B863FB);
  154. border-radius: 3px;
  155. transition: width 0.3s ease;
  156. }
  157. }
  158. .progress-text {
  159. min-width: 45px;
  160. color: #606266;
  161. font-size: 14px;
  162. }
  163. }
  164. .message {
  165. color: #606266;
  166. font-size: 14px;
  167. margin-bottom: 0px;
  168. }
  169. .action-button {
  170. padding: 10px 20px;
  171. }
  172. </style>