<!--
 * @Author: ssl 710450920@qq.com
 * @Date: 2023-08-03 14:04:16
 * @LastEditors: ssl 710450920@qq.com
 * @LastEditTime: 2023-09-04 17:04:54
 * @FilePath: \csc\src\views\resource-apply\components\alterationItem.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <div class="card-wrapper" :class="itemData && !this.$route.query.id && 'no-order'">
    <div class="fix-header" v-if="!itemData">
      <div @click="$router.back()">
        <el-icon class="el-icon-back"></el-icon>
      </div>
      <p>{{ $route.meta.title }}</p>
    </div>
    <div class="fix-height" v-if="activeStep === 1">
      <changeVM ref="vm"></changeVM>
    </div>
    <div class="fix-height"  v-else>
      <el-row>
        <basic-form :model="addData" ref="addForm"  label-position="left" label-width="120px" :disabled="disabled">
          <div class="item-block">
            <h5>基本信息</h5>
            <basic-form-item label="所属项目：" prop="projectId" validate="required">
              <el-select v-model="addData.projectId" class="basic-cmp" :disabled="!!itemData" filterable>
                <el-option v-for="item in projectList" :key="item.id" :label="item.name" :value="item.id"></el-option>
              </el-select>
            </basic-form-item>
            <basic-form-item label="项目领导："  prop="configs.projectLeaderId" validate="required">
              <el-select v-model="addData.configs.projectLeaderId" class="basic-cmp" :disabled="disabled" filterable >
                <el-option v-for="item in useList" :key="item.id" :label="`${item.name}（${item.departmentPath || ''} ）`" :value="item.id"></el-option>
              </el-select>
            </basic-form-item>
            <template v-if="!itemData">
              <basic-form-item label="云主机名称：" prop="instanceName" validate="required" >
                <el-input class="basic-cmp" v-model="addData.instanceName" disabled></el-input>
              </basic-form-item>
              <basic-form-item label="IP地址：">
                <el-input class="basic-cmp" v-model="vmData.managerIp" disabled></el-input>
              </basic-form-item>
              <basic-form-item label="所属云平台：">
                  <el-input class="basic-cmp" v-model="addData.vendorName" disabled></el-input>
              </basic-form-item>
            </template>
          </div>
          <div class="item-block">
            <h5>原配置</h5>
            <basic-form-item label="规格：" v-if="(!!itemData && addData.operation === 'Upgrade') || addData.operation === 'Upgrade'">
              {{ !!itemData && addData.preview.skuId ? addData.preview.specName : `${vmData.cpu}C/${vmData.memory}GB/${vmData.disk}GB`}}
            </basic-form-item>
            <basic-form-item label="硬盘：">
              <volume :detail="addData" ref="disk"></volume>
            </basic-form-item>
          </div>
          <div class="item-block">
            <h5>新配置</h5>
            <basic-form-item label="变更类别：">
              <el-radio-group v-model="addData.operation" size="mini" :disabled="!!itemData" @change="changeOperation">
                <el-radio label="Upgrade" border>规格</el-radio>
                <el-radio label="AddDisk" border>磁盘</el-radio>
                <el-radio label="EditDisk" border>扩容</el-radio>
              </el-radio-group>
            </basic-form-item>
            <basic-form-item label="新规格：" v-if="addData.operation === 'Upgrade'">
              <sku-table :skus="specList" style="max-width: 600px">
                <el-table-column show-overflow-tooltip label="规格代码" prop="name">
                  <template v-slot="scope">
                    <el-radio v-model="addData.preview.skuId" :label="scope.row.id">{{scope.row.code}}</el-radio>
                  </template>
                </el-table-column>
              </sku-table>
            </basic-form-item>
            <basic-form-item label="新磁盘：" v-else-if="addData.operation === 'AddDisk'">
              <basic-table :data="addData.addDataDisks" style="max-width: 600px">
                <el-table-column show-overflow-tooltip label="容量(GB)" prop="disk">
                </el-table-column>
                <el-table-column v-if="addData.service !== 'sangfor.standard.server'" show-overflow-tooltip label="挂载目录" prop="device">
                </el-table-column>
                <el-table-column v-else show-overflow-tooltip label="存储策略">
                  <template slot-scope="{ row }">
                    <span v-if="row.preallocate === 'metadata'">动态分配</span>
                    <span v-if="row.preallocate === 'off'">精简分配</span>
                    <span v-if="row.preallocate === 'full'">预分配</span>
                  </template>
                </el-table-column>
                <el-table-column label="操作">
                  <template slot-scope="{ $index }">
                    <el-button type="text" @click="handleDeleteDisk($index)">移除</el-button>
                  </template>
                </el-table-column>
                <div slot="pagination"></div>
              </basic-table>
              <el-button type="text" v-if="addData.addDataDisks.length === 0" @click="handleAddDisk">新增</el-button>
            </basic-form-item>
            <template v-else>
              <div v-if="$refs.disk">
                <basic-form-item label="扩容磁盘：" prop="diskSkuId" validate="required">
                  <el-select v-model="addData.diskSkuId" class="basic-cmp" :disabled="disabled" filterable >
                    <el-option v-for="item in $refs.disk.list" :key="item.id" :label="item.name" :value="item.id"></el-option>
                  </el-select>
                </basic-form-item>
                <basic-form-item label="扩容至(GB)：" prop="diskSize" validate="required">
                  <el-select v-model="addData.categoryId"  class="m-r-xs basic-cmp" @chang="getSkuList(addData.categoryId, this.addData.serviceCode, 'disk')">
                    <el-option :label="item.name" v-for="(item, index) in categoryList" :key="index" :value="item.id"></el-option>
                  </el-select>
                  <el-select v-model="addData.diskSize"  class="basic-cmp" >
                    <el-option :label="generateSpec(item.spec)" v-for="item in diskList" :key="item.id" :value="item.id"></el-option>
                  </el-select>
                </basic-form-item>
                <basic-form-item v-if="vmData && vmData.vendorType === 'VMWARE'" label="创建lvm：" >
                  <el-checkbox class="m-l-xs" v-model="addData.editDataDisks[0].createLvm"></el-checkbox>
                </basic-form-item>
                <template v-if="addData.editDataDisks[0].createLvm">
                  <basic-form-item label="文件系统：" >
                    <el-select  v-model="addData.editDataDisks[0].fileSystem" placeholder="文件系统"  class="basic-cmp" >
                      <el-option v-for="(item, index) in fileList" :key="index" :label="item.name" :value="item.value"></el-option>
                    </el-select>
                  </basic-form-item>
                  <basic-form-item label="挂载目录：" >
                      <el-input v-model="addData.editDataDisks[0].device" class="basic-cmp"></el-input>
                      <el-checkbox v-model="addData.editDataDisks[0].forceMount" class="m-l-md">强制挂载</el-checkbox>
                  </basic-form-item>
                </template>
              </div>
            </template>
          </div>
            <basic-form :model="addData"  label-position="left" label-width="120px" v-if="addData.location">
              <Other :add-data="addData" :item-data="itemData" red></Other>
            </basic-form>
        </basic-form>
      </el-row>
    </div>
    <div class="footer" v-if="!itemData">
      <el-button @click="$router.back(-1)" style="width: 90px" type="ghost">返 回</el-button>
      <el-button style="width: 90px"  v-if="activeStep == 2" @click="activeStep -= 1 ">上一步</el-button>
      <el-button style="width: 90px" type="ghost" v-if="activeStep == 1" @click="step">下一步</el-button>
      <el-button style="width: 90px" type="primary" v-else @click="submit">提交</el-button>
    </div>
    <addDisk v-if="diskDialog.visible" :config="diskDialog" :service-code="`${vmData.vendorType.toLowerCase()}.${vmData.vendorType === 'VMWARE' ? 'storage.disk' : 'standard.volume'}`" :add-data.sync="addData"></addDisk>
  </div>
