feat: 数据库对接(待调试)
							parent
							
								
									768259ff5f
								
							
						
					
					
						commit
						01406890f5
					
				| 
						 | 
				
			
			@ -995,5 +995,17 @@ export default {
 | 
			
		|||
      callback()
 | 
			
		||||
    },
 | 
			
		||||
    trigger: trigger
 | 
			
		||||
  },
 | 
			
		||||
  ctstackDatabaseName: {
 | 
			
		||||
    validator: (rule, value, callback) => {
 | 
			
		||||
      // 长度在 4 到 64个字符,必须以字母开头,不区分大小写,可以包含字母、数字、中划线或下划线,不能包含其他特殊字符
 | 
			
		||||
      const reg = /^[a-zA-Z][a-zA-Z0-9_-]{3,63}$/
 | 
			
		||||
      if (reg.test(value)) {
 | 
			
		||||
        callback()
 | 
			
		||||
      } else {
 | 
			
		||||
        callback(new Error('长度在 4 到 64个字符,必须以字母开头,不区分大小写,可以包含字母、数字、中划线或下划线,不能包含其他特殊字符'))
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    trigger: trigger
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,113 +1,117 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <el-dialog v-if="addData.dialog" title="新增RDS" :visible.sync="addData.dialog" width="950px">
 | 
			
		||||
  <el-dialog title="新增数据库" :visible.sync="addData.dialog" top="5vh" width="800px" :close-on-click-modal="false">
 | 
			
		||||
    <el-steps :active="active" finish-status="success">
 | 
			
		||||
      <el-step title="基础资源"></el-step>
 | 
			
		||||
      <el-step title="实例配置"></el-step>
 | 
			
		||||
    </el-steps>
 | 
			
		||||
    <el-row class="box" v-show="active === 0">
 | 
			
		||||
      <cb-form ref="basicData" :model="addData.data" label-width="120px">
 | 
			
		||||
        <cb-form-item label="计费方式: " prop="payType" :rules="[required]">
 | 
			
		||||
          <el-radio-group v-model="addData.data.payType" @change="getFlavorList">
 | 
			
		||||
            <el-radio-button label="Postpaid">后付费(按量付费)</el-radio-button>
 | 
			
		||||
            <el-radio-button disabled label="Prepaid">预付费(包年包月)</el-radio-button>
 | 
			
		||||
      <cb-form ref="basicData" :model="formData" label-width="120px">
 | 
			
		||||
        <cb-form-item label="计费方式: " prop="billMode" :rules="[required]">
 | 
			
		||||
          <el-radio-group v-model="formData.billMode" @change="getFlavorList">
 | 
			
		||||
            <el-radio-button label="2">后付费(按量付费)</el-radio-button>
 | 
			
		||||
            <el-radio-button label="1">预付费(包年包月)</el-radio-button>
 | 
			
		||||
          </el-radio-group>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <region-item :add-data="addData.data"></region-item>
 | 
			
		||||
        <cb-form-item
 | 
			
		||||
          label="实例名称:"
 | 
			
		||||
          prop="name"
 | 
			
		||||
          :rules="[{ pattern: /^[a-zA-Z\u4e00-\u9fa5?!((https?:)\/\/)][a-zA-Z0-9:_-]([a-zA-Z0-9:_-]{1,62})?$/, message: '由字母、数字、中文、下划线(_)、中划线(-)冒号(:)组成,以字母或中文开头,不能以http://或https://开头,长度限制在2-64个字符。', trigger: null }]"
 | 
			
		||||
          validate="required"
 | 
			
		||||
        >
 | 
			
		||||
          <el-input v-model="addData.data.name" placeholder="请输入实例名称" class="basic-cmp"></el-input>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <!-- <el-col :span="12"> -->
 | 
			
		||||
        <cb-form-item label="类型: " prop="dataStoreType" :rules="[required]">
 | 
			
		||||
          <el-select v-model="addData.data.dataStoreType" clearable placeholder="请选择类型" @change="changeType">
 | 
			
		||||
            <el-option v-for="(item, key) in typeList" :key="key" :value="key" :label="key"></el-option>
 | 
			
		||||
        <cb-form-item label="地域: " prop="regionId" :rules="[required]">
 | 
			
		||||
          <el-select v-model="formData.regionId" clearable placeholder="请选择地域" @change="changeRegion">
 | 
			
		||||
            <el-option v-for="item in regionData" :key="item.code" :value="item.code" :label="item.name"></el-option>
 | 
			
		||||
          </el-select>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <!-- </el-col> -->
 | 
			
		||||
        <!-- <el-col :span="12"> -->
 | 
			
		||||
        <cb-form-item label="版本: " prop="dataStoreVersion" :rules="[required]">
 | 
			
		||||
          <el-select v-model="addData.data.dataStoreVersion" clearable placeholder="请选择版本" @change="changeVersion">
 | 
			
		||||
            <el-option v-for="item in versionList" :key="item.value" :value="item.value" :label="item.name"></el-option>
 | 
			
		||||
        <cb-form-item label="企业项目: " prop="projectId" :rules="[required]">
 | 
			
		||||
          <el-select v-model="formData.projectId" clearable placeholder="请选择企业项目" @change="changeProject">
 | 
			
		||||
            <el-option v-for="item in projectList" :key="item.projectSetId" :value="item.projectSetId" :label="item.projectSetName"></el-option>
 | 
			
		||||
          </el-select>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <!-- </el-col> -->
 | 
			
		||||
        <cb-form-item label="系列: " prop="series" :rules="[required]">
 | 
			
		||||
          <el-select v-model="addData.data.series" clearable placeholder="请选择系列" @change="changeCategory">
 | 
			
		||||
            <el-option v-for="(item, index) in categoryList" :key="index" :value="item.value" :label="item.name"></el-option>
 | 
			
		||||
        <cb-form-item label="数据库类型: " prop="type" :rules="[required]">
 | 
			
		||||
          <el-select v-model="formData.type" clearable placeholder="请选择类型">
 | 
			
		||||
            <el-option v-for="(item, key) in sqlTypeMap" :key="key" :value="key" :label="key"></el-option>
 | 
			
		||||
          </el-select>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <cb-form-item label="存储类型: " prop="volType" :rules="[required]">
 | 
			
		||||
          <el-select v-model="addData.data.volType" clearable placeholder="请选择类型" @change="getFlavorList">
 | 
			
		||||
            <el-option v-for="(item, index) in volTypeList" :key="index" :value="item.value" :label="item.name"></el-option>
 | 
			
		||||
          </el-select>
 | 
			
		||||
        <cb-form-item label="数据库版本: " prop="prodVersion" :rules="[required]">
 | 
			
		||||
          <el-radio-group v-model="formData.prodVersion" clearable placeholder="请选择版本" @change="changeVersion">
 | 
			
		||||
            <el-radio v-for="item in versionList" :key="item.value" :value="item.value" :label="item.name"></el-radio>
 | 
			
		||||
          </el-radio-group>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <cb-form-item label="实例类型: " prop="prodSpecName" :rules="[required]">
 | 
			
		||||
          <el-radio-group v-model="formData.prodSpecName" clearable placeholder="请选择实例类型" @change="changeCategory">
 | 
			
		||||
            <el-radio v-for="item in prodSpecNameList" :key="item" :value="item" :label="item"></el-radio>
 | 
			
		||||
          </el-radio-group>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <cb-form-item label="主节点可用区: " prop="mysqlNodeInfoList.0.availabilityZoneInfo.0.availabilityZoneName" :rules="[required]">
 | 
			
		||||
          <el-radio-group v-model="formData.mysqlNodeInfoList[0].availabilityZoneInfo[0].availabilityZoneName" clearable placeholder="请选择类型" @change="changeZone">
 | 
			
		||||
            <el-radio v-for="item in zoneList" :key="item.availabilityZoneId" :label="item.availabilityZoneId">{{ item.displayName }}</el-radio>
 | 
			
		||||
          </el-radio-group>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <cb-form-item label="备节点可用区1: " prop="mysqlNodeInfoList.0.availabilityZoneInfo.1.availabilityZoneName" :rules="[required]" v-if="formData.prodSpecName === '一主一备'">
 | 
			
		||||
          <el-radio-group v-model="formData.mysqlNodeInfoList[0].availabilityZoneInfo[1].availabilityZoneName" clearable placeholder="请选择可用区">
 | 
			
		||||
            <el-radio v-for="item in zoneList" :key="item.availabilityZoneId" :label="item.availabilityZoneId">{{ item.displayName }}</el-radio>
 | 
			
		||||
          </el-radio-group>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <cb-form-item label="备节点可用区2: " prop="mysqlNodeInfoList.0.availabilityZoneInfo.2.availabilityZoneName" :rules="[required]" v-if="formData.prodSpecName === '一主两备'">
 | 
			
		||||
          <el-radio-group v-model="formData.mysqlNodeInfoList[0].availabilityZoneInfo[2].availabilityZoneName" clearable placeholder="请选择可用区">
 | 
			
		||||
            <el-radio v-for="item in zoneList" :key="item.availabilityZoneId" :label="item.availabilityZoneId">{{ item.displayName }}</el-radio>
 | 
			
		||||
          </el-radio-group>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <cb-form-item label="性能类型: " prop="mysqlNodeInfoList.0.instSpec" :rules="[required]">
 | 
			
		||||
          <el-radio-group v-model="formData.mysqlNodeInfoList[0].instSpec" clearable placeholder="请选择性能类型" @change="changeInstSpec">
 | 
			
		||||
            <el-radio v-for="item in instSpecList" :key="item.value" :label="item.value">{{ item.name }}</el-radio>
 | 
			
		||||
          </el-radio-group>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <cb-form-item label="实例规格: " prop="flavorId" :rules="[required]" required-message="请选择规格">
 | 
			
		||||
          <cb-smart-table :data="specList" stripe>
 | 
			
		||||
            <el-table-column show-overflow-tooltip label="规格代码" prop="flavorUuid">
 | 
			
		||||
          <cb-smart-table :data="flavorList" stripe max-height="300px" :rows="99999">
 | 
			
		||||
            <el-table-column show-overflow-tooltip label="规格代码" prop="specName">
 | 
			
		||||
              <template v-slot="scope">
 | 
			
		||||
                <el-radio v-model="addData.data.flavorId" :label="scope.row.id">{{ scope.row.flavorUuid }}</el-radio>
 | 
			
		||||
                <el-radio v-model="formData.flavorId" :label="scope.row.specName" @input="changeFlavorId">{{ scope.row.specName }}</el-radio>
 | 
			
		||||
              </template>
 | 
			
		||||
            </el-table-column>
 | 
			
		||||
            <el-table-column show-overflow-tooltip label="实例规格族" prop="typeLabel"></el-table-column>
 | 
			
		||||
            <el-table-column show-overflow-tooltip label="CPU(核)" prop="cpu"></el-table-column>
 | 
			
		||||
            <el-table-column show-overflow-tooltip label="内存(GB)" prop="memory"></el-table-column>
 | 
			
		||||
            <el-table-column show-overflow-tooltip label="最大连接数(个)" prop="maxConnections"></el-table-column>
 | 
			
		||||
            <el-table-column show-overflow-tooltip label="最大IOPS(次/秒)" prop="maxIops"></el-table-column>
 | 
			
		||||
            <el-table-column show-overflow-tooltip label="最大IO带宽(Mbps)" prop="maxIombps" v-if="addData.data.volType !== 'local_ssd'"></el-table-column>
 | 
			
		||||
            <el-table-column show-overflow-tooltip label="CPU/内存" prop="prodPerformanceSpec"></el-table-column>
 | 
			
		||||
            <span slot="pagination"></span>
 | 
			
		||||
          </cb-smart-table>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <cb-form-item label="存储空间(GB): " prop="volSize" :rules="[required]">
 | 
			
		||||
        <cb-form-item label="存储类型: " prop="mysqlNodeInfoList.0.storageType" :rules="[required]">
 | 
			
		||||
          <el-select v-model="formData.mysqlNodeInfoList[0].storageType" clearable placeholder="请选择类型">
 | 
			
		||||
            <el-option v-for="(item, index) in storageTypeList" :key="index" :value="item.value" :label="item.name"></el-option>
 | 
			
		||||
          </el-select>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <cb-form-item label="存储空间(GB): " prop="mysqlNodeInfoList.0.storageSpace" :rules="[required]">
 | 
			
		||||
          <div style="padding: 0 10px">
 | 
			
		||||
            <el-slider v-model="addData.data.volSize" :marks="marks" show-input :min="20" :max="6000"> </el-slider>
 | 
			
		||||
            <el-slider v-model="formData.mysqlNodeInfoList[0].storageSpace" show-input :min="100" :max="32768"> </el-slider>
 | 
			
		||||
          </div>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <cb-form-item v-if="formData.billMode == '1'" label="购买时长:" prop="period" :rules="[required]">
 | 
			
		||||
          <el-select v-model="formData.period" clearable filterable>
 | 
			
		||||
            <el-option v-for="(item, index) in periodList" :key="index" :value="item.value" :label="item.name"></el-option>
 | 
			
		||||
          </el-select>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
      </cb-form>
 | 
			
		||||
    </el-row>
 | 
			
		||||
    <cb-form v-show="active === 1" :model="addData.data" ref="data" label-width="120px">
 | 
			
		||||
    <!-- <cb-form :model="formData" ref="data" label-width="120px"> -->
 | 
			
		||||
    <cb-form v-show="active === 1" :model="formData" ref="data" label-width="120px">
 | 
			
		||||
      <el-row>
 | 
			
		||||
        <cb-form-item label="网络类型: " prop="instanceNetworkType" :rules="[required]">
 | 
			
		||||
          <el-radio-group v-model="addData.data.instanceNetworkType" @change="changeNetworkType">
 | 
			
		||||
            <el-radio-button label="Classic">经典网络</el-radio-button>
 | 
			
		||||
            <el-radio-button label="VPC">专有网络</el-radio-button>
 | 
			
		||||
          </el-radio-group>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <div v-if="addData.data.instanceNetworkType == 'VPC'">
 | 
			
		||||
          <cb-form-item label="VPC: " prop="vpcId" :rules="[required]">
 | 
			
		||||
            <el-select v-model="addData.data.vpcId" clearable placeholder="请选择VPC" @change="changeVpc">
 | 
			
		||||
        <cb-form-item label="虚拟私有云: " prop="vpcId" :rules="[required]">
 | 
			
		||||
          <el-select v-model="formData.vpcId" clearable placeholder="请选择虚拟私有云" @change="changeVpc">
 | 
			
		||||
            <el-option v-for="(item, index) in vpcList" :key="index" :value="item.value" :label="item.name"></el-option>
 | 
			
		||||
          </el-select>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
          <cb-form-item label="主节点交换机: " prop="vswitchId" :rules="[required]">
 | 
			
		||||
            <el-select v-model="addData.data.vswitchId" clearable placeholder="请选择主节点交换机">
 | 
			
		||||
              <el-option v-for="(item, index) in vswitchList" :key="index" :value="item.value" :label="item.name"></el-option>
 | 
			
		||||
        <cb-form-item label="子网: " prop="subnetId" :rules="[required]">
 | 
			
		||||
          <el-select v-model="formData.subnetId" clearable placeholder="请选择子网">
 | 
			
		||||
            <el-option v-for="(item, index) in subnetList" :key="index" :value="item.value" :label="item.name"></el-option>
 | 
			
		||||
          </el-select>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- <cb-form-item label="参数模板: " prop="paramGroupId" :rules="[required]">
 | 
			
		||||
          <el-select v-model="addData.data.paramGroupId" clearable placeholder="请选择参数模板">
 | 
			
		||||
            <el-option v-for="(item, index) in templateList" :key="index" :value="item.id" :label="item.name"></el-option>
 | 
			
		||||
          </el-select>
 | 
			
		||||
        </cb-form-item> -->
 | 
			
		||||
        <cb-form-item label="时区: " prop="timeZone" :rules="[required]">
 | 
			
		||||
          <el-select filterable v-model="addData.data.timeZone" clearable placeholder="请选择时区">
 | 
			
		||||
            <el-option v-for="(item, index) in timeList" :key="index" :value="item.value" :label="item.name"></el-option>
 | 
			
		||||
        <cb-form-item label="安全组: " prop="securityGroupId">
 | 
			
		||||
          <el-select v-model="formData.securityGroupId" clearable filterable>
 | 
			
		||||
            <el-option v-for="(item, index) in sgroupList" :key="index" :value="item.value" :label="item.name"></el-option>
 | 
			
		||||
          </el-select>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <cb-form-item label="表名大小写: " prop="IgnoreCase" :rules="[required]">
 | 
			
		||||
          <el-radio-group v-model="addData.data.IgnoreCase">
 | 
			
		||||
            <el-radio label="1">不区分大小写(默认)</el-radio>
 | 
			
		||||
            <el-radio label="0">区分大小写</el-radio>
 | 
			
		||||
          </el-radio-group>
 | 
			
		||||
        <cb-form-item label="实例名称:" prop="name" :rules="[required, ctstackDatabaseName]">
 | 
			
		||||
          <el-input v-model="formData.name" placeholder="请输入实例名称" class="basic-cmp"></el-input>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <cb-form-item label="登录密码:" prop="password" :rules="[required, ctstackBMSPassword]">
 | 
			
		||||
          <el-input type="password" v-model="formData.password" @blur="PswBlur" show-password></el-input>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <cb-form-item label="确认密码:" prop="endPassword" :rules="[required, ctstackBMSPassword]">
 | 
			
		||||
          <el-input type="password" v-model="formData.endPassword" @blur="PswBlur"></el-input>
 | 
			
		||||
        </cb-form-item>
 | 
			
		||||
        <!-- <cb-form-item label="资源组: " prop="resourceId">
 | 
			
		||||
          <el-select v-model="addData.data.resourceId" clearable filterable>
 | 
			
		||||
            <el-option v-for="(item, index) in rgroupList" :key="index" :value="item.resourceGroupUuid" :label="item.displayName"></el-option>
 | 
			
		||||
          </el-select>
 | 
			
		||||
        </cb-form-item> -->
 | 
			
		||||
      </el-row>
 | 
			
		||||
    </cb-form>
 | 
			
		||||
    <div slot="footer">
 | 
			
		||||
| 
						 | 
				
			
			@ -120,13 +124,24 @@
 | 
			
		|||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
import validate from '@/validate'
 | 
			
		||||
import { getRegion } from 'services/platform/index'
 | 
			
		||||
import { getSubnet } from 'views/resource/ctstack/services/subnet.js'
 | 
			
		||||
import { getRegion, getFlavor, getParamGroup, createRds, getFlavorSpec } from 'views/resource/ctstack/services/database/rds.js'
 | 
			
		||||
import { getGroup } from 'views/resource/ctstack/services/group.js'
 | 
			
		||||
import { getFlavor, createRds, getRdsProject, getRdsZone } from 'views/resource/ctstack/services/database/rds.js'
 | 
			
		||||
import { getVpc } from 'views/resource/ctstack/services/vpcs.js'
 | 
			
		||||
import RegionItem from './RegionItem.vue'
 | 
			
		||||
import { handleSearchParam } from '@cmp/cmp-element'
 | 
			
		||||
import { encrypt, handleSearchParam } from '@cmp/cmp-element'
 | 
			
		||||
import { uniqBy, cloneDeep } from 'lodash-es'
 | 
			
		||||
const instSpecMap = {
 | 
			
		||||
  通用型: '1',
 | 
			
		||||
  计算增强型: '2',
 | 
			
		||||
  内存优化型: '3'
 | 
			
		||||
}
 | 
			
		||||
const instSpecMapRevers = {
 | 
			
		||||
  1: '通用型',
 | 
			
		||||
  2: '计算增强型',
 | 
			
		||||
  3: '内存优化型'
 | 
			
		||||
}
 | 
			
		||||
export default {
 | 
			
		||||
  components: { RegionItem },
 | 
			
		||||
  props: {
 | 
			
		||||
    addData: {
 | 
			
		||||
      type: Object
 | 
			
		||||
| 
						 | 
				
			
			@ -135,304 +150,271 @@ export default {
 | 
			
		|||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      required: validate.required,
 | 
			
		||||
      ctstackDatabaseName: validate.ctstackDatabaseName,
 | 
			
		||||
      ctstackBMSPassword: validate.ctstackBMSPassword,
 | 
			
		||||
      active: 0,
 | 
			
		||||
      regions: [],
 | 
			
		||||
      typeList: {
 | 
			
		||||
        MySQL: ['5.5', '5.6', '5.7', '8.0']
 | 
			
		||||
        // SQLServer: ['2008r2', '08r2_ent_ha', '2012', '2012_ent_ha', '2012_std_ha', '2012_web', '2014_std_ha', '2016_ent_ha', '2016_std_ha', '2016_web', '2017_std_ha', '2017_ent', '2019_std_ha', '2019_ent'],
 | 
			
		||||
        // PostgreSQL: ['9.4', '10.0', '11.0', '12.0', '13.0'],
 | 
			
		||||
        // MariaDB: ['10.3']
 | 
			
		||||
      formData: {
 | 
			
		||||
        vendorId: this.addData.vendorId,
 | 
			
		||||
        type: this.addData.type,
 | 
			
		||||
        flavorId: '',
 | 
			
		||||
        billMode: '2', // 计费模式: 1是包周期,2是按需
 | 
			
		||||
        regionId: '',
 | 
			
		||||
        prodVersion: '', // 版本(参考查询规格列表接口) 12.16
 | 
			
		||||
        prodSpecName: '', // 产品名称规格名称(参考查询规格列表接口) 一主一备
 | 
			
		||||
        mysqlNodeInfoList: [
 | 
			
		||||
          {
 | 
			
		||||
            nodeType: 'master', // 节点类型
 | 
			
		||||
            instSpec: '1', // 实例类型,1=通用型,2=计算增强型,3=内存优化型,4=直通(未用到)
 | 
			
		||||
            storageType: 'SATA', // 存储类型: SSD=超高IO、SATA=普通IO、SAS=高IO、SSD-genric=通用型SSD、FAST-SSD=极速型SSD
 | 
			
		||||
            storageSpace: 100, // 存储空间(单位:G,范围100,32768)
 | 
			
		||||
            prodPerformanceSpec: '', // 规格(例: 4C8G)
 | 
			
		||||
            disks: 1, // 磁盘
 | 
			
		||||
            availabilityZoneInfo: [
 | 
			
		||||
              {
 | 
			
		||||
                availabilityZoneName: '',
 | 
			
		||||
                availabilityZoneCount: 1,
 | 
			
		||||
                nodeType: 'master' // 表示分布AZ的节点类型,master/slave/readNode
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                availabilityZoneName: '',
 | 
			
		||||
                availabilityZoneCount: 1,
 | 
			
		||||
                nodeType: 'slave'
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                availabilityZoneName: '',
 | 
			
		||||
                availabilityZoneCount: 1,
 | 
			
		||||
                nodeType: 'slave'
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          }
 | 
			
		||||
        ],
 | 
			
		||||
        vpcId: '',
 | 
			
		||||
        subnetId: '',
 | 
			
		||||
        securityGroupId: '',
 | 
			
		||||
        name: '',
 | 
			
		||||
        password: '',
 | 
			
		||||
        endPassword: '',
 | 
			
		||||
        period: '1', // 购买时长:单位月(范围:1-36)
 | 
			
		||||
        count: 1,
 | 
			
		||||
        autoRenewStatus: 0, // 自动续订状态 (0-不自动续订,1-自动续订)
 | 
			
		||||
        prodId: '', // 产品id
 | 
			
		||||
        projectId: '',
 | 
			
		||||
        projectName: '',
 | 
			
		||||
        hostType: '' // 主机类型 host type: S6 or S7
 | 
			
		||||
      },
 | 
			
		||||
      projectList: [],
 | 
			
		||||
      regionData: [],
 | 
			
		||||
      sqlTypeMap: {
 | 
			
		||||
        MySQL: ['5.7', '8.0']
 | 
			
		||||
      },
 | 
			
		||||
      prodSpecNameList: [],
 | 
			
		||||
      storageTypeList: [
 | 
			
		||||
        {
 | 
			
		||||
          name: '极速型SSD',
 | 
			
		||||
          value: 'FAST-SSD'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          name: '通用型SSD',
 | 
			
		||||
          value: 'SSD-genric'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          name: '高IO',
 | 
			
		||||
          value: 'SAS'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          name: '普通IO',
 | 
			
		||||
          value: 'SATA'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          name: '超高IO',
 | 
			
		||||
          value: 'SSD'
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      periodList: [
 | 
			
		||||
        { name: '1个月', value: '1' },
 | 
			
		||||
        { name: '2个月', value: '2' },
 | 
			
		||||
        { name: '3个月', value: '3' },
 | 
			
		||||
        { name: '4个月', value: '4' },
 | 
			
		||||
        { name: '5个月', value: '5' },
 | 
			
		||||
        { name: '6个月', value: '6' },
 | 
			
		||||
        { name: '7个月', value: '7' },
 | 
			
		||||
        { name: '8个月', value: '8' },
 | 
			
		||||
        { name: '9个月', value: '9' },
 | 
			
		||||
        { name: '12个月', value: '12' },
 | 
			
		||||
        { name: '24个月', value: '24' },
 | 
			
		||||
        { name: '36个月', value: '36' }
 | 
			
		||||
      ],
 | 
			
		||||
      allFlavorList: [],
 | 
			
		||||
      flavorList: [],
 | 
			
		||||
      versionList: [],
 | 
			
		||||
      categoryList: [],
 | 
			
		||||
      categoryMap: {
 | 
			
		||||
        5.5: [
 | 
			
		||||
          {
 | 
			
		||||
            name: '高可用版',
 | 
			
		||||
            value: 'HighAvailability',
 | 
			
		||||
            volType: [
 | 
			
		||||
              {
 | 
			
		||||
                name: '本地SSD云盘',
 | 
			
		||||
                value: 'local_ssd'
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          }
 | 
			
		||||
        ],
 | 
			
		||||
        5.6: [
 | 
			
		||||
          {
 | 
			
		||||
            name: '高可用版',
 | 
			
		||||
            value: 'HighAvailability',
 | 
			
		||||
            volType: [
 | 
			
		||||
              {
 | 
			
		||||
                name: '本地SSD云盘',
 | 
			
		||||
                value: 'local_ssd'
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          },
 | 
			
		||||
          { name: '基础版', value: 'Basic', volType: [] }
 | 
			
		||||
        ],
 | 
			
		||||
        5.7: [
 | 
			
		||||
          {
 | 
			
		||||
            name: '高可用版',
 | 
			
		||||
            value: 'HighAvailability',
 | 
			
		||||
            volType: [
 | 
			
		||||
              {
 | 
			
		||||
                name: '本地SSD云盘',
 | 
			
		||||
                value: 'local_ssd'
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                name: 'ESSD PL1云盘',
 | 
			
		||||
                value: 'cloud_essd'
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                name: 'ESSD PL2云盘',
 | 
			
		||||
                value: 'cloud_essd2'
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                name: 'ESSD PL3云盘',
 | 
			
		||||
                value: 'cloud_essd3'
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                name: 'SSD云盘',
 | 
			
		||||
                value: 'cloud_ssd'
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: '基础版',
 | 
			
		||||
            value: 'Basic',
 | 
			
		||||
            volType: [
 | 
			
		||||
              {
 | 
			
		||||
                name: 'ESSD PL1云盘',
 | 
			
		||||
                value: 'cloud_essd'
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                name: 'SSD云盘',
 | 
			
		||||
                value: 'cloud_ssd'
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: '三节点企业版',
 | 
			
		||||
            value: 'Finance',
 | 
			
		||||
            volType: [
 | 
			
		||||
              {
 | 
			
		||||
                name: '本地SSD云盘',
 | 
			
		||||
                value: 'local_ssd'
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          }
 | 
			
		||||
        ],
 | 
			
		||||
        '8.0': [
 | 
			
		||||
          {
 | 
			
		||||
            name: '高可用版',
 | 
			
		||||
            value: 'HighAvailability',
 | 
			
		||||
            volType: [
 | 
			
		||||
              {
 | 
			
		||||
                name: '本地SSD云盘',
 | 
			
		||||
                value: 'local_ssd'
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                name: 'ESSD PL1云盘',
 | 
			
		||||
                value: 'cloud_essd'
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                name: 'ESSD PL2云盘',
 | 
			
		||||
                value: 'cloud_essd2'
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                name: 'ESSD PL3云盘',
 | 
			
		||||
                value: 'cloud_essd3'
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                name: 'SSD云盘',
 | 
			
		||||
                value: 'cloud_ssd'
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: '基础版',
 | 
			
		||||
            value: 'Basic',
 | 
			
		||||
            volType: [
 | 
			
		||||
              {
 | 
			
		||||
                name: 'ESSD PL1云盘',
 | 
			
		||||
                value: 'cloud_essd'
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                name: 'SSD云盘',
 | 
			
		||||
                value: 'cloud_ssd'
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: '三节点企业版',
 | 
			
		||||
            value: 'Finance',
 | 
			
		||||
            volType: [
 | 
			
		||||
              {
 | 
			
		||||
                name: '本地SSD云盘',
 | 
			
		||||
                value: 'local_ssd'
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      },
 | 
			
		||||
      volTypeList: [],
 | 
			
		||||
      specList: [],
 | 
			
		||||
      zoneList: [],
 | 
			
		||||
      instSpecList: [],
 | 
			
		||||
      vpcList: [],
 | 
			
		||||
      vswitchList: [],
 | 
			
		||||
      templateList: [],
 | 
			
		||||
      timeList: [
 | 
			
		||||
        { name: 'UTC-12:00', value: '-12:00' },
 | 
			
		||||
        { name: 'UTC-11:00', value: '-11:00' },
 | 
			
		||||
        { name: 'UTC-10:00', value: '-10:00' },
 | 
			
		||||
        { name: 'UTC-09:00', value: '-9:00' },
 | 
			
		||||
        { name: 'UTC-08:00', value: '-8:00' },
 | 
			
		||||
        { name: 'UTC-07:00', value: '-7:00' },
 | 
			
		||||
        { name: 'UTC-06:00', value: '-6:00' },
 | 
			
		||||
        { name: 'UTC-05:00', value: '-5:00' },
 | 
			
		||||
        { name: 'UTC-04:00', value: '-4:00' },
 | 
			
		||||
        { name: 'UTC-03:00', value: '-3:00' },
 | 
			
		||||
        { name: 'UTC-02:00', value: '-2:00' },
 | 
			
		||||
        { name: 'UTC-01:00', value: '-1:00' },
 | 
			
		||||
        { name: 'UTC+00:00', value: '+0:00' },
 | 
			
		||||
        { name: 'UTC+01:00', value: '+1:00' },
 | 
			
		||||
        { name: 'UTC+02:00', value: '+2:00' },
 | 
			
		||||
        { name: 'UTC+03:00', value: '+3:00' },
 | 
			
		||||
        { name: 'UTC+04:00', value: '+4:00' },
 | 
			
		||||
        { name: 'UTC+05:00', value: '+5:00' },
 | 
			
		||||
        { name: 'UTC+05:30', value: '+5:30' },
 | 
			
		||||
        { name: 'UTC+06:00', value: '+6:00' },
 | 
			
		||||
        { name: 'UTC+07:00', value: '+7:00' },
 | 
			
		||||
        { name: 'UTC+08:00', value: '+8:00' },
 | 
			
		||||
        { name: 'UTC+09:00', value: '+9:00' },
 | 
			
		||||
        { name: 'UTC+10:00', value: '+10:00' },
 | 
			
		||||
        { name: 'UTC+11:00', value: '+11:00' },
 | 
			
		||||
        { name: 'UTC+12:00', value: '+12:00' },
 | 
			
		||||
        { name: 'UTC+13:00', value: '+13:00' }
 | 
			
		||||
      ],
 | 
			
		||||
      rgroupList: [],
 | 
			
		||||
      marks: {
 | 
			
		||||
        20: '20GB',
 | 
			
		||||
        1500: '1500GB',
 | 
			
		||||
        3000: '3000GB'
 | 
			
		||||
      }
 | 
			
		||||
      subnetList: [],
 | 
			
		||||
      sgroupList: []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.changeType(this.addData.data.dataStoreType)
 | 
			
		||||
    this.getVendorDetail()
 | 
			
		||||
    this.getRegionList()
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {},
 | 
			
		||||
  computed: {
 | 
			
		||||
    regionId() {
 | 
			
		||||
      return this.addData.data.regionId
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
    regionId(newVal) {
 | 
			
		||||
      this.versionList = []
 | 
			
		||||
      this.addData.data.dataStoreVersion = ''
 | 
			
		||||
      this.getVersions()
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    getVendorDetail() {
 | 
			
		||||
      // detailCloudVendor(this.addData.data.vendorId).then(data => {
 | 
			
		||||
      //   if (data.success) {
 | 
			
		||||
      //     const authentication = data.data.authentication ? JSON.parse(data.data.authentication) : {}
 | 
			
		||||
      //     this.regions = authentication.regions || []
 | 
			
		||||
      //   }
 | 
			
		||||
      // })
 | 
			
		||||
    },
 | 
			
		||||
    getFlavorList() {
 | 
			
		||||
      const { dataStoreType, dataStoreVersion, series, vendorId, regionId, volType, zone } = this.addData.data
 | 
			
		||||
      if (dataStoreType && dataStoreVersion && series && regionId && volType && zone) {
 | 
			
		||||
        getFlavor({
 | 
			
		||||
          series: series,
 | 
			
		||||
    getRegionList() {
 | 
			
		||||
      const { vendorId, type } = this.formData
 | 
			
		||||
      if (type) {
 | 
			
		||||
        getRegion({
 | 
			
		||||
          vendorId: vendorId,
 | 
			
		||||
          regionId: regionId,
 | 
			
		||||
          zone: zone,
 | 
			
		||||
          engine: dataStoreType.toLowerCase(),
 | 
			
		||||
          version: dataStoreVersion,
 | 
			
		||||
          storageType: volType
 | 
			
		||||
          type: type
 | 
			
		||||
        }).then(data => {
 | 
			
		||||
          if (data.success) {
 | 
			
		||||
            this.specList = data.data
 | 
			
		||||
            this.addData.data.flavorId = this.specList.length ? this.specList[0].id : ''
 | 
			
		||||
            this.regionData = data.data
 | 
			
		||||
            this.formData.regionId = this.regionData.length ? this.regionData[0].code : ''
 | 
			
		||||
            this.changeRegion()
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    getVersions() {
 | 
			
		||||
      const { vendorId, regionId } = this.addData.data
 | 
			
		||||
      const params = {
 | 
			
		||||
        type: 'version',
 | 
			
		||||
        vendorId,
 | 
			
		||||
        regionId,
 | 
			
		||||
        engine: 'MySQL'
 | 
			
		||||
      }
 | 
			
		||||
      // const res = await getFlavorSpec(params)
 | 
			
		||||
      // if (res) {
 | 
			
		||||
      //   this.versionList = res.data
 | 
			
		||||
      // }
 | 
			
		||||
      this.versionList = [
 | 
			
		||||
        { name: '8.0', value: '8.0' },
 | 
			
		||||
        { name: '5.7', value: '5.7' }
 | 
			
		||||
      ]
 | 
			
		||||
    },
 | 
			
		||||
    async getSeries(version) {
 | 
			
		||||
      const { vendorId, regionId } = this.addData.data
 | 
			
		||||
      const params = {
 | 
			
		||||
        type: 'series',
 | 
			
		||||
        vendorId,
 | 
			
		||||
        regionId,
 | 
			
		||||
        version,
 | 
			
		||||
        engine: 'MySQL'
 | 
			
		||||
      }
 | 
			
		||||
      const res = await getFlavorSpec(params)
 | 
			
		||||
      if (res) {
 | 
			
		||||
        this.categoryList = res.data
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    async getStorageType(series) {
 | 
			
		||||
      const { vendorId, regionId } = this.addData.data
 | 
			
		||||
      const params = {
 | 
			
		||||
        type: 'storageType',
 | 
			
		||||
        vendorId,
 | 
			
		||||
        regionId,
 | 
			
		||||
        series,
 | 
			
		||||
        engine: 'MySQL'
 | 
			
		||||
      }
 | 
			
		||||
      const res = await getFlavorSpec(params)
 | 
			
		||||
      if (res) {
 | 
			
		||||
        this.volTypeList = res.data
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    changeVersion(value) {
 | 
			
		||||
      this.categoryList = []
 | 
			
		||||
      this.$set(this.addData.data, 'series', '')
 | 
			
		||||
      this.volTypeList = []
 | 
			
		||||
      this.addData.data.volType = ''
 | 
			
		||||
      this.specList = []
 | 
			
		||||
      this.getSeries(value)
 | 
			
		||||
    },
 | 
			
		||||
    changeCategory(value) {
 | 
			
		||||
      this.volTypeList = []
 | 
			
		||||
      this.addData.data.volType = ''
 | 
			
		||||
      this.specList = []
 | 
			
		||||
      this.getStorageType(value)
 | 
			
		||||
    },
 | 
			
		||||
    changeNetworkType(value) {
 | 
			
		||||
      if (value == 'VPC') {
 | 
			
		||||
    changeRegion() {
 | 
			
		||||
      this.getVpcList()
 | 
			
		||||
      this.getProject()
 | 
			
		||||
    },
 | 
			
		||||
    getProject() {
 | 
			
		||||
      getRdsProject({
 | 
			
		||||
        regionId: this.formData.regionId,
 | 
			
		||||
        vendorId: this.formData.vendorId,
 | 
			
		||||
        type: this.formData.type
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res.success) {
 | 
			
		||||
          this.projectList = res.data
 | 
			
		||||
          this.formData.projectId = this.projectList.length ? this.projectList[0].projectSetId : ''
 | 
			
		||||
          this.changeProject()
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    async changeProject() {
 | 
			
		||||
      if (!this.formData.projectId) return
 | 
			
		||||
      this.formData.projectName = this.projectList.find(item => item.projectSetId === this.formData.projectId)?.projectSetName
 | 
			
		||||
      await this.getZone()
 | 
			
		||||
      this.getFlavorList()
 | 
			
		||||
    },
 | 
			
		||||
    async getZone() {
 | 
			
		||||
      await getRdsZone({
 | 
			
		||||
        regionId: this.formData.regionId,
 | 
			
		||||
        vendorId: this.formData.vendorId,
 | 
			
		||||
        projectId: this.formData.projectId
 | 
			
		||||
      }).then(data => {
 | 
			
		||||
        if (data.success) {
 | 
			
		||||
          this.zoneList = data.data
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    getFlavorList() {
 | 
			
		||||
      const { type, vendorId, regionId, projectId } = this.formData
 | 
			
		||||
      if ((type, vendorId, regionId, projectId)) {
 | 
			
		||||
        getFlavor({
 | 
			
		||||
          type,
 | 
			
		||||
          vendorId,
 | 
			
		||||
          regionId,
 | 
			
		||||
          projectId
 | 
			
		||||
        }).then(data => {
 | 
			
		||||
          if (data.success) {
 | 
			
		||||
            this.allFlavorList = Object.freeze(data.data)
 | 
			
		||||
            this.getVersionList()
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    getVersionList() {
 | 
			
		||||
      const list = this.allFlavorList.map(({ prodVersion }) => ({ name: prodVersion, value: prodVersion }))
 | 
			
		||||
      this.versionList = uniqBy(list, 'value')
 | 
			
		||||
      this.formData.prodVersion = this.versionList.length ? this.versionList[0].value : ''
 | 
			
		||||
      this.changeVersion()
 | 
			
		||||
    },
 | 
			
		||||
    changeVersion() {
 | 
			
		||||
      this.getCategoryList()
 | 
			
		||||
    },
 | 
			
		||||
    getCategoryList() {
 | 
			
		||||
      const { prodVersion } = this.formData
 | 
			
		||||
      if (!prodVersion) return
 | 
			
		||||
      const list = this.allFlavorList.filter(item => item.prodVersion === prodVersion).map(({ prodSpecName }) => prodSpecName)
 | 
			
		||||
      this.prodSpecNameList = list
 | 
			
		||||
      this.formData.prodSpecName = this.prodSpecNameList.length ? this.prodSpecNameList[0] : ''
 | 
			
		||||
      this.changeCategory()
 | 
			
		||||
    },
 | 
			
		||||
    changeCategory() {
 | 
			
		||||
      this.resetZone()
 | 
			
		||||
    },
 | 
			
		||||
    resetZone() {
 | 
			
		||||
      const [first = '', second = '', third = ''] = this.zoneList.map(item => item.availabilityZoneId)
 | 
			
		||||
      switch (this.formData.prodSpecName) {
 | 
			
		||||
        case '单机版':
 | 
			
		||||
        case '只读实例':
 | 
			
		||||
          this.formData.mysqlNodeInfoList[0].availabilityZoneInfo[0].availabilityZoneName = first
 | 
			
		||||
          this.formData.mysqlNodeInfoList[0].availabilityZoneInfo[1].availabilityZoneName = ''
 | 
			
		||||
          this.formData.mysqlNodeInfoList[0].availabilityZoneInfo[2].availabilityZoneName = ''
 | 
			
		||||
          break
 | 
			
		||||
        case '一主一备':
 | 
			
		||||
          this.formData.mysqlNodeInfoList[0].availabilityZoneInfo[0].availabilityZoneName = first
 | 
			
		||||
          this.formData.mysqlNodeInfoList[0].availabilityZoneInfo[1].availabilityZoneName = second
 | 
			
		||||
          this.formData.mysqlNodeInfoList[0].availabilityZoneInfo[2].availabilityZoneName = ''
 | 
			
		||||
          break
 | 
			
		||||
        case '一主两备':
 | 
			
		||||
          this.formData.mysqlNodeInfoList[0].availabilityZoneInfo[0].availabilityZoneName = first
 | 
			
		||||
          this.formData.mysqlNodeInfoList[0].availabilityZoneInfo[1].availabilityZoneName = second
 | 
			
		||||
          this.formData.mysqlNodeInfoList[0].availabilityZoneInfo[2].availabilityZoneName = third
 | 
			
		||||
          break
 | 
			
		||||
        default:
 | 
			
		||||
          this.formData.mysqlNodeInfoList[0].availabilityZoneInfo[0].availabilityZoneName = first
 | 
			
		||||
          this.formData.mysqlNodeInfoList[0].availabilityZoneInfo[1].availabilityZoneName = ''
 | 
			
		||||
          this.formData.mysqlNodeInfoList[0].availabilityZoneInfo[2].availabilityZoneName = ''
 | 
			
		||||
          break
 | 
			
		||||
      }
 | 
			
		||||
      this.changeZone()
 | 
			
		||||
    },
 | 
			
		||||
    changeZone() {
 | 
			
		||||
      this.getInstSpecList()
 | 
			
		||||
    },
 | 
			
		||||
    getInstSpecList() {
 | 
			
		||||
      const { prodVersion, prodSpecName } = this.formData
 | 
			
		||||
      if (!prodVersion || !prodSpecName) return
 | 
			
		||||
      const instSpecMap = {
 | 
			
		||||
        通用型: '1',
 | 
			
		||||
        计算增强型: '2',
 | 
			
		||||
        内存优化型: '3'
 | 
			
		||||
      }
 | 
			
		||||
      this.instSpecList = this.allFlavorList.filter(item => item.prodVersion === prodVersion && item.prodSpecName === prodSpecName).map(({ instanceType }) => ({ name: instanceType, value: instSpecMap[instanceType] }))
 | 
			
		||||
      this.formData.mysqlNodeInfoList[0].instSpec = this.instSpecList.length ? this.instSpecList[0].value : ''
 | 
			
		||||
      this.changeInstSpec()
 | 
			
		||||
    },
 | 
			
		||||
    changeInstSpec() {
 | 
			
		||||
      this._getFlavor()
 | 
			
		||||
    },
 | 
			
		||||
    _getFlavor() {
 | 
			
		||||
      const { prodVersion, prodSpecName, mysqlNodeInfoList } = this.formData
 | 
			
		||||
      if (!prodVersion || !prodSpecName || !mysqlNodeInfoList[0].instSpec) return
 | 
			
		||||
      // 根据数据库版本 实例类型 性能类型 过滤
 | 
			
		||||
      const find = this.allFlavorList.find(item => item.prodVersion === prodVersion && item.prodSpecName === prodSpecName && item.instanceType === instSpecMapRevers[mysqlNodeInfoList[0].instSpec])
 | 
			
		||||
      if (!find) return console.log('未找到规格', prodVersion, prodSpecName, instSpecMapRevers[mysqlNodeInfoList[0].instSpec])
 | 
			
		||||
      // 根据主节点过滤
 | 
			
		||||
      this.flavorList = find.instSpecInfoList.filter(item => item.azList.includes(this.formData.mysqlNodeInfoList[0].availabilityZoneInfo[0].availabilityZoneName)).sort((a, b) => a.prodPerformanceSpec?.split(/[A-Z]/)[0] - b.prodPerformanceSpec?.split(/[A-Z]/)[0])
 | 
			
		||||
      this.formData.flavorId = this.flavorList.length ? this.flavorList[0].specName : ''
 | 
			
		||||
      this.changeFlavorId()
 | 
			
		||||
    },
 | 
			
		||||
    changeFlavorId() {
 | 
			
		||||
      const { prodVersion, prodSpecName, mysqlNodeInfoList } = this.formData
 | 
			
		||||
      const group = this.allFlavorList.find(item => item.prodVersion === prodVersion && item.prodSpecName === prodSpecName && item.instanceType === instSpecMapRevers[mysqlNodeInfoList[0].instSpec]) || {}
 | 
			
		||||
      this.formData.prodId = group.prodId || ''
 | 
			
		||||
 | 
			
		||||
      const find = this.flavorList.find(item => item.specName === this.formData.flavorId) || {}
 | 
			
		||||
      this.formData.hostType = find.generation || ''
 | 
			
		||||
      this.formData.mysqlNodeInfoList[0].prodPerformanceSpec = find.prodPerformanceSpec || ''
 | 
			
		||||
    },
 | 
			
		||||
    getVpcList() {
 | 
			
		||||
      getVpc({
 | 
			
		||||
        simple: true,
 | 
			
		||||
        params: handleSearchParam({
 | 
			
		||||
          vendorId: this.addData.data.vendorId,
 | 
			
		||||
          regionId: this.addData.data.regionId
 | 
			
		||||
          vendorId: this.formData.vendorId,
 | 
			
		||||
          regionId: this.formData.regionId
 | 
			
		||||
        })
 | 
			
		||||
      }).then(data => {
 | 
			
		||||
        this.loading = false
 | 
			
		||||
| 
						 | 
				
			
			@ -442,63 +424,41 @@ export default {
 | 
			
		|||
      })
 | 
			
		||||
    },
 | 
			
		||||
    changeVpc(value) {
 | 
			
		||||
      let networkId = ''
 | 
			
		||||
      this.vswitchList = []
 | 
			
		||||
      this.addData.data.vswitchId = ''
 | 
			
		||||
      this.vpcList.forEach(item => {
 | 
			
		||||
        if (value == item.value) {
 | 
			
		||||
          networkId = item.id
 | 
			
		||||
          this.getSwitchList(networkId)
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      this.subnetList = []
 | 
			
		||||
      this.formData.subnetId = ''
 | 
			
		||||
      this.getSubnetList()
 | 
			
		||||
      this.getRgroup()
 | 
			
		||||
    },
 | 
			
		||||
    getSwitchList(networkId) {
 | 
			
		||||
    getSubnetList() {
 | 
			
		||||
      getSubnet({
 | 
			
		||||
        simple: true,
 | 
			
		||||
        params: handleSearchParam({
 | 
			
		||||
          networkId: networkId,
 | 
			
		||||
          vendorId: this.addData.data.vendorId,
 | 
			
		||||
          zone: this.addData.data.zone
 | 
			
		||||
          vpcUuid: this.formData.vpcId,
 | 
			
		||||
          vendorId: this.formData.vendorId
 | 
			
		||||
        })
 | 
			
		||||
      }).then(data => {
 | 
			
		||||
        if (data.success) {
 | 
			
		||||
          this.vswitchList = data.data.rows
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    getTemplateList() {
 | 
			
		||||
      getParamGroup({
 | 
			
		||||
        regionId: this.addData.data.regionId,
 | 
			
		||||
        vendorId: this.addData.data.vendorId,
 | 
			
		||||
        engine: this.addData.data.dataStoreType.toLowerCase(),
 | 
			
		||||
        version: this.addData.data.dataStoreVersion
 | 
			
		||||
      }).then(data => {
 | 
			
		||||
        if (data.success) {
 | 
			
		||||
          this.templateList = data.data
 | 
			
		||||
          this.subnetList = data.data.rows
 | 
			
		||||
          this.formData.subnetId = this.subnetList.length ? this.subnetList[0].value : ''
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    getRgroup() {
 | 
			
		||||
      // getResource({
 | 
			
		||||
      //   page: 1,
 | 
			
		||||
      //   rows: 99999,
 | 
			
		||||
      //   params: handleSearchParam({
 | 
			
		||||
      //     vendorId: this.addData.data.vendorId,
 | 
			
		||||
      //     'status:ueq': 'PendingDelete'
 | 
			
		||||
      //   })
 | 
			
		||||
      // }).then(data => {
 | 
			
		||||
      //   if (data.success) {
 | 
			
		||||
      //     this.rgroupList = data.data.rows
 | 
			
		||||
      //   }
 | 
			
		||||
      // })
 | 
			
		||||
      getGroup({
 | 
			
		||||
        simple: true,
 | 
			
		||||
        params: JSON.stringify([{ param: { vendorId: this.formData.vendorId, regionId: this.formData.regionId, tenantId: 0, vpcUuid: this.formData.vpcId }, sign: 'EQ' }])
 | 
			
		||||
      }).then(data => {
 | 
			
		||||
        if (data.success) {
 | 
			
		||||
          this.sgroupList = data.data.rows
 | 
			
		||||
          this.formData.securityGroupId = this.sgroupList.length ? this.sgroupList[0].value : ''
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    next(num) {
 | 
			
		||||
      if (num === 0) {
 | 
			
		||||
        this.$refs.basicData.validate(valid => {
 | 
			
		||||
          if (valid) {
 | 
			
		||||
            this.active = 1
 | 
			
		||||
            this.getRgroup()
 | 
			
		||||
            this.getTemplateList()
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -509,7 +469,19 @@ export default {
 | 
			
		|||
        if (!valid) {
 | 
			
		||||
          return false
 | 
			
		||||
        }
 | 
			
		||||
        createRds(this.addData.data).then(data => {
 | 
			
		||||
        const params = cloneDeep(this.formData)
 | 
			
		||||
        // 剪切可用区
 | 
			
		||||
        params.mysqlNodeInfoList[0].availabilityZoneInfo = params.mysqlNodeInfoList[0].availabilityZoneInfo.filter(item => item.availabilityZoneName)
 | 
			
		||||
        if (params.password !== params.endPassword) {
 | 
			
		||||
          this.$notify({
 | 
			
		||||
            title: '提示',
 | 
			
		||||
            message: '两次密码输入不一致'
 | 
			
		||||
          })
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
        if (params.password) params.password = encrypt(params.password)
 | 
			
		||||
        if (params.endPassword) params.endPassword = encrypt(params.endPassword)
 | 
			
		||||
        createRds(params).then(data => {
 | 
			
		||||
          const type = data.success ? 'success' : 'error'
 | 
			
		||||
          this.$message[type](data.message)
 | 
			
		||||
          if (data.success) {
 | 
			
		||||
| 
						 | 
				
			
			@ -519,7 +491,13 @@ export default {
 | 
			
		|||
          }
 | 
			
		||||
        })
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    PswBlur(e) {
 | 
			
		||||
      const value = e.target.value
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// 创建待调试
 | 
			
		||||
| 
						 | 
				
			
			@ -12,9 +12,6 @@
 | 
			
		|||
      <template #type="type">
 | 
			
		||||
        {{ filter[type] }}
 | 
			
		||||
      </template>
 | 
			
		||||
      <template #instanceNetworkType="instanceNetworkType">
 | 
			
		||||
        {{ filter[instanceNetworkType] }}
 | 
			
		||||
      </template>
 | 
			
		||||
      <template #payType="payType">
 | 
			
		||||
        {{ filter[payType] }}
 | 
			
		||||
      </template>
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +21,7 @@
 | 
			
		|||
      <template #operate="val, record">
 | 
			
		||||
        <el-button type="text" @click="patch(record)" :disabled="record.status !== 'Running'"> 重启 </el-button>
 | 
			
		||||
        <div class="action-divider"></div>
 | 
			
		||||
        <el-button type="text" @click="removeAliRds(record)" :disabled="record.status !== 'Running'"> 释放实例 </el-button>
 | 
			
		||||
        <el-button type="text" @click="removeRds(record)" :disabled="record.status !== 'Running'"> 释放实例 </el-button>
 | 
			
		||||
      </template>
 | 
			
		||||
    </cb-advance-table>
 | 
			
		||||
    <add :add-data="addData" v-if="addData.dialog" @back="getData"></add>
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +32,6 @@
 | 
			
		|||
        <cb-detail-item label="版本">{{ detailData.dataStoreVersion }}</cb-detail-item>
 | 
			
		||||
        <cb-detail-item label="实例类型">{{ filter[detailData.type] }}</cb-detail-item>
 | 
			
		||||
        <cb-detail-item label="数据库类型">{{ detailData.dataStoreType }}</cb-detail-item>
 | 
			
		||||
        <cb-detail-item label="网络类型">{{ filter[detailData.instanceNetworkType] }}</cb-detail-item>
 | 
			
		||||
        <cb-detail-item label="付费类型">{{ filter[detailData.payType] }}</cb-detail-item>
 | 
			
		||||
        <cb-detail-item label="规格">{{ detailData.flavorId }}</cb-detail-item>
 | 
			
		||||
        <cb-detail-item label="可用区">{{ detailData.region }}</cb-detail-item>
 | 
			
		||||
| 
						 | 
				
			
			@ -266,7 +262,7 @@
 | 
			
		|||
 | 
			
		||||
<script>
 | 
			
		||||
import validate from '@/validate'
 | 
			
		||||
import { getAliRds, detailAliRds, getRdsCos, patchAliRds, removeAliRds, getRdsUsers, createRdsUsers, removeRdsUsers, resetRdsUserPasd, resetRdsUser, authRdsUser, getRdsDbs, createRdsDbs, removeRdsDbs } from 'views/resource/ctstack/services/database/rds.js'
 | 
			
		||||
import { getRds, detailRds, getRdsCos, patchRds, removeRds, getRdsUsers, createRdsUsers, removeRdsUsers, resetRdsUserPasd, resetRdsUser, authRdsUser, getRdsDbs, createRdsDbs, removeRdsDbs } from 'views/resource/ctstack/services/database/rds.js'
 | 
			
		||||
import add from './add.vue'
 | 
			
		||||
import ModifyRole from './ModifyRole.vue'
 | 
			
		||||
import { keywords } from './validate'
 | 
			
		||||
| 
						 | 
				
			
			@ -377,7 +373,8 @@ export default {
 | 
			
		|||
      rdsDBPassword: { pattern: '^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\\W_]+$)(?![a-z0-9]+$)(?![a-z\\W_]+$)(?![0-9\\W_]+$)[a-zA-Z0-9\\W_]{8,32}$', message: '必须包含三种及以上类型:大小写字母、数字、特殊符号。长度为8-32位,特殊字符包括! @ # $ % ^ & * () _ + - =', trigger: null },
 | 
			
		||||
      searchConfigs: [
 | 
			
		||||
        { type: 'Input', label: '名称', value: 'name' },
 | 
			
		||||
        { type: 'Const', value: 'vendorId', initValue: this.platformObject.vendorId }
 | 
			
		||||
        { type: 'Const', value: 'vendorId', initValue: this.platformObject.vendorId },
 | 
			
		||||
        { type: 'Const', value: 'dbType', initValue: 'MYSQL' }
 | 
			
		||||
      ],
 | 
			
		||||
      columns,
 | 
			
		||||
      loading: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -524,7 +521,7 @@ export default {
 | 
			
		|||
        cancelButtonText: '取消',
 | 
			
		||||
        type: 'warning'
 | 
			
		||||
      }).then(() => {
 | 
			
		||||
        patchAliRds(data.id).then(data => {
 | 
			
		||||
        patchRds(data.id).then(data => {
 | 
			
		||||
          if (data.success) {
 | 
			
		||||
            this.$message({
 | 
			
		||||
              type: 'success',
 | 
			
		||||
| 
						 | 
				
			
			@ -535,13 +532,13 @@ export default {
 | 
			
		|||
        })
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    removeAliRds(data) {
 | 
			
		||||
    removeRds(data) {
 | 
			
		||||
      this.$confirm('确定释放该实例吗?', '提示', {
 | 
			
		||||
        confirmButtonText: '确定',
 | 
			
		||||
        cancelButtonText: '取消',
 | 
			
		||||
        type: 'warning'
 | 
			
		||||
      }).then(() => {
 | 
			
		||||
        removeAliRds(data.id).then(data => {
 | 
			
		||||
        removeRds(data.id).then(data => {
 | 
			
		||||
          if (data.success) {
 | 
			
		||||
            this.$message({
 | 
			
		||||
              type: 'success',
 | 
			
		||||
| 
						 | 
				
			
			@ -554,7 +551,7 @@ export default {
 | 
			
		|||
    },
 | 
			
		||||
    getData() {
 | 
			
		||||
      this.loading = true
 | 
			
		||||
      getAliRds(this.params).then(data => {
 | 
			
		||||
      getRds(this.params).then(data => {
 | 
			
		||||
        this.loading = false
 | 
			
		||||
        if (data.success) {
 | 
			
		||||
          this.tableData = data.data.rows
 | 
			
		||||
| 
						 | 
				
			
			@ -562,42 +559,16 @@ export default {
 | 
			
		|||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    handleSearch() {
 | 
			
		||||
      this.params.page = 1
 | 
			
		||||
      this.params.params = handleSearchParam({
 | 
			
		||||
        vendorId: this.platformObject.vendorId,
 | 
			
		||||
        regionId: this.searchData.regionId,
 | 
			
		||||
        zone: this.searchData.zone,
 | 
			
		||||
        'name:lk': this.searchData.name
 | 
			
		||||
      })
 | 
			
		||||
      this.getData()
 | 
			
		||||
    },
 | 
			
		||||
    handleCreate() {
 | 
			
		||||
      this.addData = {
 | 
			
		||||
        dialog: true,
 | 
			
		||||
        data: {
 | 
			
		||||
        vendorId: this.platformObject.vendorId,
 | 
			
		||||
          payType: 'Postpaid',
 | 
			
		||||
          regionId: '',
 | 
			
		||||
          type: 'MySQL',
 | 
			
		||||
          dataStoreVersion: '',
 | 
			
		||||
          category: '',
 | 
			
		||||
          volType: '',
 | 
			
		||||
          availZone: '',
 | 
			
		||||
          flavorId: '',
 | 
			
		||||
          volSize: 20,
 | 
			
		||||
          instanceNetworkType: 'Classic',
 | 
			
		||||
          vpcId: '',
 | 
			
		||||
          vswitchId: '',
 | 
			
		||||
          paramGroupId: '',
 | 
			
		||||
          timeZone: '+8:00',
 | 
			
		||||
          IgnoreCase: '1'
 | 
			
		||||
        }
 | 
			
		||||
        type: 'MySQL'
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    getDetail(id) {
 | 
			
		||||
      this.Super = false
 | 
			
		||||
      detailAliRds(id).then(data => {
 | 
			
		||||
      detailRds(id).then(data => {
 | 
			
		||||
        if (data.success) {
 | 
			
		||||
          this.detailData = data.data
 | 
			
		||||
          this.detailFlag = true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,79 +1,94 @@
 | 
			
		|||
import { request } from '@cmp/cmp-element'
 | 
			
		||||
import { wrapperParams, downloadFile } from 'utils'
 | 
			
		||||
const url = '/cmp/plugins/ctstack/v1/rds'
 | 
			
		||||
 | 
			
		||||
import { projectList, zoneList, flavorList } from './mockData'
 | 
			
		||||
const url = '/cmp/plugins/ctstack/v1/cloudrds'
 | 
			
		||||
// 是否开发环境
 | 
			
		||||
const isDev = process.env.NODE_ENV === 'development'
 | 
			
		||||
const mockRequest = data =>
 | 
			
		||||
  new Promise(resolve =>
 | 
			
		||||
    resolve({
 | 
			
		||||
      success: true,
 | 
			
		||||
      data
 | 
			
		||||
    })
 | 
			
		||||
  )
 | 
			
		||||
export function getRegion(params) {
 | 
			
		||||
  return request.get(`${url}/mysql/regions`, { params })
 | 
			
		||||
  return request.get(`${url}/regions`, { params })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getRdsProject(params) {
 | 
			
		||||
  if (isDev) return mockRequest(projectList)
 | 
			
		||||
  return request.get(`${url}/projects`, { params })
 | 
			
		||||
}
 | 
			
		||||
export function getRdsZone(params) {
 | 
			
		||||
  if (isDev) return mockRequest(zoneList)
 | 
			
		||||
  return request.get(`${url}/zones`, { params })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getFlavor(params) {
 | 
			
		||||
  return request.get(`${url}/mysql/flavors`, { params })
 | 
			
		||||
  if (isDev) return mockRequest(flavorList)
 | 
			
		||||
  return request.get(`${url}/flavors`, { params })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getParamGroup(params) {
 | 
			
		||||
  return request.get(`${url}/mysql/param/groups`, { params })
 | 
			
		||||
  return request.get(`${url}/param/groups`, { params })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function createRds(params) {
 | 
			
		||||
  return request.post(`${url}/mysql`, params)
 | 
			
		||||
  return request.post(`${url}`, params)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getRdsDbs(id, params) {
 | 
			
		||||
  return request.get(`${url}/mysql/${id}/dbs`, { params })
 | 
			
		||||
  return request.get(`${url}/${id}/dbs`, { params })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getRdsCos(id, params) {
 | 
			
		||||
  return request.get(`${url}/mysql/${id}/nets`, { params })
 | 
			
		||||
  return request.get(`${url}/${id}/nets`, { params })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getAliRds(params) {
 | 
			
		||||
  return request.get(`${url}/mysql`, { params })
 | 
			
		||||
export function getRds(params) {
 | 
			
		||||
  return request.get(`${url}`, { params })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function detailAliRds(id) {
 | 
			
		||||
  return request.get(`${url}/mysql/${id}`)
 | 
			
		||||
export function detailRds(id) {
 | 
			
		||||
  return request.get(`${url}/${id}`)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function patchAliRds(id) {
 | 
			
		||||
  return request.patch(`${url}/mysql/${id}`)
 | 
			
		||||
export function patchRds(id) {
 | 
			
		||||
  return request.patch(`${url}/${id}`)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function removeAliRds(id) {
 | 
			
		||||
  return request.delete(`${url}/mysql/${id}`)
 | 
			
		||||
export function removeRds(id) {
 | 
			
		||||
  return request.delete(`${url}/${id}`)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getRdsUsers(id, params) {
 | 
			
		||||
  return request.get(`${url}/mysql/${id}/users`, { params })
 | 
			
		||||
  return request.get(`${url}/${id}/users`, { params })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function createRdsUsers(id, params) {
 | 
			
		||||
  return request.post(`${url}/mysql/${id}/users`, params)
 | 
			
		||||
  return request.post(`${url}/${id}/users`, params)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function removeRdsUsers(params) {
 | 
			
		||||
  return request.delete(`${url}/mysql/${params.rdsId}/users/${params.userId}`)
 | 
			
		||||
  return request.delete(`${url}/${params.rdsId}/users/${params.userId}`)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function resetRdsUserPasd(params) {
 | 
			
		||||
  return request.put(`${url}/mysql/${params.rdsId}/users/${params.userId}/resetpassword`, wrapperParams(params))
 | 
			
		||||
  return request.put(`${url}/${params.rdsId}/users/${params.userId}/resetpassword`, wrapperParams(params))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function resetRdsUser(params) {
 | 
			
		||||
  return request.put(`${url}/mysql/${params.rdsId}/users/${params.userId}/resetaccount`, wrapperParams(params))
 | 
			
		||||
  return request.put(`${url}/${params.rdsId}/users/${params.userId}/resetaccount`, wrapperParams(params))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function authRdsUser(params) {
 | 
			
		||||
  return request.put(`${url}/mysql/${params.rdsId}/users/${params.userId}/dbs`, wrapperParams(params))
 | 
			
		||||
  return request.put(`${url}/${params.rdsId}/users/${params.userId}/dbs`, wrapperParams(params))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function createRdsDbs(id, params) {
 | 
			
		||||
  return request.post(`${url}/mysql/${id}/dbs`, params)
 | 
			
		||||
  return request.post(`${url}/${id}/dbs`, params)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function removeRdsDbs(params) {
 | 
			
		||||
  return request.delete(`${url}/mysql/${params.rdsId}/dbs/${params.dbId}`)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getFlavorSpec(params) {
 | 
			
		||||
  return request.get(`${url}/mysql/flavors/spec`, { params })
 | 
			
		||||
  return request.delete(`${url}/${params.rdsId}/dbs/${params.dbId}`)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue