<template>
  <div class="yaBox">
    <YaEditForm
      :formColumns="formColumns"
      :formData="formDataConfig"
      @submit="handlerToSubmit"
      :loading="loading"
    >
      <template #tcpPortInfo>
        <!-- TCP端口扫描 -->
        <div class="level-top radio-block">
          <div
            class="flex-bt"
            style="width: 100%"
            v-for="(item, index) in tcpPortList"
            :key="index"
          >
            <el-radio
              v-model="
                formDataConfig.remoteScanDefaultConfig.detectScanConfig
                  .tcpPortScanRange
              "
              :label="item.value"
            >
              <span>{{ item.label }}</span>
            </el-radio>
            <div
              v-if="item.value == 'standard'"
              class="port-list"
              @click="toPort"
            >
              编辑端口服务列表
            </div>
            <div v-if="item.value == 'fast'"></div>
            <div
              v-if="item.value == 'customize'"
              class="m-l-8 port-range flex-one"
            >
              <el-input
                v-model="
                  formDataConfig.remoteScanDefaultConfig.detectScanConfig
                    .tcpScanPort
                "
                placeholder="请输入1-65535"
              ></el-input>
            </div>
          </div>
        </div>
      </template>
      <template #tcpScanInfo>
        <!-- TCP端口扫描方式 -->
        <div class="level-top">
          <el-radio-group
            v-model="
              formDataConfig.remoteScanDefaultConfig.detectScanConfig
                .tcpPortScanType
            "
          >
            <el-radio
              v-for="(item, index) in tcpPortScanType"
              :key="index"
              :label="item.value"
            >
              <span>{{ item.label }}</span>
              <span v-if="item.value == 0"> </span>
              <span v-if="item.value == 1"> </span>
            </el-radio>
          </el-radio-group>
        </div>
      </template>
      <template #udpScanInfo>
        <!-- UDP扫描端口 -->
        <div class="level-top">
          <div class="scan-port">
            <span class="scan-port-chose"
              ><el-switch
                v-model="
                  formDataConfig.remoteScanDefaultConfig.detectScanConfig
                    .udpScanEnable
                "
            /></span>
            <el-input
              v-model="
                formDataConfig.remoteScanDefaultConfig.detectScanConfig
                  .udpScanPort
              "
              placeholder="请输入1-65535"
            ></el-input>
          </div>
        </div>
      </template>
      <template #configInfo>
        <!-- 探活方式 -->
        <div class="level-top">
          <el-checkbox
            disabled
            v-model="
              formDataConfig.remoteScanDefaultConfig.detectSurviveConfig
                .icmpPing
            "
            label="true"
            >ICMP PING</el-checkbox
          >
          <div class="flex-bt" style="margin-bottom: 12px">
            <el-checkbox
              v-model="
                formDataConfig.remoteScanDefaultConfig.detectSurviveConfig
                  .udpPing
              "
              label="true"
            >
              UDP PING端口
            </el-checkbox>
            <div class="m-l-12 ping-port flex-one">
              <el-input
                v-model="
                  formDataConfig.remoteScanDefaultConfig.detectSurviveConfig
                    .udpPort
                "
                placeholder="请输入1-65535"
              ></el-input>
            </div>
          </div>
          <div class="flex-bt">
            <el-checkbox
              v-model="
                formDataConfig.remoteScanDefaultConfig.detectSurviveConfig
                  .tcpPing
              "
              label="true"
              :disabled="
                formDataConfig.remoteScanDefaultConfig.detectSurviveConfig
                  .tcpPingAllPort
                  ? true
                  : false
              "
            >
              TCP PING端口
            </el-checkbox>
            <div class="m-l-16 ping-port flex-one">
              <el-input
                v-model="
                  formDataConfig.remoteScanDefaultConfig.detectSurviveConfig
                    .tcpPort
                "
                placeholder="请输入1-65535"
              ></el-input>
            </div>
          </div>
          <el-checkbox
            v-model="
              formDataConfig.remoteScanDefaultConfig.detectSurviveConfig
                .tcpPingAllPort
            "
            :disabled="
              formDataConfig.remoteScanDefaultConfig.detectSurviveConfig.tcpPing
                ? true
                : false
            "
            label="true"
            >TCP PING全端口</el-checkbox
          >
        </div>
      </template>
    </YaEditForm>
  </div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import {
  getGlobalConfig,
  modifyGlobalConfig,
} from '../../../../api/collection/collectConfig/acquiesceConfig';
import { yaMessage } from '../../../../utils/message';
import { getDictTypeList } from '../../../../api/common';
import { useRouter } from 'vue-router';
const router = useRouter();
//发包速率的校验
var checkRate = (rule, value, callback) => {
  if (value < 500) {
    callback(new Error('范围在500-200000'));
  } else if (value > 200000) {
    callback(new Error('范围在500-200000'));
  } else {
    callback();
  }
};
//重试次数的校验
var checkRetry = (rule, value, callback) => {
  if (value < 0) {
    callback(new Error('范围在0-8'));
  } else if (value > 8) {
    callback(new Error('范围在0-8'));
  } else {
    callback();
  }
};
//间隔时间的校验
var checkInterval = (rule, value, callback) => {
  if (value < 100) {
    callback(new Error('范围在100-1000'));
  } else if (value > 1000) {
    callback(new Error('范围在100-1000'));
  } else {
    callback();
  }
};
//超时时间的校验
var checkTimeout = (rule, value, callback) => {
  if (value < 1) {
    callback(new Error('范围在1-30'));
  } else if (value > 30) {
    callback(new Error('范围在1-30'));
  } else {
    callback();
  }
};
const detectModeList = ref([]);
const tcpPortList = ref([]);
const tcpPortScanType = ref([]);
const disabled = ref(false);
//表单
const formColumns = ref([
  {
    title: '默认参数设置',
    formItemClassName: 'line',
  },
  {
    key: 'mode',
    type: 'radio',
    label: '远程探测设置',
    options: [
      {
        key: '快速模式',
        value: '0',
      },
      {
        key: '标准模式',
        value: '1',
      },
      {
        key: '精准模式',
        value: '2',
      },
    ],
    onChange(data) {
      handlerChangeMode(data);
    },
    value: null,
  },
  {
    key: 'rate',
    type: 'input',
    label: '发包速率',
    isType: 'number',
    value: null,
    rules: [{ validator: checkRate, trigger: 'change' }],
    tooltip:
      '存活探测每秒的发包数，快速模式默认值为10000，标准模式为8000，精准模式为5000',
  },
  {
    key: 'retry',
    type: 'input',
    label: '重试次数',
    isType: 'number',
    value: null,
    rules: [{ validator: checkRetry, trigger: 'change' }],
    tooltip:
      '代表探测的过程中重新尝试的次数，快速模式默认值0，标准模式为2，精准模式为3',
  },
  {
    key: 'interval',
    type: 'input',
    label: '间隔时间',
    isType: 'number',
    value: null,
    rules: [{ validator: checkInterval, trigger: 'change' }],
    tooltip:
      '针对单个IP的发包间隔时间，单位为毫秒（ms），快速模式默认值为100毫秒，标准模式为300毫秒，精准模式默认值为500毫秒',
  },
  {
    key: 'timeout',
    type: 'text',
    isType: 'number',
    label: '超时时间',
    rules: [{ validator: checkTimeout, trigger: 'change' }],
    value: null,
    tooltip:
      '代表响应的最大等待时间，单位为秒（s）,快速模式默认值为3秒，标准模式为4秒，精准默认值为5秒',
  },
  {
    slotName: 'tcpPortInfo',
    label: 'TCP端口扫描',
    tooltip:
      '标准端口扫描测策略扫描目标的已知各种应用、木马等使用的端口。\n扫描1-1024；\n端口范围：1-65535；多个端口以英文“,”隔开，建议输入十个端口以内！',
  },
  {
    slotName: 'tcpScanInfo',
    label: 'TCP端口扫描方式',
    tooltip:
      '向目标端口发送SYN包，依据对方是否回复ACK报文来判断端口开放情况。\n推荐选项，通过直接建立完整的TCP连接来判断端口开放情况，此方法快而准确！',
  },
  {
    slotName: 'udpScanInfo',
    label: 'UDP扫描端口',
    tooltip: '端口范围：1-65535；多个端口以英文“,”隔开；建议输入十个端口以内！',
  },
  {
    slotName: 'configInfo',
    label: '探活方式',
    tooltip:
      '向目标主机发送UDP数据报文，根据目标主机的反应以判断其是否存活。\n向目标主机TCP SYN/ACK/FIN等数据报文，根据目标主机的反应以判断其是否存活。',
  }, {
    key: 'gatherMode',
    type: 'radio',
    label: '信息远程采集设置',
    options: [
      {
        key: '主机标准模式',
        value: 'standard',
      },
      {
        key: '主机精准模式',
        value: 'precision',
      },
    ],
    value: null,
  },
]);
//表单的数据----扫描模式默认参数设置
const formDataConfig = ref({
  remoteScanDefaultConfig: {
    detectScanConfig: {
      tcpPortScanRange: null,
      tcpPortScanType: null,
      tcpScanPort: null,
      udpScanEnable: null,
      udpScanPort: null,
    },
    detectSurviveConfig: {
      icmpPing: null,
      tcpPing: null,
      tcpPingAllPort: null,
      tcpPort: null,
      udpPing: null,
      udpPort: null,
    },
    modeConfig: {
      mode: null,
    },
  },
});
//获取任务默认参数配置
const initData = (val?) => {
  getGlobalConfig().then((res) => {
    let { code, data } = res || {};
    data = data || {};
    if (code == 200) {
      const quick = data.detectModeParamConfig?.quick;
      const standard = data.detectModeParamConfig?.standard;
      const slow = data.detectModeParamConfig?.slow;
      const modeConfig = data.remoteScanDefaultConfig.modeConfig;
      for (let key in modeConfig) {
        formColumns.value.map((item) => {     
          item.key == key&&(item.value = modeConfig[key])
        });
      }
      formColumns.value.map(item=>{
        item.key=='gatherMode'&&(item.value=data.remoteInfoGatherConfig.gatherMode)
      })
      // 非自定义模式不可编辑
      disabled.value = modeConfig.mode != 3;
      formDataConfig.value.remoteScanDefaultConfig =
        data.remoteScanDefaultConfig;
      detectModeData.value = [quick, standard, slow] as any;
    }
  });
};
//资产扫描默认配置--不同模式的切换事件
const handlerChangeMode = (val) => {
  for (let item in detectModeData.value[val]) {
    item != 'mode' &&
      formColumns.value.map((child) => {
        if (item == child.key) {
          child.value = detectModeData.value[val][item];
        }
      });
  }
};
onMounted(() => {
  getDictList();
  initData();
});
let loading = ref(false);
//修改数据的接口
const handlerToSubmit = (data) => {
  loading.value = true;
  let params = {
    detectModeParamConfig: {},
    remoteScanDefaultConfig: {
      detectScanConfig:
        formDataConfig.value.remoteScanDefaultConfig.detectScanConfig,
      detectSurviveConfig:
        formDataConfig.value.remoteScanDefaultConfig.detectSurviveConfig,
      modeConfig: {
        retry: data.retry,
        mode: data.mode,
        interval: data.interval,
        rate: data.rate,
        timeout: data.timeout,
      },
    },
    remoteInfoGatherConfig:{
      gatherMode:data.gatherMode
    }
  };

  params.detectModeParamConfig = {
    quick: detectModeData.value[0],
    standard:detectModeData.value[1],
    slow:  detectModeData.value[2],
  };

  modifyGlobalConfig(params)
    .then((res) => {
      const { code, message } = res;
      if (code == 200) {
        yaMessage(message, 'success');
        initData(data.mode);
      }
    })
    .finally(() => {
      loading.value = false;
    });
};
/**
 * @desciption 监听扫描模式
 */
