BatchEditAttributes.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <template>
  2. <div>
  3. <a-spin :spinning="loading">
  4. <page-header :title="$t('network.text_606')" />
  5. <a-card :bordered="false" size="small">
  6. <template #title>
  7. <dialog-selected-tips :name="$t('network.text_565')" :count="networks.length" :action="$t('network.text_606')" />
  8. </template>
  9. <dialog-table :data="networks" :columns="renderColumns" />
  10. </a-card>
  11. <div class="form-wrapper">
  12. <a-form v-bind="formItemLayout" :form="form.fc" @submit.prevent="handleSubmit">
  13. <a-form-item :label="$t('network.text_551')" :validate-status="ipSubnetsValidateStatus" :help="ipSubnetsHelp" required>
  14. <ip-subnets
  15. ref="ipSubnetsRef"
  16. :decorator="decorators.ipSubnets"
  17. :hiddenAddAction="true"
  18. :hiddenDeleteAction="true"
  19. @clear-error="clearIpSubnetsError" />
  20. </a-form-item>
  21. <page-footer>
  22. <template v-slot:right>
  23. <a-button type="primary" html-type="submit" class="ml-3" :loading="submiting">{{$t('network.text_606')}}</a-button>
  24. </template>
  25. </page-footer>
  26. </a-form>
  27. </div>
  28. </a-spin>
  29. </div>
  30. </template>
  31. <script>
  32. import * as R from 'ramda'
  33. import { uuid } from '@/utils/utils'
  34. import i18n from '@/locales'
  35. import ColumnsMixin from './mixins/columns'
  36. import IpSubnets from './components/IpSubnets'
  37. const validateGateway = function (rule, value, callback) {
  38. const ipItems = value.split('.')
  39. const msg = i18n.t('network.text_591')
  40. if (ipItems[ipItems.length - 1] === '0') {
  41. callback(msg)
  42. } else {
  43. callback()
  44. }
  45. }
  46. export default {
  47. name: 'BatchEditAttributes',
  48. components: {
  49. IpSubnets,
  50. },
  51. mixins: [ColumnsMixin],
  52. data () {
  53. return {
  54. loading: false,
  55. submiting: false,
  56. networks: [],
  57. networkIds: [],
  58. ipSubnetsValidateStatus: '',
  59. ipSubnetsHelp: '',
  60. decorators: {
  61. ipSubnets: {
  62. name: i => [
  63. `name[${i}]`,
  64. {
  65. initialValue: '',
  66. validateTrigger: ['change', 'blur'],
  67. validateFirst: true,
  68. rules: [
  69. { required: true, message: this.$t('network.text_116') },
  70. { validator: this.$validate('resourceName') },
  71. ],
  72. },
  73. ],
  74. startip: i => [
  75. `startip[${i}]`,
  76. {
  77. initialValue: '',
  78. validateFirst: true,
  79. rules: [
  80. { required: true, message: this.$t('network.text_593') },
  81. { validator: this.$validate('IPv4') },
  82. ],
  83. },
  84. ],
  85. endip: i => [
  86. `endip[${i}]`,
  87. {
  88. initialValue: '',
  89. validateFirst: true,
  90. rules: [
  91. { required: true, message: this.$t('network.text_594') },
  92. { validator: this.$validate('IPv4') },
  93. ],
  94. },
  95. ],
  96. netmask: i => [
  97. `netmask[${i}]`,
  98. {
  99. initialValue: '24',
  100. rules: [
  101. { required: true, message: this.$t('network.text_595') },
  102. ],
  103. },
  104. ],
  105. gateway: i => [
  106. `gateway[${i}]`,
  107. {
  108. initialValue: '',
  109. validateTrigger: ['change', 'blur'],
  110. validateFirst: true,
  111. rules: [
  112. { validator: this.$validate('IPv4') },
  113. { validator: validateGateway },
  114. ],
  115. },
  116. ],
  117. vlan: i => [
  118. `vlan[${i}]`,
  119. {
  120. initialValue: '',
  121. },
  122. ],
  123. },
  124. },
  125. form: {
  126. fc: this.$form.createForm(this),
  127. },
  128. formItemLayout: {
  129. wrapperCol: {
  130. md: { span: 23 },
  131. xl: { span: 23 },
  132. xxl: { span: 23 },
  133. },
  134. labelCol: {
  135. md: { span: 1 },
  136. xl: { span: 1 },
  137. xxl: { span: 1 },
  138. },
  139. },
  140. }
  141. },
  142. computed: {
  143. isRender () {
  144. return this.networks.length > 0
  145. },
  146. renderColumns () {
  147. const hiddenColumns = ['metadata', 'schedtag', 'is_auto_alloc', 'brand', 'account', 'public_scope']
  148. return this.columns.filter((item) => {
  149. return !hiddenColumns.includes(item.field)
  150. })
  151. },
  152. },
  153. created () {
  154. this.fetchData()
  155. this.$watch('networks', () => {
  156. if (this.networks) {
  157. this.$refs.ipSubnetsRef.ipSubnets = []
  158. this.networks.forEach(item => {
  159. const key = uuid()
  160. this.networkIds.push(item.id)
  161. this.$refs.ipSubnetsRef.ipSubnets.push({ key })
  162. const fieldKeys = Object.keys(this.decorators.ipSubnets)
  163. fieldKeys.forEach(field => {
  164. this.form.fc.getFieldDecorator(`[${field}][${key}]`, this.decorators.ipSubnets[field](key)[1])
  165. })
  166. this.$nextTick(() => {
  167. this.form.fc.setFieldsValue({ [`name[${key}]`]: item.name })
  168. this.form.fc.setFieldsValue({ [`startip[${key}]`]: item.guest_ip_start })
  169. this.form.fc.setFieldsValue({ [`endip[${key}]`]: item.guest_ip_end })
  170. this.form.fc.setFieldsValue({ [`netmask[${key}]`]: item.guest_ip_mask + '' })
  171. this.form.fc.setFieldsValue({ [`gateway[${key}]`]: item.guest_gateway })
  172. this.form.fc.setFieldsValue({ [`vlan[${key}]`]: item.vlan_id })
  173. })
  174. })
  175. }
  176. })
  177. },
  178. methods: {
  179. fetchData () {
  180. const m = new this.$Manager('networks')
  181. let ids = [this.$route.query.id]
  182. if (Array.isArray(this.$route.query.id)) {
  183. ids = this.$route.query.id
  184. }
  185. this.loading = true
  186. m.batchGet({ id: ids })
  187. .then((res) => {
  188. const { data } = res.data
  189. this.networks = data
  190. this.loading = false
  191. })
  192. .catch((err) => {
  193. this.loading = false
  194. throw err
  195. })
  196. },
  197. clearIpSubnetsError () {
  198. this.ipSubnetsValidateStatus = ''
  199. this.ipSubnetsHelp = ''
  200. },
  201. doUpdate (data) {
  202. return new this.$Manager('networks').batchUpdate({
  203. ids: this.networkIds,
  204. data,
  205. params: { batch_params: true },
  206. })
  207. },
  208. genData (values) {
  209. const data = []
  210. R.forEachObjIndexed((value, key) => {
  211. const obj = {
  212. name: values.name[key],
  213. guest_gateway: values.gateway[key],
  214. guest_ip_end: values.endip[key],
  215. guest_ip_mask: values.netmask[key],
  216. guest_ip_start: values.startip[key],
  217. vlan_id: values.vlan[key] === '' ? '1' : values.vlan[key],
  218. }
  219. data.push(obj)
  220. }, values.startip)
  221. return data
  222. },
  223. async handleSubmit () {
  224. this.submiting = true
  225. try {
  226. const values = await this.form.fc.validateFields()
  227. const data = this.genData(values)
  228. await this.doUpdate(data)
  229. this.$store.commit('keepAlive/ADD_DELAY_EVENT', { name: 'ResourceListSingleRefresh', params: this.networkIds })
  230. this.$router.push('/network')
  231. } catch (err) {
  232. throw err
  233. } finally {
  234. this.submiting = false
  235. }
  236. },
  237. },
  238. }
  239. </script>