Create.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. <template>
  2. <base-dialog @cancel="cancelDialog">
  3. <div slot="header">{{$t('compute.text_323')}}</div>
  4. <div slot="body">
  5. <a-alert class="mb-3" :message="$t('compute.baremetal_raid_tip')" type="warning" />
  6. <a-form
  7. :form="form.fc">
  8. <a-form-item :label="$t('compute.text_295')" v-bind="formItemLayout">
  9. <a-row :gutter="8">
  10. <a-col :span="22">
  11. <a-cascader :options="disksOptions" v-decorator="decorators.option" :placeholder="$t('compute.text_219')" @change="cascaderChange" />
  12. </a-col>
  13. <a-col :span="2">
  14. <a-tooltip :title="coutTitle">
  15. <a-input-number :min="mincount" :max="maxcount" v-decorator="decorators.count" :step="step" />
  16. </a-tooltip>
  17. </a-col>
  18. </a-row>
  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 _ from 'lodash'
  30. import { sizestr } from '@/utils/utils'
  31. import DialogMixin from '@/mixins/dialog'
  32. import WindowsMixin from '@/mixins/windows'
  33. export default {
  34. name: 'BaremetalCreateDiskDialog',
  35. mixins: [DialogMixin, WindowsMixin],
  36. data () {
  37. return {
  38. loading: false,
  39. form: {
  40. fc: this.$form.createForm(this),
  41. },
  42. decorators: {
  43. option: [
  44. 'option',
  45. {
  46. rules: [
  47. { required: true, message: this.$t('compute.text_324') },
  48. ],
  49. },
  50. ],
  51. count: [
  52. 'count',
  53. {
  54. initialValue: 0,
  55. rules: [
  56. { required: true, message: this.$t('compute.text_324') },
  57. ],
  58. },
  59. ],
  60. },
  61. formItemLayout: {
  62. wrapperCol: {
  63. span: 8,
  64. },
  65. labelCol: {
  66. span: 4,
  67. },
  68. },
  69. driverLimiations: {
  70. Linux: [
  71. {
  72. value: 'none',
  73. label: this.$t('compute.text_325'),
  74. min: 1,
  75. step: 1,
  76. },
  77. {
  78. value: 'raid0',
  79. label: 'Raid0',
  80. min: 1,
  81. step: 1,
  82. },
  83. {
  84. value: 'raid1',
  85. label: 'Raid1',
  86. min: 2,
  87. step: 2,
  88. },
  89. {
  90. value: 'raid5',
  91. label: 'Raid5',
  92. min: 3,
  93. step: 1,
  94. },
  95. {
  96. value: 'raid10',
  97. label: 'Raid10',
  98. min: 4,
  99. step: 2,
  100. },
  101. ],
  102. PCIE: [
  103. {
  104. value: 'none',
  105. label: this.$t('compute.text_325'),
  106. min: 1,
  107. step: 1,
  108. },
  109. {
  110. value: 'raid0',
  111. label: 'Raid0',
  112. min: 1,
  113. step: 1,
  114. },
  115. {
  116. value: 'raid1',
  117. label: 'Raid1',
  118. min: 2,
  119. step: 2,
  120. },
  121. {
  122. value: 'raid5',
  123. label: 'Raid5',
  124. min: 3,
  125. step: 1,
  126. },
  127. {
  128. value: 'raid10',
  129. label: 'Raid10',
  130. min: 4,
  131. step: 2,
  132. },
  133. ],
  134. MPT2SAS: [
  135. {
  136. value: 'none',
  137. label: this.$t('compute.text_325'),
  138. min: 1,
  139. step: 1,
  140. },
  141. {
  142. value: 'raid0',
  143. label: 'Raid0',
  144. min: 2,
  145. step: 1,
  146. },
  147. {
  148. value: 'raid1',
  149. label: 'Raid1',
  150. min: 2,
  151. max: 2,
  152. step: 2,
  153. },
  154. {
  155. value: 'raid10',
  156. label: 'Raid10',
  157. min: 4,
  158. max: 10,
  159. step: 2,
  160. },
  161. ],
  162. Mpt3SAS: [
  163. {
  164. value: 'none',
  165. label: this.$t('compute.text_325'),
  166. min: 1,
  167. step: 1,
  168. },
  169. {
  170. value: 'raid0',
  171. label: 'Raid0',
  172. min: 2,
  173. max: 10,
  174. step: 1,
  175. },
  176. {
  177. value: 'raid1',
  178. label: 'Raid1',
  179. min: 2,
  180. max: 2,
  181. step: 2,
  182. },
  183. {
  184. value: 'raid10',
  185. label: 'Raid10',
  186. min: 4,
  187. max: 10,
  188. step: 2,
  189. },
  190. ],
  191. Mpt2SAS: [
  192. {
  193. value: 'none',
  194. label: this.$t('compute.text_325'),
  195. min: 1,
  196. step: 1,
  197. },
  198. {
  199. value: 'raid0',
  200. label: 'Raid0',
  201. min: 2,
  202. max: 10,
  203. step: 1,
  204. },
  205. {
  206. value: 'raid1',
  207. label: 'Raid1',
  208. min: 2,
  209. max: 2,
  210. step: 2,
  211. },
  212. {
  213. value: 'raid10',
  214. label: 'Raid10',
  215. min: 4,
  216. max: 10,
  217. step: 2,
  218. },
  219. ],
  220. MegaRaid: [
  221. {
  222. value: 'none',
  223. label: this.$t('compute.text_325'),
  224. min: 1,
  225. step: 1,
  226. },
  227. {
  228. value: 'raid0',
  229. label: 'Raid0',
  230. min: 1,
  231. step: 1,
  232. },
  233. {
  234. value: 'raid1',
  235. label: 'Raid1',
  236. min: 2,
  237. max: 2,
  238. step: 2,
  239. },
  240. {
  241. value: 'raid5',
  242. label: 'Raid5',
  243. min: 3,
  244. step: 1,
  245. },
  246. {
  247. value: 'raid10',
  248. label: 'Raid10',
  249. min: 4,
  250. step: 2,
  251. },
  252. ],
  253. HPSARaid: [
  254. {
  255. value: 'none',
  256. label: this.$t('compute.text_325'),
  257. min: 1,
  258. step: 1,
  259. },
  260. {
  261. value: 'raid0',
  262. label: 'Raid0',
  263. min: 1,
  264. step: 1,
  265. },
  266. {
  267. value: 'raid1',
  268. label: 'Raid1',
  269. min: 2,
  270. step: 2,
  271. },
  272. {
  273. value: 'raid5',
  274. label: 'Raid5',
  275. min: 3,
  276. step: 1,
  277. },
  278. {
  279. value: 'raid10',
  280. label: 'Raid10',
  281. min: 4,
  282. step: 2,
  283. },
  284. ],
  285. MarvelRaid: [
  286. {
  287. value: 'none',
  288. label: this.$t('compute.text_325'),
  289. min: 1,
  290. step: 1,
  291. },
  292. {
  293. value: 'raid0',
  294. label: 'Raid0',
  295. min: 1,
  296. step: 1,
  297. },
  298. {
  299. value: 'raid1',
  300. label: 'Raid1',
  301. min: 2,
  302. step: 2,
  303. },
  304. {
  305. value: 'raid10',
  306. label: 'Raid10',
  307. min: 4,
  308. step: 2,
  309. },
  310. ],
  311. AdaptecRaid: [
  312. {
  313. value: 'none',
  314. label: this.$t('compute.text_325'),
  315. min: 1,
  316. step: 1,
  317. },
  318. {
  319. value: 'raid0',
  320. label: 'Raid0',
  321. min: 2,
  322. step: 1,
  323. },
  324. {
  325. value: 'raid1',
  326. label: 'Raid1',
  327. min: 2,
  328. step: 2,
  329. },
  330. {
  331. value: 'raid10',
  332. label: 'Raid10',
  333. min: 4,
  334. step: 2,
  335. },
  336. ],
  337. },
  338. disksOptions: [],
  339. maxcount: 0,
  340. mincount: 0,
  341. /*
  342. * this.params.diskData structure:
  343. * {
  344. * "MegaRaid": {
  345. * "adapter0": [
  346. * {
  347. * "count": 4,
  348. * "end_index": 3,
  349. * "size": 3814912,
  350. * "start_index": 0,
  351. * "type": "HDD"
  352. * }
  353. * ]
  354. * }
  355. * }
  356. */
  357. diskData: JSON.parse(JSON.stringify(this.params.diskData)), // 拷贝参数
  358. raidTypes: [...Object.keys(this.params.diskData)],
  359. step: 1,
  360. startIndex: 0,
  361. endIndex: 0,
  362. }
  363. },
  364. computed: {
  365. coutTitle () {
  366. return this.$t('compute.text_326', [this.mincount, this.maxcount])
  367. },
  368. },
  369. created () {
  370. this.handleDiskDate()
  371. },
  372. methods: {
  373. // 组装联动数据
  374. handleDiskDate () {
  375. this.raidTypes.map(raidType => {
  376. const raidAdapter = this.diskData[raidType]
  377. this.params.diskOptionsDate.forEach(item => {
  378. const adapterKey = item.diskInfo[1]
  379. raidAdapter[adapterKey].forEach(disks => {
  380. if (disks.type === item.type && sizestr(disks.size, 'M', 1024) === item.unitSize) {
  381. disks.count = disks.count - item.count
  382. disks.start_index = disks.start_index + item.count
  383. }
  384. })
  385. })
  386. Object.keys(raidAdapter).forEach((key) => {
  387. const option = {}
  388. option.value = raidType + ':' + key
  389. option.label = raidType + ':' + key
  390. option.children = []
  391. raidAdapter[key].forEach((item) => {
  392. let optionL2 = {}
  393. optionL2 = {
  394. ...item,
  395. label: item.type + ':' + sizestr(item.size, 'M', 1024),
  396. value: item.type + ':' + sizestr(item.size, 'M', 1024),
  397. start_index: item.start_index,
  398. end_index: item.end_index,
  399. children: this._getRaidOptions(raidType, item.count),
  400. }
  401. if (optionL2.children.length === 0) return
  402. option.children.push(optionL2)
  403. })
  404. if (option.children.length === 0) return
  405. // 合并同类型
  406. const keys = []
  407. option.children.forEach(item => {
  408. if (!keys.includes(item.value)) {
  409. keys.push(item.value)
  410. }
  411. })
  412. const children = []
  413. keys.forEach(key => {
  414. const target = option.children.filter(item => item.value === key)
  415. if (target.length === 1) {
  416. children.push(target[0])
  417. } else if (target.length > 1) {
  418. const count = target.reduce((acc, item) => acc + item.count, 0)
  419. const item = {
  420. ...target[0],
  421. count,
  422. start_index: target[0].start_index,
  423. end_index: target.reduce((acc, item) => acc + item.end_index, 0) + target.length,
  424. children: this._getRaidOptions(raidType, count),
  425. }
  426. children.push(item)
  427. }
  428. })
  429. option.children = children
  430. this.disksOptions.push(option)
  431. })
  432. })
  433. },
  434. // 计算器
  435. _getRaidOptions (dirver, diskNum) {
  436. const options = []
  437. const limits = this.driverLimiations[dirver]
  438. if (!limits) {
  439. return options
  440. }
  441. _.forEach(limits, function (item, k) {
  442. if (diskNum >= item.min) {
  443. const option = { value: item.value, label: item.label, props: { step: item.step || 1, min: item.min || 1 } }
  444. if (item.max && item.max <= diskNum) {
  445. option.props.max = item.max
  446. } else {
  447. option.props.max = diskNum - (diskNum - option.props.min) % option.props.step
  448. }
  449. options.push(option)
  450. }
  451. })
  452. return options
  453. },
  454. // 监听联动改变回调
  455. cascaderChange (value, selectedOptions) {
  456. if (selectedOptions) {
  457. // e.g. 'MegaRaid:adapter0'
  458. // const adapterOpt = selectedOptions[0]
  459. // e.g. 'HDD:3.6T'
  460. const diskOpt = selectedOptions[1]
  461. // e.g. 'Raid0'
  462. const raidOpt = selectedOptions[2]
  463. this.maxcount = raidOpt.props.max
  464. this.mincount = raidOpt.props.min
  465. this.step = raidOpt.props.step
  466. this.startIndex = diskOpt.start_index
  467. this.endIndex = diskOpt.end_index
  468. }
  469. },
  470. validateForm () {
  471. return new Promise((resolve, reject) => {
  472. this.form.fc.validateFields((err, values) => {
  473. if (!err) {
  474. resolve(values)
  475. } else {
  476. reject(err)
  477. }
  478. })
  479. })
  480. },
  481. async handleConfirm () {
  482. const values = await this.validateForm()
  483. values.computeCount = values.count
  484. values.start_index = this.startIndex
  485. values.end_index = this.endIndex
  486. this.params.updateData(values)
  487. this.cancelDialog()
  488. },
  489. },
  490. }
  491. </script>