feat: 复制裸金属代码
							parent
							
								
									cca73a0672
								
							
						
					
					
						commit
						819c933aed
					
				| 
						 | 
					@ -0,0 +1,117 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="wrapper-container">
 | 
				
			||||||
 | 
					    <el-card>
 | 
				
			||||||
 | 
					      <el-steps :active="active" align-center style="width: 60%" finish-status="success">
 | 
				
			||||||
 | 
					        <el-step title="地域和操作系统"></el-step>
 | 
				
			||||||
 | 
					        <el-step title="存储和网络"></el-step>
 | 
				
			||||||
 | 
					      </el-steps>
 | 
				
			||||||
 | 
					      <el-col :span="24" class="panel-body" v-if="active == 0">
 | 
				
			||||||
 | 
					        <AddPageOne :addData="addData" :vendor-id="vendorId" :platform-object="platformObject"></AddPageOne>
 | 
				
			||||||
 | 
					      </el-col>
 | 
				
			||||||
 | 
					      <el-col :span="24" class="panel-body" v-if="active == 1">
 | 
				
			||||||
 | 
					        <AddPageTwo :addData="addData" ref="header" :vendor-id="vendorId" :platform-object="platformObject"></AddPageTwo>
 | 
				
			||||||
 | 
					      </el-col>
 | 
				
			||||||
 | 
					      <el-col :span="24" class="panel-body" v-if="active == 2">
 | 
				
			||||||
 | 
					        <AddPageThree :addData="addData" :vendor-id="vendorId"></AddPageThree>
 | 
				
			||||||
 | 
					      </el-col>
 | 
				
			||||||
 | 
					      <el-col :span="24" class="m-b-lg">
 | 
				
			||||||
 | 
					        <el-col :span="6" :offset="5" v-if="active == 0">
 | 
				
			||||||
 | 
					          <el-button type="ghost" style="width: 100%" @click="goBack">取消</el-button>
 | 
				
			||||||
 | 
					        </el-col>
 | 
				
			||||||
 | 
					        <el-col :span="6" :offset="5" v-if="active != 0">
 | 
				
			||||||
 | 
					          <el-button type="primary" style="width: 100%" @click="LastStep()">上一步</el-button>
 | 
				
			||||||
 | 
					        </el-col>
 | 
				
			||||||
 | 
					        <el-col :span="6" :offset="1" v-if="active == 1">
 | 
				
			||||||
 | 
					          <el-button type="primary" style="width: 100%" :loading="addData.loading" @click="ok">确定</el-button>
 | 
				
			||||||
 | 
					        </el-col>
 | 
				
			||||||
 | 
					        <el-col :span="6" :offset="1" v-if="active == 0">
 | 
				
			||||||
 | 
					          <el-button type="primary" style="width: 100%" :disabled="addData.data.operatingSystem == ''" @click="next()">下一步</el-button>
 | 
				
			||||||
 | 
					        </el-col>
 | 
				
			||||||
 | 
					      </el-col>
 | 
				
			||||||
 | 
					    </el-card>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					import AddPageOne from './addPageOne.vue'
 | 
				
			||||||
 | 
					import AddPageTwo from './addPageTwo.vue'
 | 
				
			||||||
 | 
					import AddPageThree from './addPageThree.vue'
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  props: {
 | 
				
			||||||
 | 
					    platformObject: {
 | 
				
			||||||
 | 
					      type: Object
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  components: {
 | 
				
			||||||
 | 
					    AddPageOne,
 | 
				
			||||||
 | 
					    AddPageTwo,
 | 
				
			||||||
 | 
					    AddPageThree
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  data() {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      active: 0,
 | 
				
			||||||
 | 
					      vendorId: parseInt(this.$router.currentRoute.query.vendorId),
 | 
				
			||||||
 | 
					      addData: {
 | 
				
			||||||
 | 
					        loading: false,
 | 
				
			||||||
 | 
					        data: {
 | 
				
			||||||
 | 
					          placement: {
 | 
				
			||||||
 | 
					            Zone: 'yfm14az1'
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          flavorId: '',
 | 
				
			||||||
 | 
					          operatingSystemType: '',
 | 
				
			||||||
 | 
					          operatingSystem: '',
 | 
				
			||||||
 | 
					          virtualPrivateCloud: {
 | 
				
			||||||
 | 
					            vpcId: '',
 | 
				
			||||||
 | 
					            subnetId: '',
 | 
				
			||||||
 | 
					            privateIpAddresses: ''
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          loginSettings: {
 | 
				
			||||||
 | 
					            Password: '',
 | 
				
			||||||
 | 
					            Password_config: ''
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          raidType: '',
 | 
				
			||||||
 | 
					          internetAccessible: {
 | 
				
			||||||
 | 
					            internetMaxBandwidthOut: 0,
 | 
				
			||||||
 | 
					            publicIpAssigned: false,
 | 
				
			||||||
 | 
					            internetServiceProvider: ''
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          instanceName: '',
 | 
				
			||||||
 | 
					          instanceCount: 1,
 | 
				
			||||||
 | 
					          enhancedService: {
 | 
				
			||||||
 | 
					            SecurityService: {
 | 
				
			||||||
 | 
					              Enabled: 'false'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            MonitorService: {
 | 
				
			||||||
 | 
					              Enabled: 'false'
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        selectComboData: {
 | 
				
			||||||
 | 
					          cpu: '',
 | 
				
			||||||
 | 
					          flavorId: '',
 | 
				
			||||||
 | 
					          flavorName: '',
 | 
				
			||||||
 | 
					          memory: '',
 | 
				
			||||||
 | 
					          systemDisk: ''
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  computed: {},
 | 
				
			||||||
 | 
					  mounted() {},
 | 
				
			||||||
 | 
					  methods: {
 | 
				
			||||||
 | 
					    ok() {
 | 
				
			||||||
 | 
					      this.$refs.header.getData()
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    goBack() {
 | 
				
			||||||
 | 
					      this.$router.back(-1)
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    next() {
 | 
				
			||||||
 | 
					      this.active++
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    LastStep() {
 | 
				
			||||||
 | 
					      this.active--
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					<style lang="scss" scoped></style>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,186 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="">
 | 
				
			||||||
 | 
					    <cb-form :model="addData.data" ref="addData" label-width="140px">
 | 
				
			||||||
 | 
					      <h3>地域和机型</h3>
 | 
				
			||||||
 | 
					      <cb-form-item label="地域">
 | 
				
			||||||
 | 
					        <el-select v-model="addData.data.regionId" @change="getZoomData">
 | 
				
			||||||
 | 
					          <el-option v-for="(item, index) in regionList" :label="item.name" :value="item.regionId" :key="index"></el-option>
 | 
				
			||||||
 | 
					        </el-select>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="可用区">
 | 
				
			||||||
 | 
					        <el-select v-model="addData.data.zone" @change="comboGetList">
 | 
				
			||||||
 | 
					          <el-option v-for="item in zoneList" :label="item.name" :value="item.zoneId" :key="item.id"></el-option>
 | 
				
			||||||
 | 
					        </el-select>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="CPU架构">
 | 
				
			||||||
 | 
					        <el-radio-group v-model="cpuArch" @change="comboGetList">
 | 
				
			||||||
 | 
					          <el-radio-button label="X86"></el-radio-button>
 | 
				
			||||||
 | 
					          <el-radio-button label="ARM"></el-radio-button>
 | 
				
			||||||
 | 
					        </el-radio-group>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="机型">
 | 
				
			||||||
 | 
					        <el-alert title="注意:机型只能单选" type="warning"> </el-alert>
 | 
				
			||||||
 | 
					        <cb-advance-table ref="list" title="" :data="comboData" :params="comboParams" :columns="comboColumns" :get-list="comboGetList" :total="comboTotal" :loading="comboLoading" @selection-change="handleSelectChange" :search-configs="comboSearchConfigs">
 | 
				
			||||||
 | 
					          <template #raidType="val">
 | 
				
			||||||
 | 
					            <span v-if="val">{{ val.join(' ') }}</span>
 | 
				
			||||||
 | 
					          </template>
 | 
				
			||||||
 | 
					          <div slot="pagination"></div>
 | 
				
			||||||
 | 
					        </cb-advance-table>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <h3>操作系统</h3>
 | 
				
			||||||
 | 
					      <cb-form-item label="镜像提供方">
 | 
				
			||||||
 | 
					        <span>公共镜像</span>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="操作系统" v-model="addData.data.operatingSystemType">
 | 
				
			||||||
 | 
					        <div v-if="selectComboData.length == '1'">
 | 
				
			||||||
 | 
					          <span v-if="selectComboData.operatingSystem != null">windows</span>
 | 
				
			||||||
 | 
					          <span v-else>linux</span>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="系统版本" prop="operatingSystem" validate="required">
 | 
				
			||||||
 | 
					        <el-select v-model="addData.data.operatingSystem" placeholder="请选择系统版本" style="width: 160px">
 | 
				
			||||||
 | 
					          <el-option v-for="item in version" :key="item" :label="item" :value="item"> </el-option>
 | 
				
			||||||
 | 
					        </el-select>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="主机安全agent">
 | 
				
			||||||
 | 
					        <el-radio v-model="addData.data.enhancedService.SecurityService.Enabled" label="true">安装</el-radio>
 | 
				
			||||||
 | 
					        <el-radio v-model="addData.data.enhancedService.SecurityService.Enabled" label="false">不安装</el-radio>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					    </cb-form>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					import { getCombo } from 'views/resource/ctstack/services/bms.js'
 | 
				
			||||||
 | 
					import { getRegion, getZone } from 'views/resource/ctstack/services/regions.js'
 | 
				
			||||||
 | 
					const comboColumns = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    type: 'selection',
 | 
				
			||||||
 | 
					    selectable: (row, index) => {
 | 
				
			||||||
 | 
					      if (row.soldout == 1) return false
 | 
				
			||||||
 | 
					      else return true
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '机型',
 | 
				
			||||||
 | 
					    prop: 'flavorName'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '计费机型',
 | 
				
			||||||
 | 
					    prop: 'flavorType'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '类型',
 | 
				
			||||||
 | 
					    prop: 'key'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: 'CPU',
 | 
				
			||||||
 | 
					    prop: 'cpu'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '内存',
 | 
				
			||||||
 | 
					    prop: 'memory'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '硬盘',
 | 
				
			||||||
 | 
					    prop: 'systemDisk'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: 'RAID',
 | 
				
			||||||
 | 
					    prop: 'raidType',
 | 
				
			||||||
 | 
					    scopedSlots: { customRender: 'raidType' }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  props: ['vendorId', 'addData', 'platformObject'],
 | 
				
			||||||
 | 
					  components: {},
 | 
				
			||||||
 | 
					  data() {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      comboData: [],
 | 
				
			||||||
 | 
					      comboParams: {
 | 
				
			||||||
 | 
					        page: 1,
 | 
				
			||||||
 | 
					        rows: 10
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      comboColumns,
 | 
				
			||||||
 | 
					      comboTotal: 0,
 | 
				
			||||||
 | 
					      comboLoading: false,
 | 
				
			||||||
 | 
					      mountedData: '',
 | 
				
			||||||
 | 
					      radio: '1',
 | 
				
			||||||
 | 
					      options: '',
 | 
				
			||||||
 | 
					      allZone: '',
 | 
				
			||||||
 | 
					      regionList: '',
 | 
				
			||||||
 | 
					      selectComboData: {
 | 
				
			||||||
 | 
					        operatingSystem: {
 | 
				
			||||||
 | 
					          windows: [],
 | 
				
			||||||
 | 
					          linux: []
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      version: [],
 | 
				
			||||||
 | 
					      versionList: ['TencentOS Server 2.2 (TK2-0052)', 'Centos 7.7 minimal for x86_64'],
 | 
				
			||||||
 | 
					      cpuArch: 'X86'
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  mounted() {
 | 
				
			||||||
 | 
					    this.getRegion()
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  methods: {
 | 
				
			||||||
 | 
					    handleSelectChange(selection) {
 | 
				
			||||||
 | 
					      if (selection.length >= 2) {
 | 
				
			||||||
 | 
					        this.$refs.list.clearSelection()
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (selection.length > 0) {
 | 
				
			||||||
 | 
					        this.selectComboData = selection
 | 
				
			||||||
 | 
					        this.addData.selectComboData = selection[0]
 | 
				
			||||||
 | 
					        this.addData.data.flavorId = this.selectComboData[0].flavorId
 | 
				
			||||||
 | 
					        if (this.selectComboData[0].operatingSystem.windows == null) {
 | 
				
			||||||
 | 
					          this.version = this.selectComboData[0].operatingSystem.linux
 | 
				
			||||||
 | 
					          this.addData.data.operatingSystemType = 'linux'
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          this.addData.data.operatingSystemType = 'windows'
 | 
				
			||||||
 | 
					          this.version = this.selectComboData[0].operatingSystem.windows
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        this.selectComboData = selection
 | 
				
			||||||
 | 
					        this.addData.selectComboData = {}
 | 
				
			||||||
 | 
					        this.addData.data.operatingSystem = ''
 | 
				
			||||||
 | 
					        this.version = []
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    getRegion() {
 | 
				
			||||||
 | 
					      getRegion({ vendorId: this.vendorId }).then(data => {
 | 
				
			||||||
 | 
					        if (data.success) {
 | 
				
			||||||
 | 
					          this.regionList = data.data
 | 
				
			||||||
 | 
					          this.$set(this.addData.data, 'regionId', data.data[0].regionId)
 | 
				
			||||||
 | 
					          this.getZoomData()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 获取可用域
 | 
				
			||||||
 | 
					    getZoomData() {
 | 
				
			||||||
 | 
					      getZone({ vendorId: this.vendorId, regionId: this.addData.data.regionId }).then(data => {
 | 
				
			||||||
 | 
					        if (data.success) {
 | 
				
			||||||
 | 
					          this.zoneList = data.data
 | 
				
			||||||
 | 
					          this.$set(this.addData.data, 'zone', data.data[0].zoneId)
 | 
				
			||||||
 | 
					          this.comboGetList()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    comboGetList() {
 | 
				
			||||||
 | 
					      // 获取套餐
 | 
				
			||||||
 | 
					      const params = {
 | 
				
			||||||
 | 
					        zone: [this.addData.data.zone],
 | 
				
			||||||
 | 
					        regionId: this.addData.data.regionId,
 | 
				
			||||||
 | 
					        cpuArch: this.cpuArch,
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      getCombo(this.vendorId, params).then(res => {
 | 
				
			||||||
 | 
					        this.comboData = res.data.flavorSet
 | 
				
			||||||
 | 
					        this.comboData.forEach((item, index) => {
 | 
				
			||||||
 | 
					          if (item.raidType[0] == '') {
 | 
				
			||||||
 | 
					            this.comboData.splice(index, 1)
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,27 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="">
 | 
				
			||||||
 | 
					    <cb-form label-width="140px">
 | 
				
			||||||
 | 
					      <h3>确认信息</h3>
 | 
				
			||||||
 | 
					      <cb-form-item label="地域">重庆</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="可用区">yfm14</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="机型">{{ addData.selectComboData.flavorName }},{{ addData.selectComboData.cpu }},{{ addData.selectComboData.memory }},{{ addData.selectComboData.systemDisk }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="操作系统">{{ addData.data.operatingSystemType }} | {{ addData.data.operatingSystem }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="RAID类型">{{ addData.data.raidType }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="私有网络">{{ addData.data.virtualPrivateCloud.vpcId }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="子网">{{ addData.data.virtualPrivateCloud.subnetId }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="服务器数量">{{ addData.data.instanceCount }}台</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item v-if="addData.data.internetAccessible.publicIpAssigned" label="弹性公网IP">{{ addData.data.internetAccessible.publicIpAssigned }}Mpbs</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item v-else label="弹性公网IP">不分配</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item v-if="addData.data.virtualPrivateCloud.privateIpAddresses.length > 0" label="服务器内网IP">{{ addData.data.virtualPrivateCloud.privateIpAddresses }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item v-else label="服务器内网IP">自动分配</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="实例名称">{{ addData.data.instanceName }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="登录方式">密码登陆(自定义密码)</cb-form-item>
 | 
				
			||||||
 | 
					    </cb-form>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  props: ['vendorId', 'addData']
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,197 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="">
 | 
				
			||||||
 | 
					    <cb-form :model="addData.data" ref="addData" label-width="140px">
 | 
				
			||||||
 | 
					      <h3>已选配置</h3>
 | 
				
			||||||
 | 
					      <cb-form-item label="机型">{{ addData.selectComboData.flavorName }},{{ addData.selectComboData.cpu }},{{ addData.selectComboData.memory }},{{ addData.selectComboData.systemDisk }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="操作系统">{{ addData.data.operatingSystemType }} | {{ addData.data.operatingSystem }}</cb-form-item>
 | 
				
			||||||
 | 
					      <h3>存储</h3>
 | 
				
			||||||
 | 
					      <cb-form-item label="RAID类型" prop="raidType" validate="required" required-message="请选择RAID类型">
 | 
				
			||||||
 | 
					        <el-select v-model="addData.data.raidType" placeholder="请选择RAID类型" style="width: 160px">
 | 
				
			||||||
 | 
					          <el-option v-for="item in addData.selectComboData.raidType" :key="item" :label="item" :value="item"> </el-option>
 | 
				
			||||||
 | 
					        </el-select>
 | 
				
			||||||
 | 
					        <span style="display: block">系统盘容量为{{ addData.selectComboData.systemDisk }}</span>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <h3>网络</h3>
 | 
				
			||||||
 | 
					      <cb-form-item label="私有网络" prop="virtualPrivateCloud.vpcId" validate="required" required-message="请选择">
 | 
				
			||||||
 | 
					        <el-select v-model="addData.data.virtualPrivateCloud.vpcId" @change="change" placeholder="请选择VPC" style="width: 160px">
 | 
				
			||||||
 | 
					          <el-option v-for="item in vpcList" :key="item.vpcId" :label="item.name" :value="item.vpcId"> </el-option>
 | 
				
			||||||
 | 
					        </el-select>
 | 
				
			||||||
 | 
					        <el-select v-model="addData.data.virtualPrivateCloud.subnetId" placeholder="请选择子网" style="width: 160px; margin-left: 10px">
 | 
				
			||||||
 | 
					          <el-option v-for="item in subNetList" :key="item.subnetId" :label="item.name" :value="item.subnetId"> </el-option>
 | 
				
			||||||
 | 
					        </el-select>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="弹性公网IP">
 | 
				
			||||||
 | 
					        <el-checkbox v-model="addData.data.internetAccessible.publicIpAssigned">弹性公网IP</el-checkbox>  
 | 
				
			||||||
 | 
					        <el-input-number v-if="addData.data.internetAccessible.publicIpAssigned" v-model="addData.data.internetAccessible.internetMaxBandwidthOut" @change="handleChange" :min="0" :max="100"></el-input-number> <template v-if="addData.data.internetAccessible.publicIpAssigned">Mbps</template>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="外网运营商" prop="internetAccessible.internetServiceProvider" required-message="请选择运营商" v-if="addData.data.internetAccessible.publicIpAssigned">
 | 
				
			||||||
 | 
					        <el-select v-model="addData.data.internetAccessible.internetServiceProvider" placeholder="请选择运营商" style="width: 160px">
 | 
				
			||||||
 | 
					          <el-option v-for="item in operatorData.ispInfoSet" :key="item.name" :label="item.name" :value="item.type"> </el-option>
 | 
				
			||||||
 | 
					        </el-select>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="服务器数量"> <el-input-number v-model="addData.data.instanceCount" :min="1" :max="10"></el-input-number>台 </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="服务器内网IP" prop="virtualPrivateCloud.privateIpAddresses">
 | 
				
			||||||
 | 
					        <el-radio v-model="radio" label="1">自动分配</el-radio>
 | 
				
			||||||
 | 
					        <el-radio v-model="radio" label="2">手动指定</el-radio>
 | 
				
			||||||
 | 
					        <div v-if="radio == '2'">
 | 
				
			||||||
 | 
					          <span style="display: block">您需要指定{{ addData.data.instanceCount }}个内网IP,使用","分割</span>
 | 
				
			||||||
 | 
					          <el-input type="textarea" :rows="2" v-model="addData.data.virtualPrivateCloud.privateIpAddresses"> </el-input>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <h3>主机设置</h3>
 | 
				
			||||||
 | 
					      <el-alert title="设置登录密码不支持找回功能,如需重置登录密码需要重装系统,请您牢记密码!" type="warning" :closable="false"> </el-alert>
 | 
				
			||||||
 | 
					      <cb-form-item label="实例名称" prop="instanceName" validate="required" required-message="请输入实例名称">
 | 
				
			||||||
 | 
					        <el-input v-model="addData.data.instanceName"></el-input>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="密码" prop="loginSettings.Password" validate="required,tceClusterPassword" required-message="请输入密码">
 | 
				
			||||||
 | 
					        <el-input v-model="addData.data.loginSettings.Password" show-password></el-input>
 | 
				
			||||||
 | 
					        <span style="display: block">linux机器密码需10到30位,至少包括三项([a-z,A-Z],[0-9]和[()`~!@#$%^&*-+=_|{}[]:;'&It\;>,.?/]的特殊符号)</span>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="确认密码" prop="loginSettings.Password_config" validate="required,tceClusterPassword" required-message="请输入确认密码">
 | 
				
			||||||
 | 
					        <el-input v-model="addData.data.loginSettings.Password_config" show-password></el-input>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <h3>确认信息</h3>
 | 
				
			||||||
 | 
					      <cb-form-item label="地域">重庆</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="可用区">yfm14</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="机型">{{ addData.selectComboData.flavorName }},{{ addData.selectComboData.cpu }},{{ addData.selectComboData.memory }},{{ addData.selectComboData.systemDisk }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="操作系统">{{ addData.data.operatingSystemType }} | {{ addData.data.operatingSystem }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="RAID类型">{{ addData.data.raidType }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="私有网络">{{ getVpcName(addData.data.virtualPrivateCloud.vpcId) }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="子网">{{ getSubnetName(addData.data.virtualPrivateCloud.subnetId) }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="服务器数量">{{ addData.data.instanceCount }}台</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item v-if="addData.data.internetAccessible.publicIpAssigned" label="弹性公网IP">{{ addData.data.internetAccessible.internetMaxBandwidthOut }}Mpbs</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item v-else label="弹性公网IP">不分配</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item v-if="addData.data.virtualPrivateCloud.privateIpAddresses.length > 0" label="服务器内网IP">{{ addData.data.virtualPrivateCloud.privateIpAddresses }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item v-else label="服务器内网IP">自动分配</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="实例名称">{{ addData.data.instanceName }}</cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="登录方式">密码登陆(自定义密码)</cb-form-item>
 | 
				
			||||||
 | 
					    </cb-form>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					import { getOperator, addBMS } from 'views/resource/ctstack/services/bms.js'
 | 
				
			||||||
 | 
					import { getVpc } from 'views/resource/ctstack/services/vpcs.js'
 | 
				
			||||||
 | 
					import { getSubnet } from 'views/resource/ctstack/services/subnet.js'
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  props: ['vendorId', 'addData', 'platformObject'],
 | 
				
			||||||
 | 
					  components: {},
 | 
				
			||||||
 | 
					  data() {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      params: {
 | 
				
			||||||
 | 
					        page: 1,
 | 
				
			||||||
 | 
					        rows: 10
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      searchConfigs: [{ type: 'Const', value: 'vendorId', initValue: this.vendorId }],
 | 
				
			||||||
 | 
					      value8: 0,
 | 
				
			||||||
 | 
					      options: '',
 | 
				
			||||||
 | 
					      checked: true,
 | 
				
			||||||
 | 
					      num1: 1,
 | 
				
			||||||
 | 
					      radio: '1',
 | 
				
			||||||
 | 
					      ruleForm: {},
 | 
				
			||||||
 | 
					      operatorData: {},
 | 
				
			||||||
 | 
					      vpcList: [],
 | 
				
			||||||
 | 
					      subNetList: []
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  computed: {},
 | 
				
			||||||
 | 
					  mounted() {
 | 
				
			||||||
 | 
					    this.getOperatorList()
 | 
				
			||||||
 | 
					    this.getSelectVpc()
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  methods: {
 | 
				
			||||||
 | 
					    // 校验信息
 | 
				
			||||||
 | 
					    getData() {
 | 
				
			||||||
 | 
					      this.$refs.addData.validate(valid => {
 | 
				
			||||||
 | 
					        if (valid) {
 | 
				
			||||||
 | 
					          this.addData.loading = true
 | 
				
			||||||
 | 
					          if (this.addData.data.loginSettings.Password !== this.addData.data.loginSettings.Password_config) {
 | 
				
			||||||
 | 
					            this.$message.error('两次密码输入不一致')
 | 
				
			||||||
 | 
					            this.addData.loading = false
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            this.addData.data.loginSettings.Password = window.btoa(this.addData.data.loginSettings.Password)
 | 
				
			||||||
 | 
					            if (this.addData.data.virtualPrivateCloud.privateIpAddresses == '') {
 | 
				
			||||||
 | 
					              delete this.addData.data.virtualPrivateCloud.privateIpAddresses
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              this.addData.data.virtualPrivateCloud.privateIpAddresses = this.addData.data.virtualPrivateCloud.privateIpAddresses.split(',')
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            const params = this.addData.data
 | 
				
			||||||
 | 
					            addBMS(this.vendorId, params).then(res => {
 | 
				
			||||||
 | 
					              this.$message.success(res.message)
 | 
				
			||||||
 | 
					              this.goBack()
 | 
				
			||||||
 | 
					              this.addData.dialog = false
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    goBack() {
 | 
				
			||||||
 | 
					      this.$router.back(-1)
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 获取运营商
 | 
				
			||||||
 | 
					    getOperatorList() {
 | 
				
			||||||
 | 
					      getOperator({
 | 
				
			||||||
 | 
					        regionId: this.addData.data.regionId
 | 
				
			||||||
 | 
					      }).then(res => {
 | 
				
			||||||
 | 
					        this.operatorData = res.data
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    getSelectVpc() {
 | 
				
			||||||
 | 
					      this.params.params = JSON.stringify([{ param: { vendorId: this.vendorId }, sign: 'EQ' }])
 | 
				
			||||||
 | 
					      getVpc(this.params).then(res => {
 | 
				
			||||||
 | 
					        this.vpcList = res.data.rows
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    getVpcName(id) {
 | 
				
			||||||
 | 
					      let name = ''
 | 
				
			||||||
 | 
					      this.vpcList.forEach(item => {
 | 
				
			||||||
 | 
					        if (item.vpcId == id) {
 | 
				
			||||||
 | 
					          name = item.name
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      return name
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    getSubnetName(id) {
 | 
				
			||||||
 | 
					      let name = ''
 | 
				
			||||||
 | 
					      this.subNetList.forEach(item => {
 | 
				
			||||||
 | 
					        if (item.subnetId == id) {
 | 
				
			||||||
 | 
					          name = item.name
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      return name
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    change() {
 | 
				
			||||||
 | 
					      const param = {
 | 
				
			||||||
 | 
					        type: 9,
 | 
				
			||||||
 | 
					        vendorId: this.vendorId,
 | 
				
			||||||
 | 
					        vpcUuid: this.addData.data.virtualPrivateCloud.vpcId,
 | 
				
			||||||
 | 
					        regionId: this.addData.data.regionId,
 | 
				
			||||||
 | 
					        zone: this.addData.data.zone
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      const params = {
 | 
				
			||||||
 | 
					        page: 1,
 | 
				
			||||||
 | 
					        rows: 9999,
 | 
				
			||||||
 | 
					        params: JSON.stringify([{ param, sign: 'EQ' }])
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      getSubnet(params).then(res => {
 | 
				
			||||||
 | 
					        this.subNetList = res.data.rows
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					span {
 | 
				
			||||||
 | 
					  font-size: 12px;
 | 
				
			||||||
 | 
					  color: #ccc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.el-alert {
 | 
				
			||||||
 | 
					  margin-left: 25px;
 | 
				
			||||||
 | 
					  width: 800px;
 | 
				
			||||||
 | 
					  border: 1px solid orange;
 | 
				
			||||||
 | 
					  margin-bottom: 30px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.el-input {
 | 
				
			||||||
 | 
					  width: 300px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,180 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <el-dialog title="分配" :close-on-click-modal="false" v-if="addData.dialog" :visible.sync="addData.dialog">
 | 
				
			||||||
 | 
					    <cb-form :model="addData.data" label-width="100px" ref="authData">
 | 
				
			||||||
 | 
					      <cb-form-item label="分配方式:" prop="type" validate="required" v-if="showType">
 | 
				
			||||||
 | 
					        <el-radio-group v-model="addData.data.type" size="mini" @change="getList">
 | 
				
			||||||
 | 
					          <el-radio-button label="tenant">租户</el-radio-button>
 | 
				
			||||||
 | 
					        </el-radio-group>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="租户列表:" prop="tenantId" validate="required" v-if="addData.data.type == 'tenant'" key="tenant">
 | 
				
			||||||
 | 
					        <el-select v-model="addData.data.tenantId" @change="handleSearchProject" filterable>
 | 
				
			||||||
 | 
					          <el-option v-for="(item, index) in tenantList" :key="index" :label="item.name" :value="item.id"></el-option>
 | 
				
			||||||
 | 
					        </el-select>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="系统列表:" prop="projectId" v-if="showType && addData.data.type == 'tenant'" key="1">
 | 
				
			||||||
 | 
					        <el-select v-model="addData.data.projectId" placeholder="请选择" filterable @change="getTenantData">
 | 
				
			||||||
 | 
					          <el-option v-for="item in projectList" :key="item.id" :label="item.name" :value="item.id"></el-option>
 | 
				
			||||||
 | 
					        </el-select>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					      <cb-form-item label="系统列表:" prop="projectId" validate="required" v-if="showType && addData.data.type == 'all'" key="2">
 | 
				
			||||||
 | 
					        <el-select v-model="addData.data.projectId" placeholder="请选择" filterable @change="getTenantData">
 | 
				
			||||||
 | 
					          <el-option v-for="item in projectList" :key="item.id" :label="item.name" :value="item.id"></el-option>
 | 
				
			||||||
 | 
					        </el-select>
 | 
				
			||||||
 | 
					      </cb-form-item>
 | 
				
			||||||
 | 
					    </cb-form>
 | 
				
			||||||
 | 
					    <div slot="footer" class="dialog-footer">
 | 
				
			||||||
 | 
					      <el-button type="ghost" @click.native="addData.dialog = false">取消</el-button>
 | 
				
			||||||
 | 
					      <el-button type="primary" @click.native="authSubmit" :disabled="disabled" :loading="loading">确定</el-button>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </el-dialog>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					import { getProject } from 'views/resource/ctstack/services/projects.js'
 | 
				
			||||||
 | 
					import { getListTenantTree } from 'views/resource/ctstack/services/tenants.js'
 | 
				
			||||||
 | 
					import { getUser } from 'views/resource/ctstack/services/users.js'
 | 
				
			||||||
 | 
					import { vmUsers } from 'views/resource/ctstack/services/vm.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  props: {
 | 
				
			||||||
 | 
					    addData: {
 | 
				
			||||||
 | 
					      type: Object,
 | 
				
			||||||
 | 
					      default: function () {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          data: {
 | 
				
			||||||
 | 
					            months: 1,
 | 
				
			||||||
 | 
					            userId: '',
 | 
				
			||||||
 | 
					            projectId: ''
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          dialog: false
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    showType: {
 | 
				
			||||||
 | 
					      type: Boolean,
 | 
				
			||||||
 | 
					      default: true
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  data() {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      userList: [],
 | 
				
			||||||
 | 
					      projectList: [],
 | 
				
			||||||
 | 
					      props: {
 | 
				
			||||||
 | 
					        label: 'name',
 | 
				
			||||||
 | 
					        value: 'id',
 | 
				
			||||||
 | 
					        children: 'children'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      departMap: {},
 | 
				
			||||||
 | 
					      tenantList: [],
 | 
				
			||||||
 | 
					      disabled: false,
 | 
				
			||||||
 | 
					      loading: false
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  methods: {
 | 
				
			||||||
 | 
					    getList() {
 | 
				
			||||||
 | 
					      if (this.addData.data.type == 'tenant') {
 | 
				
			||||||
 | 
					        if (this.addData.data.projectId) this.$set(this.addData.data, 'projectId', '')
 | 
				
			||||||
 | 
					        if (this.addData.data.userId) this.$set(this.addData.data, 'userId', '')
 | 
				
			||||||
 | 
					        if (this.addData.data.tenantId) this.$set(this.addData.data, 'tenantId', '')
 | 
				
			||||||
 | 
					        this.getTenantList()
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        if (this.addData.data.projectId) this.$set(this.addData.data, 'projectId', '')
 | 
				
			||||||
 | 
					        if (this.addData.data.userId) this.$set(this.addData.data, 'userId', '')
 | 
				
			||||||
 | 
					        this.getAllTenant()
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    authSubmit() {
 | 
				
			||||||
 | 
					      this.$refs.authData.validate(valid => {
 | 
				
			||||||
 | 
					        if (valid) {
 | 
				
			||||||
 | 
					          this.loading = true
 | 
				
			||||||
 | 
					          let obj = {}
 | 
				
			||||||
 | 
					          if (this.addData.data.type == 'tenant') {
 | 
				
			||||||
 | 
					            obj = {
 | 
				
			||||||
 | 
					              ids: this.addData.data.ids,
 | 
				
			||||||
 | 
					              userId: this.addData.data.userId,
 | 
				
			||||||
 | 
					              projectId: this.addData.data.projectId,
 | 
				
			||||||
 | 
					              tenantId: this.addData.data.tenantId,
 | 
				
			||||||
 | 
					              resourceCategory: this.addData.data.resourceCategory,
 | 
				
			||||||
 | 
					              vendorType: this.addData.data.vendorType
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            obj = {
 | 
				
			||||||
 | 
					              ids: this.addData.data.ids,
 | 
				
			||||||
 | 
					              userId: this.addData.data.userId,
 | 
				
			||||||
 | 
					              projectId: this.addData.data.projectId,
 | 
				
			||||||
 | 
					              resourceCategory: this.addData.data.resourceCategory,
 | 
				
			||||||
 | 
					              vendorType: this.addData.data.vendorType
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          vmUsers(obj).then(data => {
 | 
				
			||||||
 | 
					            if (data.success) {
 | 
				
			||||||
 | 
					              this.$message.success(data.message)
 | 
				
			||||||
 | 
					              this.addData.dialog = false
 | 
				
			||||||
 | 
					              this.$emit('back')
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            this.loading = false
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 获取租户列表
 | 
				
			||||||
 | 
					    getTenantList(value) {
 | 
				
			||||||
 | 
					      getListTenantTree({ parentId: 0 })
 | 
				
			||||||
 | 
					        .then(data => {
 | 
				
			||||||
 | 
					          if (data.success) {
 | 
				
			||||||
 | 
					            this.tenantList = data.data
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .finally(() => {
 | 
				
			||||||
 | 
					          this.loading = false
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 获取系统
 | 
				
			||||||
 | 
					    handleSearchProject() {
 | 
				
			||||||
 | 
					      if (this.addData.data.vendorType == 'OPENSTACK' && this.addData.data.resourceCategory == 'Storage') this.getTenantData()
 | 
				
			||||||
 | 
					      if (this.addData.data.projectId) this.$set(this.addData.data, 'projectId', '')
 | 
				
			||||||
 | 
					      getProject({
 | 
				
			||||||
 | 
					        page: 1,
 | 
				
			||||||
 | 
					        rows: 9999,
 | 
				
			||||||
 | 
					        params: JSON.stringify([{ param: { tenantId: this.addData.data.tenantId }, sign: 'EQ' }])
 | 
				
			||||||
 | 
					      }).then(data => {
 | 
				
			||||||
 | 
					        if (data.success) {
 | 
				
			||||||
 | 
					          this.projectList = data.data.rows
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    getAllTenant() {
 | 
				
			||||||
 | 
					      getProject({
 | 
				
			||||||
 | 
					        page: 1,
 | 
				
			||||||
 | 
					        rows: 9999,
 | 
				
			||||||
 | 
					        params: JSON.stringify([{ param: { tenantId: 'null' }, sign: 'NUL' }])
 | 
				
			||||||
 | 
					      }).then(data => {
 | 
				
			||||||
 | 
					        if (data.success) {
 | 
				
			||||||
 | 
					          this.projectList = data.data.rows
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 获取租户
 | 
				
			||||||
 | 
					    getTenantData(value) {
 | 
				
			||||||
 | 
					      if (this.addData.data.userId) this.$set(this.addData.data, 'userId', '')
 | 
				
			||||||
 | 
					      getUser({
 | 
				
			||||||
 | 
					        simple: true,
 | 
				
			||||||
 | 
					        params: this.handleSearchParam({
 | 
				
			||||||
 | 
					          projectId: this.addData.data.projectId,
 | 
				
			||||||
 | 
					          tenantId: this.addData.data.projectId ? '' : this.addData.data.tenantId
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      }).then(data => {
 | 
				
			||||||
 | 
					        if (data.success) {
 | 
				
			||||||
 | 
					          this.userList = data.data.rows
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  mounted() {},
 | 
				
			||||||
 | 
					  created() {
 | 
				
			||||||
 | 
					    this.projectList = []
 | 
				
			||||||
 | 
					    this.userList = []
 | 
				
			||||||
 | 
					    this.getList()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,479 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div>
 | 
				
			||||||
 | 
					    <cb-advance-table title="" :data="data" :params="params" :columns="columns" :get-list="getList" :total="total" @select="handleSelectItem" @select-all="handleSelectAll" :loading="loading" :search-configs="searchConfigs">
 | 
				
			||||||
 | 
					      <template v-slot:action>
 | 
				
			||||||
 | 
					        <el-button type="primary" @click="handleAdd()"> 新增 </el-button>
 | 
				
			||||||
 | 
					      </template>
 | 
				
			||||||
 | 
					      <template #instanceId="val, record">
 | 
				
			||||||
 | 
					        <span class="detail-href" @click="getDiskList(record)">{{ val }}</span>
 | 
				
			||||||
 | 
					      </template>
 | 
				
			||||||
 | 
					      <template #state="val">
 | 
				
			||||||
 | 
					        <cb-status-icon :type="val | bareMetalColor">{{ val | bareMetalState }}</cb-status-icon>
 | 
				
			||||||
 | 
					      </template>
 | 
				
			||||||
 | 
					      <template #operate="val, record">
 | 
				
			||||||
 | 
					        <el-button type="text" @click="reboot(record)"> 重启 </el-button>
 | 
				
			||||||
 | 
					        <div class="action-divider"></div>
 | 
				
			||||||
 | 
					        <el-button type="text" @click="bootup(record)"> 开机 </el-button>
 | 
				
			||||||
 | 
					        <div class="action-divider"></div>
 | 
				
			||||||
 | 
					        <el-button type="text" @click="stop(record)"> 关机 </el-button>
 | 
				
			||||||
 | 
					        <div class="action-divider"></div>
 | 
				
			||||||
 | 
					        <el-dropdown trigger="click">
 | 
				
			||||||
 | 
					          <span class="el-dropdown-link"> 更多<i class="el-icon-arrow-down el-icon--right"></i> </span>
 | 
				
			||||||
 | 
					          <el-dropdown-menu slot="dropdown">
 | 
				
			||||||
 | 
					            <el-dropdown-item @click.native="edt(record)" :disabled="record.status == 'PENDING'"> 退还 </el-dropdown-item>
 | 
				
			||||||
 | 
					            <el-dropdown-item @click.native="reload(record)"> 重装 </el-dropdown-item>
 | 
				
			||||||
 | 
					            <el-dropdown-item @click.native="edit(record)"> 改名 </el-dropdown-item>
 | 
				
			||||||
 | 
					            <el-dropdown-item @click.native="edit(record)" disabled> 分配 </el-dropdown-item>
 | 
				
			||||||
 | 
					            <el-dropdown-item @click.native="edit(record)" disabled> 回收 </el-dropdown-item>
 | 
				
			||||||
 | 
					          </el-dropdown-menu>
 | 
				
			||||||
 | 
					        </el-dropdown>
 | 
				
			||||||
 | 
					      </template>
 | 
				
			||||||
 | 
					    </cb-advance-table>
 | 
				
			||||||
 | 
					    <!-- 更改名称 -->
 | 
				
			||||||
 | 
					    <el-dialog width="30%" title="更改名称" :close-on-click-modal="false" v-if="editData.dialog" :visible.sync="editData.dialog">
 | 
				
			||||||
 | 
					      <cb-form :model="editData.data" ref="editData" label-width="50px">
 | 
				
			||||||
 | 
					        <cb-form-item label="名称" prop="newName">
 | 
				
			||||||
 | 
					          <el-input v-model="editData.data.newName"></el-input>
 | 
				
			||||||
 | 
					        </cb-form-item>
 | 
				
			||||||
 | 
					      </cb-form>
 | 
				
			||||||
 | 
					      <div slot="footer" class="dialog-footer">
 | 
				
			||||||
 | 
					        <el-button type="ghost" @click.native="editData.dialog = false">取消</el-button>
 | 
				
			||||||
 | 
					        <el-button type="primary" @click.native="editSubmit">确定</el-button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </el-dialog>
 | 
				
			||||||
 | 
					    <!-- 硬盘列表 -->
 | 
				
			||||||
 | 
					    <el-dialog width="50%" title="硬盘列表" :close-on-click-modal="false" v-if="diskSign" :visible.sync="diskSign">
 | 
				
			||||||
 | 
					      <cb-smart-table ref="list" :data="diskData" :rows="5" style="margin-top: 10px">
 | 
				
			||||||
 | 
					        <el-table-column show-overflow-tooltip label="硬盘ID" prop="diskId"></el-table-column>
 | 
				
			||||||
 | 
					        <el-table-column show-overflow-tooltip label="硬盘名称" prop="diskName"></el-table-column>
 | 
				
			||||||
 | 
					        <el-table-column show-overflow-tooltip label="硬盘大小" prop="diskSize"></el-table-column>
 | 
				
			||||||
 | 
					        <el-table-column show-overflow-tooltip label="硬盘类型" prop="diskType"></el-table-column>
 | 
				
			||||||
 | 
					        <el-table-column show-overflow-tooltip label="创建时间" prop="createdTime"></el-table-column>
 | 
				
			||||||
 | 
					      </cb-smart-table>
 | 
				
			||||||
 | 
					      <div slot="footer" class="dialog-footer">
 | 
				
			||||||
 | 
					        <el-button type="ghost" @click.native="diskSign = false">取消</el-button>
 | 
				
			||||||
 | 
					        <el-button type="primary" @click.native="diskSign = false">确定</el-button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </el-dialog>
 | 
				
			||||||
 | 
					    <!-- 重装 -->
 | 
				
			||||||
 | 
					    <el-dialog width="45%" title="重装" :close-on-click-modal="false" v-if="Reloading" :visible.sync="Reloading" :append-to-body="true">
 | 
				
			||||||
 | 
					      <cb-form :model="reloadData.data" ref="reloadData" label-width="140px">
 | 
				
			||||||
 | 
					        <h3>当前配置</h3>
 | 
				
			||||||
 | 
					        <cb-form-item label="镜像名称">{{ reloadData.row.operatingSystemType }}</cb-form-item>
 | 
				
			||||||
 | 
					        <cb-form-item label="RAID类型">{{ reloadData.row.raidType }}</cb-form-item>
 | 
				
			||||||
 | 
					        <h3>重装为</h3>
 | 
				
			||||||
 | 
					        <cb-form-item label="镜像类型">{{ reloadData.row.operatingSystemType }}</cb-form-item>
 | 
				
			||||||
 | 
					        <cb-form-item label="镜像">
 | 
				
			||||||
 | 
					          <el-select v-model="reloadData.data.operatingSystem" placeholder="请选择镜像">
 | 
				
			||||||
 | 
					            <el-option v-for="item in selectCombo.operatingSystem.linux" :key="item" :label="item" :value="item"> </el-option>
 | 
				
			||||||
 | 
					          </el-select>
 | 
				
			||||||
 | 
					        </cb-form-item>
 | 
				
			||||||
 | 
					        <cb-form-item label="RAID类型" prop="raidType">
 | 
				
			||||||
 | 
					          <el-select v-model="reloadData.data.raidType" placeholder="请选择类型">
 | 
				
			||||||
 | 
					            <el-option v-for="item in selectCombo.raidType" :key="item" :label="item" :value="item"> </el-option>
 | 
				
			||||||
 | 
					          </el-select>
 | 
				
			||||||
 | 
					        </cb-form-item>
 | 
				
			||||||
 | 
					        <cb-form-item label="主机安全agent">
 | 
				
			||||||
 | 
					          <el-radio v-model="reloadData.data.enhancedService.SecurityService.Enabled" label="true">开启</el-radio>
 | 
				
			||||||
 | 
					          <el-radio v-model="reloadData.data.enhancedService.SecurityService.Enabled" label="false">关闭</el-radio>
 | 
				
			||||||
 | 
					        </cb-form-item>
 | 
				
			||||||
 | 
					        <cb-form-item label="新密码" prop="loginSettings.Password" validate="required,tceClusterPassword" required-message="请输入密码">
 | 
				
			||||||
 | 
					          <el-input v-model="reloadData.data.loginSettings.Password" show-password></el-input>
 | 
				
			||||||
 | 
					          <span style="display: block; font-size: 8px">请输入8~16位密码,密码需要包含字母,数字和特殊符号三种中的三种</span>
 | 
				
			||||||
 | 
					        </cb-form-item>
 | 
				
			||||||
 | 
					        <cb-form-item label="确认密码" prop="loginSettings.Password_config" validate="required,tceClusterPassword" required-message="请输入确认密码">
 | 
				
			||||||
 | 
					          <el-input v-model="reloadData.data.loginSettings.Password_config" show-password></el-input>
 | 
				
			||||||
 | 
					        </cb-form-item>
 | 
				
			||||||
 | 
					      </cb-form>
 | 
				
			||||||
 | 
					      <div slot="footer" class="dialog-footer">
 | 
				
			||||||
 | 
					        <el-button type="ghost" @click.native="Reloading = false">取消</el-button>
 | 
				
			||||||
 | 
					        <el-button type="primary" :loading="subLoading" @click.native="ok">确定</el-button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </el-dialog>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					import { bareMetalState, bareMetalColor } from 'filters'
 | 
				
			||||||
 | 
					import { getBareMetalList, modifyBareMetal, bmsReboot, bmsBootUp, bmsStop, bmsedt, getDisk, getCombo, bmsReload } from 'views/resource/ctstack/services/bms.js'
 | 
				
			||||||
 | 
					import { removeVmUsers } from 'views/resource/ctstack/services/vm.js'
 | 
				
			||||||
 | 
					const columns = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    type: 'selection'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: 'ID',
 | 
				
			||||||
 | 
					    prop: 'instanceId',
 | 
				
			||||||
 | 
					    disabled: true,
 | 
				
			||||||
 | 
					    scopedSlots: { customRender: 'instanceId' }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '名称',
 | 
				
			||||||
 | 
					    prop: 'instanceName',
 | 
				
			||||||
 | 
					    disabled: true
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '状态',
 | 
				
			||||||
 | 
					    prop: 'status',
 | 
				
			||||||
 | 
					    scopedSlots: { customRender: 'state' }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '机型',
 | 
				
			||||||
 | 
					    prop: 'flavorName'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '可用区',
 | 
				
			||||||
 | 
					    prop: 'zone'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '私有网络',
 | 
				
			||||||
 | 
					    prop: 'vpcId'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '子网',
 | 
				
			||||||
 | 
					    prop: 'subnetId'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '公网IP',
 | 
				
			||||||
 | 
					    prop: ''
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '内网IP',
 | 
				
			||||||
 | 
					    prop: ''
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '操作系统',
 | 
				
			||||||
 | 
					    prop: 'operatingSystemType'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: 'RAID类型',
 | 
				
			||||||
 | 
					    prop: 'raidType'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: '操作',
 | 
				
			||||||
 | 
					    disabled: true,
 | 
				
			||||||
 | 
					    width: '220px',
 | 
				
			||||||
 | 
					    scopedSlots: { customRender: 'operate' }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  components: {},
 | 
				
			||||||
 | 
					  props: {
 | 
				
			||||||
 | 
					    platformObject: {
 | 
				
			||||||
 | 
					      type: Object,
 | 
				
			||||||
 | 
					      default: function () {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          huaweiId: -1,
 | 
				
			||||||
 | 
					          operate: -1
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  data() {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      columns,
 | 
				
			||||||
 | 
					      loading: false,
 | 
				
			||||||
 | 
					      subLoading: false,
 | 
				
			||||||
 | 
					      params: {
 | 
				
			||||||
 | 
					        page: 1,
 | 
				
			||||||
 | 
					        rows: 10
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      data: [],
 | 
				
			||||||
 | 
					      total: 0,
 | 
				
			||||||
 | 
					      searchConfigs: [{ type: 'Const', value: 'vendorId', initValue: this.platformObject.vendorId }],
 | 
				
			||||||
 | 
					      // 编辑数据
 | 
				
			||||||
 | 
					      editData: {
 | 
				
			||||||
 | 
					        dialog: false,
 | 
				
			||||||
 | 
					        data: {}
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      diskSign: false,
 | 
				
			||||||
 | 
					      diskData: [],
 | 
				
			||||||
 | 
					      // 重装
 | 
				
			||||||
 | 
					      Reloading: false,
 | 
				
			||||||
 | 
					      ruleForm: {},
 | 
				
			||||||
 | 
					      reloadData: {
 | 
				
			||||||
 | 
					        data: {
 | 
				
			||||||
 | 
					          instanceId: '',
 | 
				
			||||||
 | 
					          raidType: '',
 | 
				
			||||||
 | 
					          operatingSystemType: '',
 | 
				
			||||||
 | 
					          operatingSystem: '',
 | 
				
			||||||
 | 
					          loginSettings: {
 | 
				
			||||||
 | 
					            Password: '',
 | 
				
			||||||
 | 
					            Password_config: ''
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          enhancedService: {
 | 
				
			||||||
 | 
					            SecurityService: {
 | 
				
			||||||
 | 
					              Enabled: ''
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        row: {}
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      comboData: '',
 | 
				
			||||||
 | 
					      selectCombo: {},
 | 
				
			||||||
 | 
					      assignData: {
 | 
				
			||||||
 | 
					        dialog: false,
 | 
				
			||||||
 | 
					        data: {}
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  methods: {
 | 
				
			||||||
 | 
					    // 重装
 | 
				
			||||||
 | 
					    ok() {
 | 
				
			||||||
 | 
					      this.$refs.reloadData.validate(valid => {
 | 
				
			||||||
 | 
					        if (valid) {
 | 
				
			||||||
 | 
					          this.subLoading = true
 | 
				
			||||||
 | 
					          if (this.reloadData.data.loginSettings.Password !== this.reloadData.data.loginSettings.Password_config) {
 | 
				
			||||||
 | 
					            this.$message.error('两次密码输入不一致')
 | 
				
			||||||
 | 
					            this.subLoading = false
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            this.reloadData.data.loginSettings.Password = window.btoa(this.reloadData.data.loginSettings.Password)
 | 
				
			||||||
 | 
					            bmsReload(this.platformObject.vendorId, this.reloadData.data).then(res => {
 | 
				
			||||||
 | 
					              this.subLoading = false
 | 
				
			||||||
 | 
					              if (res.success) {
 | 
				
			||||||
 | 
					                this.$message.success(res.message)
 | 
				
			||||||
 | 
					                this.Reloading = false
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    reload(row) {
 | 
				
			||||||
 | 
					      const params = {
 | 
				
			||||||
 | 
					        zone: ['yfm14az1']
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      getCombo(this.platformObject.vendorId, params).then(res => {
 | 
				
			||||||
 | 
					        this.comboData = res.data.flavorSet
 | 
				
			||||||
 | 
					        this.Reloading = true
 | 
				
			||||||
 | 
					        this.reloadData.row = row
 | 
				
			||||||
 | 
					        this.reloadData.data = {
 | 
				
			||||||
 | 
					          instanceId: row.instanceId,
 | 
				
			||||||
 | 
					          raidType: row.raidType,
 | 
				
			||||||
 | 
					          operatingSystemType: row.operatingSystemType,
 | 
				
			||||||
 | 
					          operatingSystem: row.operatingSystem,
 | 
				
			||||||
 | 
					          loginSettings: {
 | 
				
			||||||
 | 
					            Password: ''
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          enhancedService: {
 | 
				
			||||||
 | 
					            SecurityService: {
 | 
				
			||||||
 | 
					              Enabled: 'false'
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this.comboData.forEach(item => {
 | 
				
			||||||
 | 
					          if (item.flavorId == row.flavorId) {
 | 
				
			||||||
 | 
					            this.selectCombo = item
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 获取套参
 | 
				
			||||||
 | 
					    getArea() {
 | 
				
			||||||
 | 
					      // 获取套餐
 | 
				
			||||||
 | 
					      const params = {
 | 
				
			||||||
 | 
					        zone: ['yfm14az1']
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      getCombo(this.platformObject.vendorId, params).then(res => {
 | 
				
			||||||
 | 
					        this.comboData = res.data.flavorSet
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 获取硬盘列表
 | 
				
			||||||
 | 
					    getDiskList(row) {
 | 
				
			||||||
 | 
					      this.diskSign = true
 | 
				
			||||||
 | 
					      getDisk({ id: row.id }).then(res => {
 | 
				
			||||||
 | 
					        this.diskData = res.data
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    handleAdd() {
 | 
				
			||||||
 | 
					      this.$router.push({ name: 'ctstackAddBareMetal', query: { vendorId: this.platformObject.vendorId } })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 退还实例
 | 
				
			||||||
 | 
					    edt(row) {
 | 
				
			||||||
 | 
					      this.$confirm('此操作将退还实例,退回后,磁盘将被格式化且不可恢复,请提前备份数据。物理服务器关联的网络资源将自动解除。是否继续?', '提示', {
 | 
				
			||||||
 | 
					        confirmButtonText: '退还',
 | 
				
			||||||
 | 
					        cancelButtonText: '取消',
 | 
				
			||||||
 | 
					        type: 'warning'
 | 
				
			||||||
 | 
					      }).then(() => {
 | 
				
			||||||
 | 
					        this.$cmpDelete(close => {
 | 
				
			||||||
 | 
					          bmsedt([row.instanceId]).then(data => {
 | 
				
			||||||
 | 
					            if (data.success) {
 | 
				
			||||||
 | 
					              this.$message({
 | 
				
			||||||
 | 
					                type: 'success',
 | 
				
			||||||
 | 
					                message: data.message
 | 
				
			||||||
 | 
					              })
 | 
				
			||||||
 | 
					              setTimeout(() => {
 | 
				
			||||||
 | 
					                this.getList()
 | 
				
			||||||
 | 
					              }, 5000)
 | 
				
			||||||
 | 
					              close()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    reboot(row) {
 | 
				
			||||||
 | 
					      bmsReboot({ id: row.id }).then(data => {
 | 
				
			||||||
 | 
					        if (data.success) {
 | 
				
			||||||
 | 
					          this.$message({
 | 
				
			||||||
 | 
					            type: 'success',
 | 
				
			||||||
 | 
					            message: data.message
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					          setTimeout(() => {
 | 
				
			||||||
 | 
					            this.getList()
 | 
				
			||||||
 | 
					          }, 2000)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        setTimeout(() => {
 | 
				
			||||||
 | 
					          this.getList()
 | 
				
			||||||
 | 
					        }, 70000)
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    bootup(row) {
 | 
				
			||||||
 | 
					      bmsBootUp({ id: row.id }).then(data => {
 | 
				
			||||||
 | 
					        if (data.success) {
 | 
				
			||||||
 | 
					          this.$message({
 | 
				
			||||||
 | 
					            type: 'success',
 | 
				
			||||||
 | 
					            message: data.message
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					          setTimeout(() => {
 | 
				
			||||||
 | 
					            this.getList()
 | 
				
			||||||
 | 
					          }, 2000)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        setTimeout(() => {
 | 
				
			||||||
 | 
					          this.getList()
 | 
				
			||||||
 | 
					        }, 25000)
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    stop(row) {
 | 
				
			||||||
 | 
					      bmsStop({ id: row.id }).then(data => {
 | 
				
			||||||
 | 
					        if (data.success) {
 | 
				
			||||||
 | 
					          this.$message({
 | 
				
			||||||
 | 
					            type: 'success',
 | 
				
			||||||
 | 
					            message: data.message
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					          setTimeout(() => {
 | 
				
			||||||
 | 
					            this.getList()
 | 
				
			||||||
 | 
					          }, 2000)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        setTimeout(() => {
 | 
				
			||||||
 | 
					          this.getList()
 | 
				
			||||||
 | 
					        }, 45000)
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    edit(row) {
 | 
				
			||||||
 | 
					      this.editData = {
 | 
				
			||||||
 | 
					        dialog: true,
 | 
				
			||||||
 | 
					        data: {
 | 
				
			||||||
 | 
					          id: row.id,
 | 
				
			||||||
 | 
					          instanceId: row.instanceId,
 | 
				
			||||||
 | 
					          newName: row.instanceName
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    editSubmit() {
 | 
				
			||||||
 | 
					      this.$refs.editData.validate(valid => {
 | 
				
			||||||
 | 
					        if (valid) {
 | 
				
			||||||
 | 
					          modifyBareMetal(this.editData.data).then(res => {
 | 
				
			||||||
 | 
					            if (res.success) {
 | 
				
			||||||
 | 
					              this.$message.success(res.message)
 | 
				
			||||||
 | 
					              this.editData.dialog = false
 | 
				
			||||||
 | 
					              this.getList()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 全选
 | 
				
			||||||
 | 
					    handleSelectAll(selection) {
 | 
				
			||||||
 | 
					      this.refreshId()
 | 
				
			||||||
 | 
					      if (selection.length) {
 | 
				
			||||||
 | 
					        // 全选情况下
 | 
				
			||||||
 | 
					        selection.forEach(item => {
 | 
				
			||||||
 | 
					          if (this.idList.indexOf(item.id) == -1) {
 | 
				
			||||||
 | 
					            this.selectList.push(item)
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        // 全不选情况下
 | 
				
			||||||
 | 
					        this.list.forEach(item => {
 | 
				
			||||||
 | 
					          if (this.idList.indexOf(item.id) > -1) {
 | 
				
			||||||
 | 
					            for (let j = 0; j < this.selectList.length; j++) {
 | 
				
			||||||
 | 
					              const row = this.selectList[j]
 | 
				
			||||||
 | 
					              if (item.id == row.id) {
 | 
				
			||||||
 | 
					                this.selectList.splice(j, 1)
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    assign(row) {
 | 
				
			||||||
 | 
					      this.assignData = {
 | 
				
			||||||
 | 
					        dialog: true,
 | 
				
			||||||
 | 
					        data: {
 | 
				
			||||||
 | 
					          type: 'tenant',
 | 
				
			||||||
 | 
					          ids: [row.id],
 | 
				
			||||||
 | 
					          resourceCategory: 'Bms',
 | 
				
			||||||
 | 
					          vendorType: 'CTSTACK'
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    recycle(row) {
 | 
				
			||||||
 | 
					      this.$confirm('确认回收该资源嘛?', '提示', {
 | 
				
			||||||
 | 
					        confirmButtonText: '确定',
 | 
				
			||||||
 | 
					        cancelButtonText: '取消',
 | 
				
			||||||
 | 
					        type: 'warning'
 | 
				
			||||||
 | 
					      }).then(() => {
 | 
				
			||||||
 | 
					        const params = {
 | 
				
			||||||
 | 
					          ids: [row.id],
 | 
				
			||||||
 | 
					          resourceCategory: 'Bms',
 | 
				
			||||||
 | 
					          vendorType: 'CTSTACK'
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        removeVmUsers(params).then(data => {
 | 
				
			||||||
 | 
					          this.$message.success(data.message)
 | 
				
			||||||
 | 
					          this.getList()
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    getList() {
 | 
				
			||||||
 | 
					      this.loading = true
 | 
				
			||||||
 | 
					      // const params = {
 | 
				
			||||||
 | 
					      //   page: this.params.page,
 | 
				
			||||||
 | 
					      //   rows: this.params.rows,
 | 
				
			||||||
 | 
					      //   params: JSON.stringify([{
 | 
				
			||||||
 | 
					      //     param: {
 | 
				
			||||||
 | 
					      //       vendorId: this.platformObject.vendorId,
 | 
				
			||||||
 | 
					      //     },
 | 
				
			||||||
 | 
					      //     sign: 'EQ'
 | 
				
			||||||
 | 
					      //   }])
 | 
				
			||||||
 | 
					      // }
 | 
				
			||||||
 | 
					      getBareMetalList(this.params)
 | 
				
			||||||
 | 
					        .then(res => {
 | 
				
			||||||
 | 
					          if (res.success) {
 | 
				
			||||||
 | 
					            this.data = res.data.rows
 | 
				
			||||||
 | 
					            this.total = res.data.total
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .finally(() => {
 | 
				
			||||||
 | 
					          this.loading = false
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  watch: {
 | 
				
			||||||
 | 
					    platformObject: {
 | 
				
			||||||
 | 
					      handler(newVal, oldVal) {
 | 
				
			||||||
 | 
					        this.searchConfigs = [{ type: 'Const', value: 'vendorId', initValue: this.platformObject.vendorId }]
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      deep: true
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					.el-select {
 | 
				
			||||||
 | 
					  width: 300px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.el-input {
 | 
				
			||||||
 | 
					  width: 300px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					@ -2,9 +2,9 @@
 | 
				
			||||||
  <cb-form :model="addData" ref="addData" label-width="160px">
 | 
					  <cb-form :model="addData" ref="addData" label-width="160px">
 | 
				
			||||||
    <el-row>
 | 
					    <el-row>
 | 
				
			||||||
      <el-col :span="12">
 | 
					      <el-col :span="12">
 | 
				
			||||||
        <cb-form-item label="地域:">
 | 
					        <cb-form-item label="地域:" prop="regionId" validate="required">
 | 
				
			||||||
          <el-select v-model="addData.region" @change="changeRegion">
 | 
					          <el-select v-model="addData.regionId" @change="changeRegion">
 | 
				
			||||||
            <el-option v-for="item in regionList" :key="item.id" :label="item.name" :value="item.code"></el-option>
 | 
					            <el-option v-for="item in regionData" :key="item.id" :label="item.name" :value="item.code"></el-option>
 | 
				
			||||||
          </el-select>
 | 
					          </el-select>
 | 
				
			||||||
        </cb-form-item>
 | 
					        </cb-form-item>
 | 
				
			||||||
      </el-col>
 | 
					      </el-col>
 | 
				
			||||||
| 
						 | 
					@ -166,6 +166,7 @@
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
 | 
					import { getRegion, getZone } from 'services/platform/index'
 | 
				
			||||||
import { getDescribeVersions, getTKERegions, createCluterImages, checkCIDR } from 'views/resource/ctstack/services/tke.js'
 | 
					import { getDescribeVersions, getTKERegions, createCluterImages, checkCIDR } from 'views/resource/ctstack/services/tke.js'
 | 
				
			||||||
import { getVpc } from 'views/resource/ctstack/services/vpcs.js'
 | 
					import { getVpc } from 'views/resource/ctstack/services/vpcs.js'
 | 
				
			||||||
import { getSubnet } from 'views/resource/ctstack/services/subnet.js'
 | 
					import { getSubnet } from 'views/resource/ctstack/services/subnet.js'
 | 
				
			||||||
| 
						 | 
					@ -214,7 +215,7 @@ export default {
 | 
				
			||||||
      systemList: [],
 | 
					      systemList: [],
 | 
				
			||||||
      kubernetesList: [],
 | 
					      kubernetesList: [],
 | 
				
			||||||
      vpcList: [],
 | 
					      vpcList: [],
 | 
				
			||||||
      regionList: [],
 | 
					      regionData: [],
 | 
				
			||||||
      twoMin: 0,
 | 
					      twoMin: 0,
 | 
				
			||||||
      twoMax: 255,
 | 
					      twoMax: 255,
 | 
				
			||||||
      subnetList: [],
 | 
					      subnetList: [],
 | 
				
			||||||
| 
						 | 
					@ -337,7 +338,7 @@ export default {
 | 
				
			||||||
    checkCIDRValue(params) {
 | 
					    checkCIDRValue(params) {
 | 
				
			||||||
      this.CIDRIndex++
 | 
					      this.CIDRIndex++
 | 
				
			||||||
      const index = this.CIDRIndex
 | 
					      const index = this.CIDRIndex
 | 
				
			||||||
      params.region = this.addData.regionId
 | 
					      params.region = this.addData.regionIdId
 | 
				
			||||||
      this.addData.checkLoading = true
 | 
					      this.addData.checkLoading = true
 | 
				
			||||||
      checkCIDR(params).then(data => {
 | 
					      checkCIDR(params).then(data => {
 | 
				
			||||||
        this.addData.checkLoading = false
 | 
					        this.addData.checkLoading = false
 | 
				
			||||||
| 
						 | 
					@ -396,7 +397,6 @@ export default {
 | 
				
			||||||
      this.$refs.addData.validate(valid => {
 | 
					      this.$refs.addData.validate(valid => {
 | 
				
			||||||
        if (valid) {
 | 
					        if (valid) {
 | 
				
			||||||
          this.addData.kubernetesName = this.kubernetesList.find(item => item.version == this.addData.kubernetes).name
 | 
					          this.addData.kubernetesName = this.kubernetesList.find(item => item.version == this.addData.kubernetes).name
 | 
				
			||||||
          this.addData.regionName = this.regionList.find(item => item.alias == this.addData.regionId).regionName
 | 
					 | 
				
			||||||
          this.addData.systemName = this.systemList.find(item => item.osName == this.addData.system).alias
 | 
					          this.addData.systemName = this.systemList.find(item => item.osName == this.addData.system).alias
 | 
				
			||||||
          this.addData.imageId = this.systemList.find(item => item.osName == this.addData.system).imageId
 | 
					          this.addData.imageId = this.systemList.find(item => item.osName == this.addData.system).imageId
 | 
				
			||||||
          this.addData.vpcName = this.vpcList.find(item => item.vpcId == this.addData.vpcId).name
 | 
					          this.addData.vpcName = this.vpcList.find(item => item.vpcId == this.addData.vpcId).name
 | 
				
			||||||
| 
						 | 
					@ -424,10 +424,10 @@ export default {
 | 
				
			||||||
      this.selectionIds = []
 | 
					      this.selectionIds = []
 | 
				
			||||||
      this.addData.selectionSubnet = []
 | 
					      this.addData.selectionSubnet = []
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    getRegionList() {
 | 
					    getregionData() {
 | 
				
			||||||
      getRegion({ vendorId: this.vendorId }).then(data => {
 | 
					      getRegion({ vendorId: this.vendorId }).then(data => {
 | 
				
			||||||
        if (data.success) {
 | 
					        if (data.success) {
 | 
				
			||||||
          this.regionList = data.data
 | 
					          this.regionData = data.data
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
| 
						 | 
					@ -485,7 +485,7 @@ export default {
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  created() {
 | 
					  created() {
 | 
				
			||||||
    this.handleOne(1)
 | 
					    this.handleOne(1)
 | 
				
			||||||
    this.getRegionList()
 | 
					    this.getregionData()
 | 
				
			||||||
    this.getVpc()
 | 
					    this.getVpc()
 | 
				
			||||||
    // this.getImages()
 | 
					    // this.getImages()
 | 
				
			||||||
    // this.getKubernetesList()
 | 
					    // this.getKubernetesList()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,5 +15,7 @@ export default {
 | 
				
			||||||
  ctstackContainer: () => import('views/resource/ctstack/page/container/index.vue'),
 | 
					  ctstackContainer: () => import('views/resource/ctstack/page/container/index.vue'),
 | 
				
			||||||
  ctstackClusterAdd: () => import('views/resource/ctstack/page/container/addCluster.vue'),
 | 
					  ctstackClusterAdd: () => import('views/resource/ctstack/page/container/addCluster.vue'),
 | 
				
			||||||
  ctstackCreateCluster: () => import('views/resource/ctstack/page/container/creatCluster/index.vue'),
 | 
					  ctstackCreateCluster: () => import('views/resource/ctstack/page/container/creatCluster/index.vue'),
 | 
				
			||||||
  ctstackInstanceAdd: () => import('views/resource/ctstack/page/container/instance/create/index.vue')
 | 
					  ctstackInstanceAdd: () => import('views/resource/ctstack/page/container/instance/create/index.vue'),
 | 
				
			||||||
 | 
					  ctstackAddBareMetal: () => import('views/resource/ctstack/page/bareMetal/addBareMetal.vue'),
 | 
				
			||||||
 | 
					  ctstackBareMetal: () => import('views/resource/ctstack/page/bareMetal/index.vue')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,61 @@
 | 
				
			||||||
 | 
					import { request } from '@cmp/cmp-element'
 | 
				
			||||||
 | 
					import { wrapperParams } from 'utils'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function getBareMetalList(params) {
 | 
				
			||||||
 | 
					  return request.get('/cmp/plugins/ctstack/v1/bms', {
 | 
				
			||||||
 | 
					    params
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 新建 获取套餐列表
 | 
				
			||||||
 | 
					export function getCombo(id, params) {
 | 
				
			||||||
 | 
					  return request.post(`/cmp/plugins/ctstack/v1/bms/describeFlavors/${id}`, wrapperParams(params))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					// 获取运营商
 | 
				
			||||||
 | 
					export function getOperator(params) {
 | 
				
			||||||
 | 
					  return request.post('/cmp/plugins/ctstack/v1/bms/describeEIPIspInfo', wrapperParams(params))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					// 获取子网
 | 
				
			||||||
 | 
					export function getBareSubnet(id, params) {
 | 
				
			||||||
 | 
					  return request.post(`/cmp/plugins/ctstack/v1/bms/describeSubnets/${id}`, wrapperParams(params))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 新建BMS
 | 
				
			||||||
 | 
					export function addBMS(id, params) {
 | 
				
			||||||
 | 
					  return request.post(`/cmp/plugins/ctstack/v1/bms/runInstances/${id}`, wrapperParams(params))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 修改BMS名称
 | 
				
			||||||
 | 
					export function modifyBareMetal(params) {
 | 
				
			||||||
 | 
					  return request.post(`/cmp/plugins/ctstack/v1/bms/modifyAttribute/${params.id}`, wrapperParams(params))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 重启
 | 
				
			||||||
 | 
					export function bmsReboot(params) {
 | 
				
			||||||
 | 
					  return request.patch(`/cmp/plugins/ctstack/v1/bms/reboot/${params.id}`)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 开机
 | 
				
			||||||
 | 
					export function bmsBootUp(params) {
 | 
				
			||||||
 | 
					  return request.patch(`/cmp/plugins/ctstack/v1/bms/start/${params.id}`)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 关机
 | 
				
			||||||
 | 
					export function bmsStop(params) {
 | 
				
			||||||
 | 
					  return request.patch(`/cmp/plugins/ctstack/v1/bms/stop/${params.id}`)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 退还实例
 | 
				
			||||||
 | 
					export function bmsedt(params) {
 | 
				
			||||||
 | 
					  return request.post('/cmp/plugins/ctstack/v1/bms/terminateInstances', wrapperParams(params))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 获取硬盘列表
 | 
				
			||||||
 | 
					export function getDisk(params) {
 | 
				
			||||||
 | 
					  return request.get(`/cmp/plugins/ctstack/v1/bms/disks/${params.id}`)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 重装
 | 
				
			||||||
 | 
					export function bmsReload(id, params) {
 | 
				
			||||||
 | 
					  return request.post(`/cmp/plugins/ctstack/v1/bms/resetInstance/${id}`, wrapperParams(params))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue