Create.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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 :label="$t('network.text_291')" v-bind="formItemLayout" v-if="params.type === 'create'">
  8. <a-input v-decorator="decorators.name" :placeholder="$t('network.text_44')" />
  9. </a-form-item>
  10. <a-form-item v-bind="formItemLayout">
  11. <span slot="label">{{$t('network.text_292')}}<a-tooltip>
  12. <div slot="title">{{$t('network.text_293')}}<br />{{$t('network.text_294')}}<br />{{$t('network.text_295')}}<br />{{$t('network.text_296')}}<br />{{$t('network.text_297')}}</div>
  13. <a-icon type="info-circle" />
  14. </a-tooltip>
  15. </span>
  16. <a-textarea v-decorator="decorators.acl_entries"
  17. :placeholder="$t('network.text_298')"
  18. rows="8" />
  19. </a-form-item>
  20. </a-form>
  21. </div>
  22. <div slot="footer">
  23. <a-button type="primary" @click="handleConfirm" :loading="loading">{{ $t('dialog.ok') }}</a-button>
  24. <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
  25. </div>
  26. </base-dialog>
  27. </template>
  28. <script>
  29. import { REGEXP } from '@/utils/validate'
  30. import DialogMixin from '@/mixins/dialog'
  31. import WindowsMixin from '@/mixins/windows'
  32. const ipsValidate = (rule, value, cb) => {
  33. const pureIps = value.split(/[\s\n]/).filter(v => !!v).map(str => str.trim())
  34. const noRepeatIps = Array.from(new Set(pureIps))
  35. const isRepeat = noRepeatIps.length !== pureIps.length
  36. let descValid = true
  37. const valid = pureIps.every(ipComment => {
  38. const [ip, comment = ''] = ipComment.split('|').filter(v => !!v && v !== '|')
  39. if (comment.length > 16) descValid = false
  40. if (ip.includes('/')) {
  41. let [ipStr, max] = ip.split('/')
  42. max = Number(max)
  43. if (REGEXP.IPv4.regexp.test(ipStr) && max < 256) {
  44. const ipStrArr = ipStr.split('.')
  45. const ipStrLast = ipStrArr[ipStrArr.length - 1]
  46. if (+ipStrLast >= 0 && +ipStrLast < max) {
  47. return true
  48. }
  49. return false
  50. }
  51. } else {
  52. if (REGEXP.IPv4.regexp.test(ip)) {
  53. return true
  54. }
  55. return false
  56. }
  57. })
  58. if (valid) {
  59. if (isRepeat) {
  60. cb(new Error(this.$t('network.text_299')))
  61. } else {
  62. if (!descValid) cb(new Error(this.$t('network.text_300')))
  63. cb()
  64. }
  65. } else {
  66. cb(new Error(this.$t('network.text_301')))
  67. }
  68. }
  69. export default {
  70. name: 'LbaclsCreateDialog',
  71. mixins: [DialogMixin, WindowsMixin],
  72. data () {
  73. return {
  74. loading: false,
  75. form: {
  76. fc: this.$form.createForm(this, {
  77. onValuesChange: (props, values) => {
  78. if (values.acl_entries) {
  79. const str = values.acl_entries
  80. const cidrs = str.split(/[\s\n]/).filter(v => !!v)
  81. this.aclEntries = cidrs.map(str => {
  82. const [cidr, comment = ''] = str.split('|')
  83. return {
  84. cidr,
  85. comment,
  86. }
  87. })
  88. }
  89. },
  90. }),
  91. },
  92. decorators: {
  93. name: [
  94. 'name',
  95. {
  96. validateFirst: true,
  97. validateTrigger: ['blur'],
  98. rules: [
  99. { required: true, message: this.$t('network.text_116') },
  100. { validator: this.$validate('serverName') },
  101. ],
  102. },
  103. ],
  104. acl_entries: [
  105. 'acl_entries',
  106. {
  107. validateFirst: true,
  108. validateTrigger: ['blur'],
  109. rules: [
  110. { required: true, message: this.$t('network.text_302') },
  111. { validator: ipsValidate },
  112. ],
  113. },
  114. ],
  115. },
  116. formItemLayout: {
  117. wrapperCol: {
  118. span: 20,
  119. },
  120. labelCol: {
  121. span: 4,
  122. },
  123. },
  124. aclEntries: [],
  125. }
  126. },
  127. created () {
  128. if (this.params.type === 'update') {
  129. const initialValue = this.params.data[0].acl_entries.map(v => {
  130. if (v.comment) {
  131. return `${v.cidr}|${v.comment}`
  132. }
  133. return v.cidr
  134. }).join(`
  135. `)
  136. this.form.fc.getFieldDecorator('acl_entries', { preserve: true, initialValue })
  137. }
  138. },
  139. methods: {
  140. doCreate (data) {
  141. return this.params.onManager('create', {
  142. managerArgs: {
  143. data: {
  144. name: data.name,
  145. acl_entries: this.aclEntries,
  146. },
  147. },
  148. })
  149. },
  150. doUpdate (data) {
  151. return this.params.onManager('update', {
  152. id: this.params.data[0].id,
  153. managerArgs: {
  154. data: {
  155. name: data.name,
  156. acl_entries: this.aclEntries,
  157. },
  158. },
  159. })
  160. },
  161. async handleConfirm () {
  162. this.loading = true
  163. try {
  164. const values = await this.form.fc.validateFields()
  165. if (this.params.type === 'create') {
  166. await this.doCreate(values)
  167. } else {
  168. await this.doUpdate(values)
  169. }
  170. this.loading = false
  171. this.cancelDialog()
  172. } catch (error) {
  173. this.loading = false
  174. }
  175. },
  176. },
  177. }
  178. </script>