DiskOptionsUpdate.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <template>
  2. <base-dialog @cancel="cancelDialog">
  3. <div slot="header">{{params.title}}</div>
  4. <div slot="body">
  5. <a-form
  6. :form="form.fc">
  7. <a-form-item v-if="isConvert" :label="$t('compute.text_327')" v-bind="formItemLayout">
  8. <a-input v-decorator="decorators.name" v-if="!isDisabled" class="workspace-prefix-wrapper">
  9. <span class="workspace-prefix" slot="prefix">{{prefix}}</span>
  10. </a-input>
  11. <a-input v-else :disabled="isDisabled" v-decorator="decorators.name" />
  12. <template #extra v-if="!isDisabled">
  13. {{$t('compute.text_1361', ['/opt/cloud/workspace'])}}
  14. </template>
  15. </a-form-item>
  16. <a-form-item v-else :label="$t('compute.text_327')" v-bind="formItemLayout">
  17. <a-input v-decorator="decorators.name" :disabled="isDisabled" />
  18. <template #extra v-if="!isDisabled">
  19. {{$t('compute.mount_point_tips', ['/opt/cloud/workspace'])}}
  20. </template>
  21. </a-form-item>
  22. <a-form-item :label="$t('compute.text_328')" v-bind="formItemLayout" v-if="!isDisabled">
  23. <a-select v-decorator="decorators.format" :placeholder="$t('compute.text_329')">
  24. <a-select-option value="ext4">ext4</a-select-option>
  25. <a-select-option value="xfs">xfs</a-select-option>
  26. <a-select-option value="ntfs">ntfs</a-select-option>
  27. <a-select-option value="swap">swap</a-select-option>
  28. </a-select>
  29. </a-form-item>
  30. <a-form-item :label="$t('compute.text_330')" v-bind="formItemLayout">
  31. <a-radio-group v-decorator="decorators.method" @change="handleMethodChange">
  32. <a-radio value="autoextend" v-show="this.params.item.remainder !== 0">{{$t('compute.text_331')}}</a-radio>
  33. <a-radio value="manual">{{$t('compute.text_332')}}</a-radio>
  34. </a-radio-group>
  35. </a-form-item>
  36. <a-form-item v-bind="tailFormItemLayout" v-if="isManual">
  37. <a-tooltip :title="coutTitle">
  38. <a-input-number
  39. v-decorator="decorators.size"
  40. :min="1"
  41. :max="maxNumber"
  42. :formatter="value => `${value}G`"
  43. :parser="value => value.replace('G', '')" />
  44. </a-tooltip>
  45. </a-form-item>
  46. </a-form>
  47. </div>
  48. <div slot="footer">
  49. <a-button type="primary" @click="handleConfirm" :loading="loading">{{ $t('dialog.ok') }}</a-button>
  50. <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
  51. </div>
  52. </base-dialog>
  53. </template>
  54. <script>
  55. import DialogMixin from '@/mixins/dialog'
  56. import WindowsMixin from '@/mixins/windows'
  57. export default {
  58. name: 'DiskOptionsUpdateDialog',
  59. mixins: [DialogMixin, WindowsMixin],
  60. data () {
  61. const prefix = '/opt/cloud/workspace'
  62. const nameValue = this.params.selectedArea.name.replace(prefix, '')
  63. const isConvert = this.params.type === 'Convert'
  64. const initNameValue = this.params.title === this.$t('compute.text_318') ? this.params.selectedArea.name : '/opt/cloud/workspace'
  65. const initConvertNameValue = this.params.title === this.$t('compute.text_318') ? nameValue : ''
  66. return {
  67. loading: false,
  68. prefix,
  69. formItemLayout: {
  70. wrapperCol: {
  71. span: 16,
  72. },
  73. labelCol: {
  74. span: 4,
  75. },
  76. },
  77. tailFormItemLayout: {
  78. wrapperCol: {
  79. sm: {
  80. span: 8,
  81. offset: 3,
  82. },
  83. },
  84. },
  85. form: {
  86. fc: this.$form.createForm(this),
  87. },
  88. decorators: {
  89. name: [
  90. 'name',
  91. {
  92. initialValue: isConvert ? initConvertNameValue : initNameValue,
  93. validateTrigger: ['change', 'blur'],
  94. validateFirst: true,
  95. rules: [
  96. { required: !isConvert, message: this.$t('compute.text_333') },
  97. { validator: isConvert ? this.checkConvertMountpoint : this.checkMountpoint },
  98. ],
  99. },
  100. ],
  101. format: [
  102. 'format',
  103. {
  104. initialValue: this.params.title === this.$t('compute.text_318') ? this.params.selectedArea.format : 'ext4',
  105. rules: [
  106. { required: true, message: this.$t('compute.text_329') },
  107. ],
  108. },
  109. ],
  110. method: [
  111. 'method',
  112. {
  113. initialValue: this.params.title === this.$t('compute.text_317') ? 'autoextend' : 'manual',
  114. rules: [
  115. { required: true },
  116. ],
  117. },
  118. ],
  119. size: [
  120. 'size',
  121. {
  122. initialValue: this.params.title === this.$t('compute.text_318') ? this.params.selectedArea.size : 1,
  123. rules: [
  124. { required: true },
  125. ],
  126. },
  127. ],
  128. },
  129. isManual: this.params.title !== this.$t('compute.text_317'),
  130. }
  131. },
  132. computed: {
  133. maxNumber () {
  134. if (this.params.title === this.$t('compute.text_318')) {
  135. return this.params.item.remainder + this.params.selectedArea.size
  136. }
  137. return this.params.item.remainder
  138. },
  139. coutTitle () {
  140. if (this.params.title === this.$t('compute.text_318')) {
  141. return this.$t('compute.text_334', [this.params.item.remainder + this.params.selectedArea.size])
  142. }
  143. return this.$t('compute.text_334', [this.params.item.remainder])
  144. },
  145. selectedAreaName () {
  146. return this.params.selectedArea.name.replace(this.prefix, '')
  147. },
  148. isConvert () {
  149. return this.params.type === 'Convert'
  150. },
  151. isSystem () {
  152. return this.selectedAreaName === this.$t('compute.text_316')
  153. },
  154. isDisabled () {
  155. if (this.params.title === this.$t('compute.text_318') && this.isSystem) {
  156. return true
  157. }
  158. return false
  159. },
  160. },
  161. methods: {
  162. handleMethodChange (e) {
  163. if (e.target.value === 'autoextend') {
  164. this.isManual = false
  165. } else {
  166. this.isManual = true
  167. }
  168. },
  169. checkConvertMountpoint (rule, value, callback) {
  170. const pathReg = new RegExp('^(/[^/ ]*)+')
  171. const checkName = this.params.nameArr.filter(item => item.name === `${this.prefix}${value}`)
  172. if (this.params.title === this.$t('compute.text_317') && checkName.length > 0) {
  173. callback(new Error(this.$t('compute.text_337')))
  174. }
  175. if (value) {
  176. if (!pathReg.test(value)) {
  177. callback(new Error(this.$t('compute.text_335')))
  178. }
  179. const checkName = this.params.nameArr.filter(item => item.name === `${this.prefix}${value}`)
  180. if (this.params.title === this.$t('compute.text_318') && checkName.length > 1) {
  181. callback(new Error(this.$t('compute.text_337')))
  182. }
  183. }
  184. callback()
  185. },
  186. checkMountpoint (rule, value, callback) {
  187. const pathReg = new RegExp('^(/[^/ ]*)+')
  188. if (!pathReg.test(value)) {
  189. callback(new Error(this.$t('compute.text_335')))
  190. }
  191. const checkName = this.params.nameArr.filter(item => item.name === value)
  192. if (this.params.title === this.$t('compute.text_318') && checkName.length > 1) {
  193. callback(new Error(this.$t('compute.text_337')))
  194. }
  195. if (this.params.title === this.$t('compute.text_317') && checkName.length > 0) {
  196. callback(new Error(this.$t('compute.text_337')))
  197. }
  198. callback()
  199. },
  200. validateForm () {
  201. return new Promise((resolve, reject) => {
  202. this.form.fc.validateFields((err, values) => {
  203. if (!err) {
  204. resolve(values)
  205. } else {
  206. reject(err)
  207. }
  208. })
  209. })
  210. },
  211. async handleConfirm () {
  212. let values = await this.validateForm()
  213. if (values.method === 'autoextend' && this.params.title === this.$t('compute.text_317')) {
  214. values = {
  215. ...values,
  216. size: this.params.item.remainder,
  217. }
  218. }
  219. if (values.method === 'autoextend' && this.params.title === this.$t('compute.text_318')) {
  220. values = {
  221. ...values,
  222. size: this.params.item.remainder + this.params.selectedArea.size,
  223. }
  224. }
  225. if (this.isConvert) {
  226. values.name = this.isDisabled ? values.name : `${this.prefix}${values.name}`
  227. }
  228. this.params.updateData(values)
  229. this.cancelDialog()
  230. },
  231. },
  232. }
  233. </script>
  234. <style lang="scss">
  235. .ant-input-affix-wrapper.workspace-prefix-wrapper {
  236. .ant-input:not(:first-child) {
  237. padding-left: 143px;
  238. }
  239. }
  240. </style>