cos-web/src/views/resource-apply/ecs/EFCVmList.vue

764 lines
29 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<basic-form :model="formData" ref="addForm" label-width="0" :disabled="disabled">
<basic-table :data="showParamList" ref="addTable">
<el-table-column label="序号" show-overflow-tooltip width="60px">
<template slot-scope="{ $index }">
<basic-form-item label="">
{{ $index + 1 }}
</basic-form-item>
</template>
</el-table-column>
<el-table-column label="命名规则" show-overflow-tooltip width="160px">
<template slot-scope="{ row, $index }">
<basic-form-item label="" :prop="`showParamList.${$index}.configs.nameRuleId`">
<el-select v-model="row.configs.nameRuleId" placeholder="请选择命名规则" clearable filterable>
<el-option v-for="(item, index) in nameruleList" :key="index" :label="item.name" :value="item.id"> </el-option>
</el-select>
</basic-form-item>
</template>
</el-table-column>
<el-table-column label="主机名" show-overflow-tooltip width="160px">
<template slot-scope="{ row, $index }">
<basic-form-item label="" validate="required,vmHostName" :prop="`showParamList.${$index}.configs.vmHostName`">
<el-input v-model="row.configs.vmHostName"> </el-input>
</basic-form-item>
</template>
</el-table-column>
<!-- <el-table-column label="云平台类型" show-overflow-tooltip>
<template slot-scope="{ row,$index }">
<basic-form-item label="">
<el-select v-model="row.subLocation.vendorType">
<el-option :label="item | vendorName" :value="item" v-for="item in vendorTypelist" :key="item"></el-option>
</el-select>
</basic-form-item>
</template>
</el-table-column> -->
<el-table-column label="区域" show-overflow-tooltip width="180px">
<template slot-scope="{ row, $index }">
<basic-form-item label="" validate="required" :prop="`showParamList.${$index}.subLocation.region`">
<el-select v-model="row.subLocation.region" @change="changeRegion(row, true)">
<el-option :label="item.regionName" :value="item.region" v-for="item in regionList" :key="item.region"></el-option>
</el-select>
</basic-form-item>
</template>
</el-table-column>
<el-table-column label="可用区" show-overflow-tooltip width="180px">
<template slot-scope="{ row, $index }">
<basic-form-item label="" validate="required" :prop="`showParamList.${$index}.subLocation.az`">
<el-select v-model="row.subLocation.az" @change="changeAz(row, true)">
<el-option :label="item.azName" :value="item.availablitiyZone" v-for="item in getZoneListByRegion(row)" :key="item.availablitiyZone"></el-option>
</el-select>
</basic-form-item>
</template>
</el-table-column>
<el-table-column label="镜像类型" show-overflow-tooltip width="180px">
<template slot-scope="{ row, $index }">
<basic-form-item label="" validate="required" :prop="`showParamList.${$index}.configs.osCategory`">
<el-select v-model="row.configs.osCategory" placeholder="请选择" @change="getVersionList(row, true)">
<el-option v-for="(item, index) in row.osList" :key="index" :label="item" :value="item"> </el-option>
</el-select>
</basic-form-item>
</template>
</el-table-column>
<el-table-column label="镜像版本" show-overflow-tooltip width="180px">
<template slot-scope="{ row, $index }">
<basic-form-item label="" validate="required" :prop="`showParamList.${$index}.configs.osVersion`">
<el-select v-model="row.configs.osVersion" placeholder="请选择" @change="getImage(row, true)">
<el-option v-for="(item, index) in row.versionList" :key="index" :label="item" :value="item"> </el-option>
</el-select>
</basic-form-item>
</template>
</el-table-column>
<el-table-column label="CPU" show-overflow-tooltip width="160px">
<template slot-scope="{ row, $index }">
<basic-form-item label="" validate="required" :prop="`showParamList.${$index}.configs.cpu`">
<el-input-number :min="1" :max="500" v-model="row.configs.cpu" @change="(val) => changeCpu(val, row)"> </el-input-number>
</basic-form-item>
</template>
</el-table-column>
<el-table-column label="内存GB" show-overflow-tooltip width="160px">
<template slot-scope="{ row, $index }">
<basic-form-item label="" validate="required" :prop="`showParamList.${$index}.configs.memory`">
<el-input-number :min="row.configs.templateRam" :max="500" v-model="row.configs.memory" @change="(val) => changeMemory(val, row)"> </el-input-number>
</basic-form-item>
</template>
</el-table-column>
<el-table-column label="磁盘GB" show-overflow-tooltip width="160px">
<template slot-scope="{ row, $index }">
<basic-form-item label="" validate="required" :prop="`showParamList.${$index}.configs.sysDisk.disk`">
<span class="detail-href" @click="handleOpenDiskDialog(row, $index)">
<template v-if="getDiskTotalSize(row) > 0">{{ getDiskTotalSize(row) }}</template>
<template v-else>配置</template>
</span>
</basic-form-item>
</template>
</el-table-column>
<el-table-column label="网络" show-overflow-tooltip width="180px">
<template slot-scope="{ row, $index }">
<basic-form-item label="" :prop="`showParamList.${$index}`" :rules="rules.networkCardConfigsRule">
<span class="detail-href" @click="handleOpenNetworkDialog(row, $index)">
<template v-if="!row.configs.networkCardConfigs.length || row.configs.networkCardConfigs[0].ipPoolId">
<div v-for="(item, index) in row.configs.networkCardConfigs" :key="index">
{{ item.ipPoolName }} <span v-if="item.address.length">-{{ item.address.join('、') }}</span>
</div>
</template>
<template v-else>配置</template>
</span>
</basic-form-item>
</template>
</el-table-column>
<el-table-column label="密码" show-overflow-tooltip width="160px">
<template slot-scope="{ row, $index }">
<basic-form-item label="" validate="required,vmPassword" :prop="`showParamList.${$index}.configs.password`">
<el-input v-model="row.configs.password" placeholder="请输入密码" show-password></el-input>
</basic-form-item>
<basic-form-item label="" validate="required" :prop="`showParamList.${$index}.configs.confirm_password`">
<el-input v-model="row.configs.confirm_password" placeholder="请再次输入密码" show-password></el-input>
</basic-form-item>
</template>
</el-table-column>
<el-table-column label="用途" show-overflow-tooltip width="160px">
<template slot-scope="{ row, $index }">
<basic-form-item label="" validate="required" :prop="`showParamList.${$index}.subLocation.purpose`">
<el-input v-model="row.subLocation.purpose"> </el-input>
</basic-form-item>
</template>
</el-table-column>
<el-table-column label="软件配置" show-overflow-tooltip width="160px">
<template slot-scope="{ row, $index }">
<basic-form-item label="">
<span class="detail-href" @click="openGraph(row, $index)"> {{ getGraphConfigLabel(row) }} </span>
</basic-form-item>
</template>
</el-table-column>
<el-table-column label="数量" show-overflow-tooltip width="160px">
<template slot-scope="{ row, $index }">
<basic-form-item label="" validate="required" :prop="`showParamList.${$index}.emption.count`">
<el-input-number v-model="row.emption.count"> </el-input-number>
</basic-form-item>
</template>
</el-table-column>
<el-table-column label="操作" width="160px" fixed="right">
<template slot-scope="{ row, $index }">
<basic-form-item label="">
<el-button type="text" @click="handleClone(row)">复制</el-button>
<el-button type="text" @click="handleSub($index)">删除</el-button>
</basic-form-item>
</template>
</el-table-column>
<span slot="pagination"></span>
</basic-table>
<DataDisk v-if="addDiskDialog.visible" :dialog="addDiskDialog" @success="changeDisk"></DataDisk>
<Ippool v-if="addNetworkDialog.visible" :dialog="addNetworkDialog" :disabled="disabled"></Ippool>
<el-dialog :visible.sync="graphDialog.visible" title="作业编排" width="1200px" append-to-body top="5vh" :closeOnClickModal="false">
<Graph v-if="graphDialog.visible" :addData="addData" :graphDialog="graphDialog" @back="graphDialog.visible = false" :disabled="disabled"></Graph>
</el-dialog>
</basic-form>
</template>
<script>
import { conditionService, conditionImage, getNameRule } from 'services/platform/index'
import { generateSpec, getSpecValue } from 'views/resource-apply/utils/index'
import { getPoolCondition } from 'services/platform/pool'
import { uniqBy, cloneDeep } from 'lodash-es'
import { transformNetworkConfig } from './ImageItem'
import { subApplicationParam, GEN_UUID, ServiceCodeMap, defaultTask } from '../data/EFCInit'
import Ippool, { CECSTACK_DEFAULT_CONFIG, CLOUDTOWER_DEFAULT_CONFIG } from './EFCIppool'
import DataDisk from './EFCDataDisk'
import sku from '../mixins/EFCsku'
import Graph from '../graph/graph.vue'
import { getVolumeTpl } from 'services/platform/smart.js'
export default {
name: 'VmList',
mixins: [sku],
components: {
Ippool,
DataDisk,
Graph
},
props: {
itemData: {
type: [Object, Boolean]
},
showParamList: {
type: Array,
required: true,
default: () => []
},
addData: {
type: Object,
required: true,
default: () => {}
},
disabled: {
type: Boolean
}
},
provide() {
// 使用函数的形式,可以访问到 `this`
return {
getSubApplicationParamsForTaskServer: () => this.addData.subApplicationParams.filter((item) => item.taskGroupUuid === this.graphDialog.task.taskGroupUuid)
}
},
computed: {
formData() {
return { showParamList: this.showParamList }
},
regionList() {
return this.allPoolList.reduce((pre, cur) => {
if (!pre.find((item) => item.region == cur.region)) {
pre.push({
regionName: cur.regionName,
region: cur.region
})
}
return pre
}, [])
}
},
data() {
return {
nameruleList: [],
vendorTypelist: [],
allPoolList: [],
addDiskDialog: {
visible: false,
index: '',
row: {}
},
addNetworkDialog: {
visible: false,
row: {},
cb: () => {}
},
rules: {
networkCardConfigsRule: [
{
required: true,
validator: (rule, value, callback) => {
const validateNetworkCard = this.validateNetworkCard(value)
if (validateNetworkCard.valid) {
callback()
} else {
callback(new Error(validateNetworkCard.message))
}
},
trigger: null
}
]
},
graphDialog: {
visible: false,
task: {},
cb: () => {}
},
CTDataDisktemplateData: []
}
},
created() {
getNameRule({
page: 1,
rows: 9999
}).then((data) => {
if (data.success) {
this.nameruleList = data.data.rows
}
})
this.getAllPool()
// 获取云平台类型
conditionService('server').then((data) => {
if (data.success) {
this.vendorTypelist = data.data
}
})
},
methods: {
getGraphConfigLabel(row) {
const task = this.addData.tasks.find(({ taskGroupUuid }) => taskGroupUuid === row.taskGroupUuid)
if (!task) return '配置'
return `${task.taskName}`
},
openGraph(row) {
if (!this.addData.location.name) return this.$message.error('请填写业务信息')
if (!row.configs.vmHostName) return this.$message.error('请填写主机名')
if (!row.configs.password) return this.$message.error('请填写密码')
this.$emit('handleUpdateParamList')
this.graphDialog.visible = true
this.graphDialog.task = cloneDeep(
this.addData.tasks.find((item) => item.taskGroupUuid === row.taskGroupUuid) || {
...defaultTask,
taskGroupUuid: row.taskGroupUuid
}
)
this.graphDialog.cb = () => {
this.graphDialog.task.taskName = `${this.addData.location.name}_${this.graphDialog.task.name}`
const findIndex = this.addData.tasks.findIndex((item) => item.taskGroupUuid === row.taskGroupUuid)
if (findIndex > -1) {
this.addData.tasks[findIndex] = this.graphDialog.task
} else {
this.addData.tasks.push(this.graphDialog.task)
}
}
},
changeCpu(val, row) {
row.elements[0].specs[0].cpu = val
},
changeMemory(val, row) {
row.elements[0].specs[1].memory = val
},
// 将磁盘配置保存到 elements 中
async changeDisk(index = -1, row) {
row = index > -1 ? this.showParamList[index] : row
// 系统盘
row.elements[1].specs = [{ disk: row.configs.sysDisk.disk }]
row.configs.sysDisk.categoryId = row.elements[1].categoryId
// 数据盘
row.elements.splice(2)
if (row.configs.addDiskList.length) {
const dataDiskElementClone = cloneDeep(row.elements[1])
row.configs.addDiskList.map((item) => {
row.elements.push({ ...dataDiskElementClone, specs: [{ disk: item.disk }] })
})
}
// 设置各个云平台的默认磁盘配置
const vendorType = row.subLocation.vendorType
const vendorId = row.subLocation.vendorId
switch (vendorType) {
case 'VMWARE':
row.configs.sysDisk.diskType = 'thin'
// 设置磁盘默认数据
row.configs.addDiskList.forEach((item) => {
item.createLvm = false
item.diskType = 'thin'
item.fileSystem = 'ext3'
item.forceMount = false
})
break
case 'INSPURRAIL':
row.configs.sysDisk.diskType = 'thin'
// 设置磁盘默认数据
row.configs.addDiskList.forEach((item) => {
item.createLvm = false
item.diskType = 'thin'
item.fileSystem = 'ext3'
item.forceMount = false
})
break
case 'CLOUDTOWER':
const busData = [
{ name: 'VIRTIO', value: 'VIRTIO' },
{ name: 'SCSI', value: 'SCSI' },
{ name: 'IDE', value: 'IDE' }
]
// 设置磁盘默认数据
if (!this.CTDataDisktemplateData.length || this.CTDataDisktemplateData[0].vendorId !== vendorId) {
await getVolumeTpl({
simple: true,
params: this.$tools.handleSearchParam({ vendorId })
}).then((data) => {
if (data.success) {
if (!data.data.rows.length) {
row.configs.addDiskList = []
return this.$message.error('获取CLOUDTOWER存储策略数据为空,请联系管理员')
}
this.CTDataDisktemplateData = data.data.rows
}
})
}
row.configs.addDiskList.forEach((item) => {
item.type = 'newDisk'
item.bus = busData[0].value
item.volumeTemplateId = this.CTDataDisktemplateData[0].id // 存储策略
item.volumeTemplateName = this.CTDataDisktemplateData[0].name
})
break
case 'CECSTACK':
row.configs.addDiskList.forEach((item) => {
item.deleteWithInstance = true
item.bootVolume = false
// item.size = ''
// item.volumeType = ''
item.volumeUnit = 'GiB'
// item.bootIndex = ''
})
break
default:
break
}
},
handleClone(row = subApplicationParam) {
const cloneData = cloneDeep(row)
cloneData.taskGroupUuid = GEN_UUID()
cloneData.taskTargetUuid = GEN_UUID()
cloneData.configs.name = ''
this.showParamList.push(cloneData)
},
handleSub(index) {
this.showParamList.splice(index, 1)
},
handleOpenNetworkDialog(row, index) {
this.addNetworkDialog.visible = true
this.addNetworkDialog.row = row
this.addNetworkDialog.cb = () => {
this.$refs.addForm && this.$refs.addForm.$refs.formRef.validateField(`showParamList.${index}`)
}
},
getDiskTotalSize(row) {
return row.configs.sysDisk.disk + row.configs.addDiskList.reduce((pre, cur) => pre + cur.disk, 0)
},
handleOpenDiskDialog(row, index) {
this.addDiskDialog.visible = true
this.addDiskDialog.row = row
this.addDiskDialog.index = index
},
getOsList(row) {
if (!row.subLocation.vendorId) return
let params
if (row.subLocation.vendorType === 'CECSTACK') {
params = {
condition: 'listByImageType',
vendorId: row.subLocation.vendorId,
status: 'ACTIVE',
tenantId: 0,
regionId: row.subLocation.region,
imageType: 'PUBLIC'
}
} else {
params = {
condition: 'listTenantImages',
vendorId: row.subLocation.vendorId
}
if (row.subLocation.vendorType === 'SANGFOR') {
if (!row.subLocation.azUuid) return
params.azUuid = row.subLocation.azUuid
}
}
conditionImage(params).then((data) => {
if (data.success) {
row.imageData = data.data
this.$set(row, 'osList', Object.keys(row.imageData))
if (!this.itemData) {
row.configs.osCategory = row.osList[0]
row.configs.osVersion = ''
}
this.$set(row, 'versionList', [])
this.getVersionList(row, !row.configs.osVersion)
}
})
return row.osList
},
getVersionList(row, flag) {
if (row.subLocation.vendorType === 'CECSTACK') {
row.versionList = row.imageData[row.configs.osCategory].map(({ name }) => name)
} else {
row.versionList = Object.keys(row.imageData[row.configs.osCategory])
}
if (flag) {
row.configs.osVersion = row.versionList[0]
this.getImage(row, true)
} else {
this.getImage(row, false)
}
},
getImage(row, flag) {
let obj
if (row.subLocation.vendorType === 'CECSTACK') {
obj = row.imageData[row.configs.osCategory].find(({ name }) => row.configs.osVersion === name)
} else {
obj = row.imageData[row.configs.osCategory][row.configs.osVersion]?.[0]
}
if (!obj) return
if (flag) {
row.configs.imageId = obj.id
// 电子云为 minDisk
// cloudtower 镜像中可能没系统盘大小
row.configs.templateDisk = obj.templateDisk || obj.minDisk || 50
row.configs.templateRam = obj.minRam / 1024 || 1
if (row.configs.memory < row.configs.templateRam) row.configs.memory = row.configs.templateRam
row.configs.sysDisk.disk = row.configs.templateDisk
}
if (row.subLocation.vendorType == 'CECSTACK') {
if (flag) {
this.$set(row.configs, 'networkCardConfigs', [
{
networkId: obj.networkId,
ipPolicy: 'Auto',
ipPoolId: '',
ipPoolName: '',
address: [],
portGroupId: '',
loading: false,
// 电子云特殊参数
...CECSTACK_DEFAULT_CONFIG
}
])
}
} else if (row.subLocation.vendorType == 'SANGFOR') {
row.configs.vmUuid = obj.imageUuid
if (flag && row.configs.networkCardConfigs.length == 0) {
const hardware_status = JSON.parse(obj.detail || '{}')?.hardware_status
if (!hardware_status) return this.$message.error('镜像缺少网卡,请检查镜像是否正确')
const configs = transformNetworkConfig(hardware_status).map((item) => ({
ipPolicy: 'Auto',
ipPoolId: '',
ipPoolName: '',
address: [],
portGroupId: '',
loading: false
}))
this.$set(row.configs, 'networkCardConfigs', configs)
}
} else if (row.subLocation.vendorType == 'VMWARE') {
if (flag && (row.configs.networkCardConfigs.length == 0 || row.configs.networkCardConfigs[0].networkCardId != obj.networkCards?.[0]?.id)) {
if (!obj.networkCards?.length) this.$message.error('镜像缺少网卡,请检查镜像是否正确')
this.$set(
row.configs,
'networkCardConfigs',
obj.networkCards.map((item) => {
return {
networkCardId: item.id,
ipPolicy: 'Auto',
ipPoolId: '',
ipPoolName: '',
address: [],
portGroupId: '',
loading: false
}
})
)
}
} else if (row.subLocation.vendorType == 'INSPURRAIL') {
if (flag) {
if (row.configs.networkCardConfigs.length == 0 || row.configs.networkCardConfigs[0].networkCardId != obj.networkCards?.[0]?.id) {
if (!obj.networkCards?.length) this.$message.error('镜像缺少网卡,请检查镜像是否正确')
this.$set(
row.configs,
'networkCardConfigs',
obj.networkCards.map((item) => {
return {
networkCardId: item.id,
ipPolicy: 'Auto',
ipPoolId: '',
ipPoolName: '',
address: [],
portGroupId: '',
loading: false
}
})
)
}
// 模板里面的磁盘配置
const volumes = obj.volumes || []
volumes.map(({ bootVolume, size }) => {
if (bootVolume) {
row.configs.templateDisk = size
row.configs.sysDisk.disk = size
} else {
row.configs.addDiskList.push({ disk: size, templateDisk: size })
}
})
}
} else if (row.subLocation.vendorType == 'CLOUDTOWER') {
if (flag) {
this.$set(row.configs, 'networkCardConfigs', [
{
networkId: obj.networkId,
ipPolicy: 'Auto',
ipPoolId: '',
ipPoolName: '',
address: [],
portGroupId: '',
loading: false,
// CLOUDTOWER特殊参数
...CLOUDTOWER_DEFAULT_CONFIG
}
])
}
} else if (row.subLocation.vendorType === 'CNWARE') {
const res = JSON.parse(obj.configuration).devices.map((d) => {
if (d.capacity) {
const size = Number(d.capacity) / 1024 / 1024 / 1024
// 系统盘大小
row.configs.templateDisk = size
}
return {
...d
}
})
if (flag) {
row.configs.sysDiskList = res.flat()
}
}
// 设置硬盘参数
if (flag) this.changeDisk(-1, row)
},
setVendor(row, manual = true) {
const findVendorList = this.getVendorListByRegionZone(row)
const pool = findVendorList.filter((item) => item.vendorId == row.subLocation.vendorId)[0]
if (!pool) return this.$message.error('当前可用区下不存在资源池')
console.log('当前资源池:', pool.vendorType, pool.name)
const { vendorType, id, azUuid } = pool
row.subLocation.poolGroupId = id
row.subLocation.azUuid = azUuid
row.subLocation.vendorType = vendorType
row.networkRelations = pool.networkRelations || []
row.service = ServiceCodeMap.server[vendorType]
row.elements.map((item, index) => {
item.serviceCode = index === 0 ? ServiceCodeMap.server[vendorType] : ServiceCodeMap.disk[vendorType]
})
switch (vendorType) {
case 'VMWARE':
row.configs.isAddShterm = false
break
case 'INSPURRAIL':
row.configs.isAddShterm = false
break
case 'CLOUDTOWER':
row.configs.serverId = 0
row.configs.ha = true
row.configs.firmware = 'BIOS'
row.configs.status = 'running'
row.configs.fullClone = false
break
default:
break
}
// 根据云平台类型设置默认磁盘配置
this.changeDisk(-1, row)
this.getData(row, manual)
},
getData(row, manual = true) {
// 加载服务目录
if (!this.itemData || !this.disabled) this.loadSku(row)
this.getOsList(row)
},
getZoneListByRegion(row) {
const filterPools = this.allPoolList.filter((item) => item.region == row.subLocation.region)
if (!filterPools.length) return []
// 同一地域下可能会存在重复可用区,去重处理
if (filterPools[0].vendorType === 'CECSTACK') {
const formatPools = []
// 将多个可用区扁平化放在资源池中
filterPools.map((pool) => {
pool.regionRelations.map((zone) => {
formatPools.push({ ...pool, availablitiyZone: zone.zoneId, azName: zone.zoneName })
})
})
return uniqBy(formatPools, 'availablitiyZone')
} else {
return uniqBy(filterPools, 'availablitiyZone')
}
},
getVendorListByRegionZone(row) {
const zoneList = this.getZoneListByRegion(row)
return zoneList.filter((item) => item.availablitiyZone == row.subLocation.az)
},
// 地域变化
// manual 手动切换
changeRegion(row, manual = true) {
this.setZone(row, manual)
},
// 设置可用区
setZone(row, manual = true) {
const zoneList = this.getZoneListByRegion(row)
// 手动切换才需要置空
if (manual && !zoneList.length) return (row.subLocation.az = '')
if (!zoneList.find((item) => item.availablitiyZone === row.subLocation.az)) {
row.subLocation.az = zoneList[0].availablitiyZone
}
this.changeAz(row, manual)
},
// 可用区改变
changeAz(row, manual = true) {
const findVendorList = this.getVendorListByRegionZone(row)
if (manual && !findVendorList.length) return (row.subLocation.vendorId = '')
if (!findVendorList.find((item) => item.vendorId === row.subLocation.vendorId)) {
row.subLocation.vendorId = findVendorList[0].vendorId
}
this.setVendor(row, manual)
},
// 所有资源池
async getAllPool() {
const res = await getPoolCondition({
condition: 'listPoolGroups',
tenantId: this.addData.location.tenantId
})
if (!res.success) return
this.allPoolList = res.data
if (!this.regionList.length) return
const [{ region }] = this.regionList
if (!this.showParamList[0].subLocation.region) {
this.showParamList[0].subLocation.region = region
}
this.changeRegion(this.showParamList[0], false)
},
validateNetworkCard(param) {
const res = {
valid: true,
message: ''
}
let flag = false
let addressLenFlag = false
let cecstackFlag = false
param.configs.networkCardConfigs.forEach((item) => {
if (!item.ipPoolId || (item.ipPolicy == 'Manual' && item.address.length == 0) || (item.checkIpv6 && (!item.ipv6PoolId || (item.ipv6Policy == 'Manual' && item.ipv6Address.length == 0)))) flag = true
if (item.ipPolicy == 'Manual' && item.address.length !== param.emption.count) {
addressLenFlag = true
}
if (param.subLocation.vendorType === 'CECSTACK' && !(item.vpcUuid || item.subnetUuid)) {
cecstackFlag = true
}
})
if (flag) {
res.valid = false
res.message = '网卡信息配置不完善'
return res
}
if (addressLenFlag) {
res.valid = false
res.message = 'IP数量与云主机订购数量不一致'
return res
}
if (cecstackFlag) {
res.valid = false
res.message = '缺少 VPC 和子网信息'
}
return res
},
getParams() {
let data = false
this.$refs.addForm.validate((valid) => {
if (valid) {
const result = []
this.showParamList.forEach((param) => {
const validateNetworkCard = this.validateNetworkCard(param)
if (!validateNetworkCard.valid) {
data = false
return
}
const { password, confirm_password, ...other } = param.configs
if (password !== confirm_password) {
data = false
this.$message.error('两次密码输入不一致')
return
}
result.push({
...other,
categoryId: param.elements[0].categoryId
})
})
if (result.length === this.showParamList.length) data = result
} else {
this.$message.error('虚拟机信息未填写完整')
}
})
return data
}
}
}
</script>
<style scoped lang="scss"></style>