BackupRecovery.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <template>
  2. <base-dialog :width="900" @cancel="cancelDialog">
  3. <div slot="header">{{$t('db.text_45')}}</div>
  4. <a-form :form="form.fc" class="mt-3" slot="body">
  5. <dialog-selected-tips :name="$t('dictionary.dbinstancebackups')" :count="params.data.length" :action="params.title" />
  6. <dialog-table :data="params.data" :columns="params.columns.slice(0, 3)" />
  7. <a-form-item :label="$t('db.text_221')" v-bind="formItemLayout">
  8. <a-radio-group v-model="recoveryType">
  9. <a-tooltip>
  10. <template #title v-if="(isAliyun && !isSupportCurrentVersion) || !params.data[0].db_names">
  11. <p v-if="isAliyun && !isSupportCurrentVersion">{{$t('db.text_363')}}</p>
  12. <p v-if="!params.data[0].db_names">{{$t('db.text_364')}}</p>
  13. </template>
  14. <a-radio-button :value="0" :disabled="isDisabled">{{$t('db.text_222')}}</a-radio-button>
  15. </a-tooltip>
  16. <a-tooltip v-if="isGoogle" :title="$t('db.text_205')">
  17. <a-radio-button :disabled="true" :value="1">{{$t('db.text_223')}}</a-radio-button>
  18. </a-tooltip>
  19. <a-tooltip v-else>
  20. <template #title v-if="(isAliyun && !isSupportCurrentVersion) || !params.data[0].db_names">
  21. <p v-if="isAliyun && !isSupportCurrentVersion">{{$t('db.text_363')}}</p>
  22. <p v-if="!params.data[0].db_names">{{$t('db.text_364')}}</p>
  23. </template>
  24. <a-radio-button :value="1" :disabled="isDisabled">{{$t('db.text_223')}}</a-radio-button>
  25. </a-tooltip>
  26. <a-radio-button :value="2" v-if="['Huawei', 'Aliyun', 'HuaweiCloudStack'].indexOf(params.data[0].provider) !== -1">{{$t('db.text_365')}}</a-radio-button>
  27. </a-radio-group>
  28. <div style="width:100%">
  29. <rds-list :backupItem="backupItem" v-if="recoveryType === 1" />
  30. </div>
  31. </a-form-item>
  32. <a-form-item :label="$t('db.text_366')" v-bind="formItemLayout" v-if="recoveryType === 1 || recoveryType === 0">
  33. <a-select v-decorator="decorators.databases" mode="multiple">
  34. <a-select-option :key="item" v-for="item in dbNameOptions">{{item}}</a-select-option>
  35. </a-select>
  36. </a-form-item>
  37. <a-form-item :label="$t('db.text_367')" v-bind="formItemLayout" v-if="recoveryType === 2">
  38. <a-input v-decorator="decorators.name" />
  39. </a-form-item>
  40. </a-form>
  41. <div slot="footer">
  42. <a-button :disabled="!form.fc.getFieldsValue().dbinstance_id" :loading="loading" @click="handleConfirm" type="primary">{{ $t('dialog.ok') }}</a-button>
  43. <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
  44. </div>
  45. </base-dialog>
  46. </template>
  47. <script>
  48. import * as R from 'ramda'
  49. import RdsList from '../components/BackupRecoveryRdsList'
  50. import { HYPERVISORS_MAP } from '@/constants'
  51. import DialogMixin from '@/mixins/dialog'
  52. import WindowsMixin from '@/mixins/windows'
  53. export default {
  54. name: 'RDSBackupRecovery',
  55. components: { RdsList },
  56. mixins: [DialogMixin, WindowsMixin],
  57. data () {
  58. return {
  59. recoveryType: '',
  60. loading: false,
  61. form: {
  62. fc: this.$form.createForm(this),
  63. },
  64. formItemLayout: {
  65. wrapperCol: { span: 20 },
  66. labelCol: { span: 4 },
  67. },
  68. decorators: {
  69. databases: [
  70. 'databases',
  71. {
  72. rules: [{ required: true, message: this.$t('db.text_368') }],
  73. },
  74. ],
  75. name: [
  76. 'name',
  77. {
  78. rules: [{ required: true, message: this.$t('db.text_369') }],
  79. },
  80. ],
  81. },
  82. }
  83. },
  84. computed: {
  85. backupItem () {
  86. return this.params.data ? this.params.data[0] : {}
  87. },
  88. isGoogle () {
  89. return this.backupItem.provider === 'Google'
  90. },
  91. isAliyun () {
  92. return this.params.data[0].provider === HYPERVISORS_MAP.aliyun.provider
  93. },
  94. isSupportCurrentVersion () {
  95. const { engine, engine_version, category, storage_type } = this.params.rdsItem
  96. const supportedEngine = ['MySQL']
  97. const supportedEngineVersion = ['5.6', '5.7', '8.0']
  98. const supportedCategory = ['high_availability']
  99. const supportedStorageType = ['local_ssd']
  100. if (!R.includes(engine, supportedEngine)) return false
  101. if (!R.includes(engine_version, supportedEngineVersion)) return false
  102. if (!R.includes(category, supportedCategory)) return false
  103. if (!R.includes(storage_type, supportedStorageType)) return false
  104. return true
  105. },
  106. isDisabled () {
  107. if (!this.params.data[0].db_names) return true
  108. if (!this.isAliyun) return true
  109. if (this.isAliyun) return !this.isSupportCurrentVersion
  110. return false
  111. },
  112. dbNameOptions () {
  113. return this.params.data[0].db_names ? this.params.data[0].db_names.split(',') : []
  114. },
  115. },
  116. watch: {
  117. recoveryType: {
  118. handler (type) {
  119. this.form.fc.getFieldDecorator('dbinstance_id', { preserve: true })
  120. this.form.fc.setFieldsValue({
  121. dbinstance_id: type === 0 || type === 2 ? this.backupItem.dbinstance_id : undefined,
  122. })
  123. },
  124. immediate: true,
  125. },
  126. },
  127. provide () {
  128. return {
  129. form: this.form,
  130. }
  131. },
  132. methods: {
  133. validateForm () {
  134. return new Promise((resolve, reject) => {
  135. this.form.fc.validateFields((err, values) => {
  136. if (!err) {
  137. resolve(values)
  138. } else {
  139. reject(err)
  140. }
  141. })
  142. })
  143. },
  144. genData (values) {
  145. const ret = {}
  146. if (values.databases) {
  147. const _databases = {}
  148. values.databases.map(item => {
  149. _databases[item] = item + '_back'
  150. })
  151. ret.databases = _databases
  152. }
  153. if (values.name) ret.name = values.name
  154. if (this.recoveryType === 2) {
  155. ret.dbinstancebackup_id = this.backupItem.id
  156. } else {
  157. ret.dbinstancebackup = this.backupItem.id
  158. }
  159. return ret
  160. },
  161. async handleConfirm () {
  162. this.loading = true
  163. try {
  164. if (!this.recoveryType) {
  165. this.$message.warn(this.$t('db.text_376'))
  166. return
  167. }
  168. const values = await this.validateForm()
  169. const manager = new this.$Manager('dbinstances', 'v2')
  170. const data = this.genData(values)
  171. const id = values.dbinstance_id
  172. if (this.recoveryType === 2) {
  173. await manager.create({
  174. id,
  175. data,
  176. })
  177. } else {
  178. await manager.performAction({
  179. id,
  180. action: 'recovery',
  181. data,
  182. })
  183. }
  184. this.$bus.$emit('RdsRefresh')
  185. this.cancelDialog()
  186. } finally {
  187. this.loading = false
  188. }
  189. },
  190. },
  191. }
  192. </script>