DeleteDisk.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <template>
  2. <base-dialog @cancel="cancelDialog">
  3. <div slot="header">{{$t('compute.perform_delete')}}</div>
  4. <div slot="body">
  5. <!-- <a-alert class="mb-4" type="warning" v-if="isCeph">
  6. <div slot="message">{{$t('compute.text_419')}}</div>
  7. </a-alert> -->
  8. <dialog-selected-tips :count="params.data.length" :name="$t('dictionary.disk')" :action="this.params.title" />
  9. <dialog-table v-if="params.columns && params.columns.length" :data="params.data" :columns="params.columns.slice(0, 3)" />
  10. <a-form
  11. :form="form.fc" v-show="isShowAutoDelete">
  12. <!-- <a-form-item :label="$t('compute.text_420')" v-bind="formItemLayout">
  13. <a-switch :checkedChildren="$t('compute.text_115')" :unCheckedChildren="$t('compute.text_116')" v-decorator="decorators.autoDelete" @change="autoDeleteChangeHandle" />
  14. </a-form-item>
  15. <a-form-item v-if="!form.fd.autoDelete" v-bind="formItemLayoutWithoutLabel">
  16. {{ $t('compute.text_1310', [snapshot.list.length]) }}
  17. </a-form-item> -->
  18. <!-- 快照 -->
  19. <a-form-item v-if="deleteSnapshotLimit.show" class="mb-0">
  20. <a-tooltip>
  21. <template v-if="deleteSnapshotLimit.mustDelete" slot="title">
  22. {{deleteSnapshotLimit.tip}}
  23. </template>
  24. <a-checkbox
  25. :checked="form.fd.deleteSnapshot || (deleteSnapshotLimit.support && deleteSnapshotLimit.mustDelete)"
  26. :disabled="deleteSnapshotLimit.mustDelete"
  27. @change="deleteSnapshotChange">
  28. {{$t('compute.text_420')}}
  29. </a-checkbox>
  30. </a-tooltip>
  31. </a-form-item>
  32. </a-form>
  33. <!-- <dialog-table v-if="form.fd.autoDelete" :data="snapshot.list" :columns="snapshot.columns" /> -->
  34. </div>
  35. <div slot="footer">
  36. <a-button type="primary" @click="handleConfirm" :loading="loading">{{ $t("dialog.ok") }}</a-button>
  37. <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
  38. </div>
  39. </base-dialog>
  40. </template>
  41. <script>
  42. import * as R from 'ramda'
  43. import i18n from '@/locales'
  44. // import { DISK_TYPES, SERVER_TYPE } from '@Compute/constants'
  45. import DialogMixin from '@/mixins/dialog'
  46. import WindowsMixin from '@/mixins/windows'
  47. // import { sizestr } from '@/utils/utils'
  48. import { findPlatform } from '@/utils/common/hypervisor'
  49. // import { BRAND_MAP } from '@/constants'
  50. const canDeleteBrandList = ['OneCloud', 'VMware', 'OpenStack', 'ZStack', 'DStack', 'Aliyun', 'Huawei', 'Qcloud', 'Aws', 'Azure', 'Google', 'Ksyun']
  51. const deleteSnapshotLimit = {
  52. OneCloud: {
  53. mustDeleteOnCeph: true,
  54. tip: i18n.t('compute.disable_delete_snapshot_by_disk_tooltip', [i18n.t('common.storage.ceph')]),
  55. },
  56. Huawei: {
  57. mustDeleteOnBrand: true,
  58. tip: i18n.t('compute.disable_delete_snapshot_by_brand_on_disk_tooltip', [i18n.t('providers.huawei')]),
  59. },
  60. }
  61. export default {
  62. name: 'DiskDeleteDialog',
  63. mixins: [DialogMixin, WindowsMixin],
  64. data () {
  65. return {
  66. loading: false,
  67. snapshotList: [],
  68. form: {
  69. fc: this.$form.createForm(this),
  70. fd: {
  71. autoDelete: false,
  72. deleteSnapshot: false,
  73. },
  74. },
  75. decorators: {
  76. autoDelete: [
  77. 'autoDelete',
  78. {
  79. valuePropName: 'checked',
  80. initialValue: false,
  81. },
  82. ],
  83. deleteSnapshot: [
  84. 'deleteSnapshot',
  85. {
  86. valuePropName: 'checked',
  87. },
  88. ],
  89. },
  90. formItemLayout: {
  91. wrapperCol: {
  92. span: 21,
  93. },
  94. labelCol: {
  95. span: 3,
  96. },
  97. },
  98. formItemLayoutWithoutLabel: {
  99. wrapperCol: {
  100. span: 21,
  101. offset: 3,
  102. },
  103. },
  104. }
  105. },
  106. computed: {
  107. brand () {
  108. const brand = this.params.data[0].brand
  109. return brand
  110. },
  111. type () {
  112. return findPlatform(this.brand)
  113. },
  114. isShowAutoDelete () {
  115. return canDeleteBrandList.indexOf(this.brand) >= 0
  116. },
  117. isCeph () {
  118. const isSomeCeph = this.params.data.some((item) => {
  119. return item.storage_type === 'rbd'
  120. })
  121. return isSomeCeph
  122. },
  123. deleteSnapshotLimit () {
  124. const result = {
  125. show: true,
  126. support: true,
  127. mustDelete: false,
  128. tip: '',
  129. }
  130. if (!(this.snapshotList && this.snapshotList.length)) {
  131. result.show = false
  132. }
  133. if ((deleteSnapshotLimit[this.brand] && deleteSnapshotLimit[this.brand].mustDeleteOnBrand) || (deleteSnapshotLimit[this.brand] && deleteSnapshotLimit[this.brand].mustDeleteOnCeph && this.isCeph)) {
  134. result.mustDelete = true
  135. result.tip = deleteSnapshotLimit[this.brand].tip
  136. }
  137. return result
  138. },
  139. },
  140. created () {
  141. if (this.isShowAutoDelete) {
  142. const ids = this.params.data.map((item) => { return item.id })
  143. this.fetchSnapshotsByDiskId(ids.join(','))
  144. }
  145. },
  146. methods: {
  147. async handleConfirm () {
  148. this.loading = true
  149. try {
  150. if (this.params.ok) {
  151. await this.params.ok()
  152. } else {
  153. const ids = this.params.data.map(item => item.id)
  154. let params = {}
  155. params = {
  156. ...params,
  157. ...this.params.requestParams,
  158. }
  159. if (this.isShowAutoDelete) {
  160. if (this.form.fd.deleteSnapshot || (this.deleteSnapshotLimit.support && this.deleteSnapshotLimit.mustDelete)) {
  161. params.delete_snapshots = true
  162. }
  163. }
  164. const res = await this.params.onManager('batchDelete', {
  165. id: ids,
  166. managerArgs: { params },
  167. })
  168. const isOk = res.data.data.every(item => item.status === 200)
  169. if (isOk) {
  170. if (this.params.success && R.is(Function, this.params.success)) {
  171. this.params.success(res)
  172. }
  173. this.$message.success(this.$t('compute.text_423'))
  174. }
  175. this.cancelDialog()
  176. }
  177. } finally {
  178. this.loading = false
  179. }
  180. },
  181. autoDeleteChangeHandle (val) {
  182. this.form.fd.autoDelete = val
  183. },
  184. async fetchSnapshotsByDiskId (diskId) {
  185. const manager = new this.$Manager('snapshots')
  186. const params = {
  187. scope: this.$store.getters.scope,
  188. filter: `disk_id.in(${diskId})`,
  189. is_instance_snapshot: false,
  190. }
  191. const res = await manager.list({ params })
  192. this.snapshotList = res.data.data
  193. },
  194. deleteSnapshotChange (val) {
  195. const { checked } = val.target
  196. this.form.fd.deleteSnapshot = checked
  197. },
  198. },
  199. }
  200. </script>