</template>

<script>
import changeVM from './changeVM.vue'
import volume from '../alteration/components/volume.vue'
import addDisk from '../alteration/addDisk.vue'
import { conditionProject } from 'services/system/project';
import { applyAlteration, detailVm, getDictChildren } from 'services/platform';
import { getCategoriesByCode, getSkus } from 'services/services/product'
import { getSpec, generateSpec, getSpecValue } from '@/views/resource-apply/utils/index'
import { getUser } from 'services/system/manager';
import Other from './Other.vue';

export default {
  components: { changeVM, volume, addDisk, Other },
  props: {
    itemData: {
      type: [Object, Boolean]
    },
    disabled: {
      type: Boolean
    }
  },
  data() {
    return {
      addData: {
        preview: {},
        location: {
          remark: '',
          groupId: ''
        },
        configs: {
          projectLeaderId: ''
        },
        editDataDisks: [{}]
      },
      vmData: null,
      activeStep: 1,
      ip: '',
      vendorName: '',
      projectList: [],
      specList: [],
      useList: [],
      diskDialog: {
        visible: false,
        data: {}
      },
      dilatationData: {},
      categoryList: [],
      diskList: [],
      fileList: [],
      generateSpec
    };
  },
  created() {
    this.getProjectList()
    this.getUseList()
    if (this.itemData) {
      this.activeStep += 1
      this.addData = this.itemData
      if (this.addData.operation === 'Upgrade') {
        if (typeof this.addData.preview === 'string') this.addData.preview = JSON.parse(this.addData.preview)
        this.getSkuList(this.addData.preview.categoryId, this.addData.service)
      } else {
        this.getDetails()
        if (this.addData.operation === 'EditDisk') {
          const { skuId: diskSkuId, serviceCode } = this.itemData.upgrade[0]
          this.addData = {
            ...this.itemData,
            diskSkuId,
            diskSize: '',
            serviceCode
          }
          this.getCategoryList()
          this.getFileList()
        }
      }
    }
  },
  methods: {
    async getDetails () {
      const { data } = await detailVm(this.addData.serverId)
      this.vmData = {
        ...data,
        service: this.addData.service
      }
    },
    async getProjectList () {
      const { tenantId, tenantAccount } = this.$store.state.app.userData
      const { data } = await conditionProject({ condition: JSON.stringify({ condition: 'listTenantProjects', tenantId: tenantId || tenantAccount.tenantId }) })
      this.projectList = data
    },
    async getFileList() {
      const { data } = await getDictChildren({ value: 'FS_TYPE' })
      this.fileList = data
    },
    async getSkuList(categoryId, serviceCode, type) {
      const { data } = await getSkus({ page: 1, rows: 9999, params: this.$tools.handleSearchParam({ categoryId, serviceCode }) })
      const skuList = data.map(item => {
        return {
          ...item,
          spec: JSON.parse(item.spec)
        }
      })
      if (type) {
        this.diskList = skuList;
        if (this.itemData) {
          this.addData.diskSize = skuList.find(item => item.spec[0].specValue == this.itemData.upgrade[0].specs[0].disk)?.id
        } else {
          this.addData.diskSize = skuList[0]?.id;
        }
      } else {
        this.specList = skuList
      }
    },
    async getUseList() {
      const { data: { rows } } = await getUser({ page: 1, rows: 99999 })
      this.useList = rows
    },
    async getCategoryList() {
      const { data } = await getCategoriesByCode(this.addData.serviceCode)
      this.categoryList = data
      if (!this.addData.categoryId) this.addData.categoryId = data[0]?.id
      this.getSkuList(this.addData.categoryId, this.addData.serviceCode, 'disk')
    },
    step() {
      if (!this.$refs.vm.vmData) return this.$message.error('请选择虚拟机')
      this.vmData = this.$refs.vm.vmData
      const { projectId, name, id, uuid, skuId, categoryId, cpu, memory, disk, expiredTime, vendorName, vendorType, service } = this.vmData
      this.vmData.service = vendorType.toLowerCase() + '.standard.server'
      this.addData = {
        serverId: id,
        service: this.vmData.service,
        serviceCode: vendorType === 'VMWARE' ? 'vmware.storage.disk' : 'sangfor.standard.volume',
        instance: uuid,
        instanceName: name,
        skuId,
        configs: {
          projectLeaderId: ''
        },
        preview: {
          skuId,
          categoryId,
          specName: `${cpu}C/${memory}GB/${disk}GB`
        },
        diskSkuId: '',
        diskSize: '',
        operation: 'Upgrade',
        projectId: '',
        expiredTime,
        vendorName,
        upgrade: [],
        addDataDisks: [],
        location: {
          remark: '',
          groupId: ''
        },
        editDataDisks: [{ name: '', disk: '', createLvm: false, forceMount: false, device: '', oldSize: '' }]
      }
      this.getSkuList(categoryId, this.addData.service)
      this.activeStep += 1
    },
    changeOperation(val) {
      if (val === 'EditDisk') {
        this.addData.categoryId = ''
        this.getCategoryList()
        this.getFileList()
      }
    },
    handleAddDisk() {
      this.diskDialog = {
        visible: true,
        data: this.vmData
      }
    },
    handleDeleteDisk(index) {
      this.addData.addDataDisks.splice(index, 1)
      this.addData.upgrade.splice(index, 1)
    },
    submit() {
      this.$refs.addForm.validate(async(valid) => {
        if (valid) {
          let params = null
          const { name, id, uuid, categoryId, cpu, memory, disk, vendorName, vendorType, service, expiredTime, osCategory, preview, configs, managerIp } = this.vmData
          const { projectId, location: { remark }, diskSkuId, diskSize } = this.addData
          if (!remark) return this.$message.error('请输入申请理由')
          if (this.addData.operation === 'Upgrade') {
            const { preview: { skuId } } = this.addData
            if (!skuId) return this.$message.error('请选择新规格')
            params = {
              preview: {
                skuId,
                categoryId,
                specName: `${cpu}C/${memory}GB/${disk}GB`
              },
              upgrade: [{
                serviceCode: this.addData.service,
                skuId,
                spec: getSpec(skuId, this.specList)
              }]
            }
          } else if (this.addData.operation === 'AddDisk') {
            if (!this.addData.addDataDisks.length) return this.$message.error('请新增磁盘')
          } else {
            const { name: diskName, size } = this.$refs.disk.list.find(item => item.id === diskSkuId)
            const newDiskSize = getSpecValue({ skuId: diskSize, skuList: this.diskList }).disk
            if (newDiskSize <= size) return this.$message.error('扩容大小不能小于等于当前磁盘大小')
            params = {
              preview: [
                { label: '云主机名称', value: name },
                { label: '云主机规格', value: `${cpu}C/${memory}GB/${disk}GB` },
                { label: 'IP地址', value: [managerIp] }
              ],
              params: {
                osCategory,
                type: vendorType
              },
              upgrade: [{
                serviceCode: this.addData.serviceCode,
                skuId: diskSkuId,
                uuid,
                specs: [{ ...getSpecValue({ skuId: diskSize, skuList: this.diskList }) }]
              }]
            }
            this.addData.editDataDisks = [{ ...this.addData.editDataDisks[0], name: diskName, ...getSpecValue({ skuId: diskSize, skuList: this.diskList }), oldSize: size }]
          }
          this.addData = {
            ...this.addData,
            ...params
          }
          const { success, message } = await applyAlteration(this.addData)
          if (success) {
            this.$message.success(message)
            this.$router.go(-1)
          }
        }
      })
    },
    getApplyData() {
      if (this.addData.operation === 'Upgrade') {
        this.addData.upgrade = [{
          serviceCode: this.addData.service,
          skuId: this.addData.preview.skuId,
          spec: getSpec(this.addData.preview.skuId, this.specList)
        }]
      }
      return this.addData
    }
  }
};
</script>

<style type="text/scss" lang="scss" scoped>
@import '../index.scss';
.footer {
  position: fixed;
  display: flex;
  justify-content: right;
  align-items: center;
  bottom: 0px;
  left: 48px;
  right: 0px;
  height: 50px;
  padding-right: 20px;
  background: white;
}
</style>
