index.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <template>
  2. <div>
  3. <a-form-item class="mb-0">
  4. <a-radio-group v-decorator="decorators.type" :disabled="disabled" @change="handleTypeChange">
  5. <a-radio-button
  6. v-for="item of types"
  7. :key="item.key"
  8. :value="item.key">{{ item.label }}</a-radio-button>
  9. </a-radio-group>
  10. </a-form-item>
  11. <a-form-item class="mb-0" v-if="isBind">
  12. <div slot="extra">{{$t('compute.text_188', [_max])}}<help-link :href="href">{{$t('compute.text_189')}}</help-link>
  13. </div>
  14. <base-select
  15. remote
  16. class="w-50 pr-1"
  17. v-decorator="secgroupDecorator"
  18. resource="secgroups"
  19. :params="params"
  20. :showSync="true"
  21. :select-props="{ allowClear: true, placeholder: $t('compute.text_190'), mode: 'multiple' }" />
  22. </a-form-item>
  23. </div>
  24. </template>
  25. <script>
  26. import * as R from 'ramda'
  27. import { SECGROUP_OPTIONS_MAP } from '@Compute/constants'
  28. import { HYPERVISORS_MAP } from '@/constants'
  29. export default {
  30. name: 'SecgroupConfig',
  31. props: {
  32. decorators: {
  33. type: Object,
  34. required: true,
  35. validator: val => val.type && val.secgroup,
  36. },
  37. secgroupParams: {
  38. type: Object,
  39. default: () => ({}),
  40. },
  41. form: {
  42. type: Object,
  43. },
  44. isSnapshotImageType: { // 表单的镜像类型是否是主机快照
  45. type: Boolean,
  46. default: false,
  47. },
  48. hypervisor: {
  49. type: String,
  50. default: HYPERVISORS_MAP.kvm.key,
  51. },
  52. max: {
  53. type: Number,
  54. },
  55. showSecgroupBind: {
  56. type: Boolean,
  57. default: true,
  58. },
  59. },
  60. data () {
  61. // const concatRules = (k, l, r) => k === 'rules' ? R.concat(l, r) : r
  62. // const secgroupDecMsg = R.mergeDeepWithKey(concatRules,
  63. // (this.decorators.secgroup[1] || {}),
  64. // { rules: [{ validator: this.validateSecgroups }] },
  65. // )
  66. return {
  67. isBind: this.decorators.type[1].initialValue === SECGROUP_OPTIONS_MAP.bind.key,
  68. loading: false,
  69. disabled: false,
  70. // secgroupDecorator: [
  71. // this.decorators.secgroup[0],
  72. // this.secgroupDecMsg,
  73. // ],
  74. }
  75. },
  76. computed: {
  77. types () {
  78. const types = { ...SECGROUP_OPTIONS_MAP }
  79. if (this.isInCloudSphere || !this.showSecgroupBind) {
  80. delete types.bind
  81. }
  82. return types
  83. },
  84. params () {
  85. const params = {
  86. limit: 20,
  87. scope: this.$store.getters.scope,
  88. ...this.secgroupParams,
  89. }
  90. if (this.secgroupParams.project_domain) delete params.scope
  91. return params
  92. },
  93. href () {
  94. const url = this.$router.resolve('/secgroup')
  95. return url.href
  96. },
  97. isInCloudSphere () {
  98. return this.hypervisor.toLowerCase() === HYPERVISORS_MAP.incloudsphere.hypervisor.toLowerCase()
  99. },
  100. isAzure () {
  101. return this.hypervisor.toLowerCase() === HYPERVISORS_MAP.azure.hypervisor.toLowerCase()
  102. },
  103. isUCloud () {
  104. return this.hypervisor.toLowerCase() === HYPERVISORS_MAP.ucloud.hypervisor.toLowerCase()
  105. },
  106. isZstack () {
  107. return this.hypervisor.toLowerCase() === HYPERVISORS_MAP.zstack.hypervisor.toLowerCase()
  108. },
  109. _max () {
  110. if (this.max) {
  111. return this.max
  112. }
  113. return (this.isAzure || this.isUCloud || this.isZstack) ? 1 : 5
  114. },
  115. secgroupDecorator () {
  116. const concatRules = (k, l, r) => k === 'rules' ? R.concat(l, r) : r
  117. const obj = R.mergeDeepWithKey(concatRules,
  118. (this.decorators.secgroup[1] || {}),
  119. {
  120. rules: [{ validator: this.validateSecgroups }],
  121. initialValue: this.decorators.secgroup[1].initialValue || [],
  122. },
  123. )
  124. if (obj.rules.length > 1) {
  125. obj.validateFirst = true
  126. }
  127. const arr = [
  128. this.decorators.secgroup[0],
  129. obj,
  130. ]
  131. return arr
  132. },
  133. },
  134. watch: {
  135. isSnapshotImageType (val) {
  136. if (val) {
  137. this.disabled = true
  138. this.form.fc.setFieldsValue({
  139. [this.decorators.type[0]]: SECGROUP_OPTIONS_MAP.none.key,
  140. })
  141. } else {
  142. this.disabled = false
  143. }
  144. },
  145. hypervisor () {
  146. if (this.form && this.form.fc) {
  147. this.form.fc.validateFields([this.decorators.secgroup[0]])
  148. }
  149. },
  150. types (val) {
  151. if (!val.bind && this.form.fd && this.form.fd[this.decorators.type[0]] === 'bind' && this.form && this.form.fc) {
  152. this.form.fc.setFieldsValue({
  153. [this.decorators.type[0]]: 'default',
  154. })
  155. this.isBind = false
  156. }
  157. },
  158. },
  159. methods: {
  160. validateSecgroups (rule, value, callback) {
  161. const max = this._max
  162. const maxError = this.$t('compute.text_191', [max])
  163. const minError = this.$t('compute.text_192')
  164. if (value.length > max) {
  165. return callback(maxError)
  166. }
  167. if (value.length < 1) {
  168. return callback(minError)
  169. }
  170. return callback()
  171. },
  172. handleTypeChange (e) {
  173. this.isBind = (e.target.value === SECGROUP_OPTIONS_MAP.bind.key)
  174. },
  175. },
  176. }
  177. </script>