//不同扫描模式的数据
const detectModeData = ref([]);

/**
 * @description: 端口策略列表
 */
const toPort = () => {
  router.push({
    path: '/system/systemConfig/portStrategy',
  });
};
/**
 * @description: 字典数据初始化
 */
const resetDictData = (e) => {
  let list = e.map((item) => {
    return {
      label: item.dictName,
      value: item.dictValue,
    };
  });
  return list;
};
//获取下拉框数据
const getDictList = () => {
  // 扫描模式
  getDictTypeList({ dictType: 'detectMode' }).then((res) => {
    if (res.code == 200) {
      detectModeList.value = resetDictData(res.data).map((item) => {
        item.value = Number(item.value);
        return item;
      });
    }
  });
  // TCP端口扫描
  getDictTypeList({ dictType: 'portScanRange' }).then((res) => {
    if (res.code == 200) {
      tcpPortList.value = resetDictData(res.data);
    }
  });
  // tcp 端口扫描方式
  getDictTypeList({ dictType: 'tcpPortScanType' }).then((res) => {
    if (res.code == 200) {
      tcpPortScanType.value = resetDictData(res.data).map((item) => {
        item.value = Number(item.value);
        return item;
      });
    }
  });
};
</script>
<style lang="scss" scoped>
.yaBox {
  .level-top {
    width: 100%;
  }
  .flex-bt,
  .scan-port {
    display: flex;
  }
  .scan-port {
    ::v-deep .el-input {
      max-width: calc((100% - 156px) / 2);
    }
  }
  .ping-port {
    ::v-deep .el-input {
      max-width: calc((100% - 181px) / 2);
    }
  }
  .flex-one {
    flex: 1;
  }
  .radio-block {
    ::v-deep .el-radio {
      margin-right: 12px;
    }
    ::v-deep .el-input {
      max-width: calc((100% - 167px) / 2);
    }
  }

  ::v-deep .el-checkbox,
  ::v-deep .el-switch {
    margin-right: 12px;
  }
  .port-list {
    color: #0079ea;
    font-weight: 400;
    text-decoration: underline;
    cursor: pointer;
  }
}
</style>
