<template>
  <div class="app-container upload-model">
    <div class="search-container" style="padding-top:4px;padding-right:20px;">
      <h4>模型基本信息</h4>
      <el-form ref="uploadForm" :rules="upRules" :model="upForm" label-width="120">
        <el-row>
          <el-col :span="12">
            <el-form-item label="模型名称" prop="model_name">
              <el-input v-model="upForm.model_name" placeholder="请输入模型名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12" class="div-mode-type">
            <el-row>
              <el-col :span="14">
                <el-form-item label="模型类型" prop="modl_main_type">
                  <el-select v-model="upForm.modl_main_type" placeholder="请选择" @change="doMainTypeChange">
                    <el-option v-for="(it, idx) in listOpt.modelType" :key="idx" :label="it.modl_main_type_name"
                      :value="it.modl_main_type" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="10">
                <el-form-item label="" prop="modl_sub_type" class="form-item-sub-type">
                  <el-select v-model="upForm.modl_sub_type" placeholder="请选择">
                    <el-option v-for="(it, idx) in listOpt.modelSubType" :key="idx" :label="it.modl_sub_type_name"
                      :value="it.modl_sub_type" />
                  </el-select>
                </el-form-item>
              </el-col>
            </el-row>

          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="模型版本" prop="model_version">
              <el-input v-model="upForm.model_version" placeholder="请输入模型版本" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="模型描述">
              <el-input v-model="upForm.model_desc" type="textarea" style="width:100%;" :rows="4"
                placeholder="请输入模型描述" />
            </el-form-item>
          </el-col>

        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="算法框架" prop="modl_framework">
              <el-select v-model="upForm.modl_framework" placeholder="请选择" style="width: 48%;margin-left:2%;">
                <el-option v-for="(it, idx) in listOpt.modelFramework" :label="it" :value="it" :key="idx" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12" class="div-mode-type">
            <el-row>
              <el-col :span="14">
                <el-form-item label="模型网络" prop="modl_net_main_type">
                  <el-select v-model="upForm.modl_net_main_type" placeholder="请选择" @change="doNetMainTypeChange">
                    <el-option v-for="(it, idx) in listOpt.modelNetType" :label="it.model_net_serial"
                      :value="it.model_net_serial" :key="idx" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="10">
                <el-form-item label="" prop="modl_net_type" class="form-item-sub-type">
                  <el-select v-model="upForm.modl_net_type" placeholder="请选择">
                    <el-option v-for="(it, idx) in listOpt.modelNetSubType" :label="it" :value="it" :key="idx" />
                  </el-select>
                </el-form-item>
              </el-col>
            </el-row>

          </el-col>

        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="文件格式" prop="modl_file_type">
              <el-select v-model="upForm.modl_file_type" placeholder="请选择" style="width: 48%;margin-left:2%;">
                <el-option v-for="(it, idx) in listOpt.modelFileType" :label="it" :value="it" :key="idx" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">

          </el-col>

        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="网络参数" prop="model_file_list">
              <el-upload ref="uploadRef1" class="uploadFile1" :http-request="handleFileChange"
                :on-remove="handleFileRemove" :on-exceed="handleFileExceed" :auto-upload-demo="false" :limit="1"
                accept=".onnx,.ts">
                <el-button type="primary"><el-icon class="el-icon--upload"> <i-ep-upload-filled />
                  </el-icon>选择文件</el-button>
                <template #tip>
                  <div class="el-upload__tip">
                    请上传大小不超过<span style="color:coral">10M</span>,格式为<span style="color:coral">onnx/ts</span>的文件
                  </div>
                </template>
              </el-upload>
            </el-form-item>
          </el-col>
          <el-col :span="12" style="position: relative;">
            <el-button v-if="upForm.model_parameters" style="position: absolute;left:240px;z-index:999"
              @click="showModelParameters">
              <i-ep-view />
              查看配置</el-button>
            <el-form-item label="网络配置" prop="model_parameters">
              <el-upload class="upload-demo" ref="uploadRef2" :on-remove="handleFileRemoveCfg"
                :on-exceed="handleFileExceed" :auto-upload-demo="false" :http-request="handleUploadCfg" :limit="1"
                accept=".json">
                <el-button type="primary"><el-icon class="el-icon--upload"> <i-ep-upload-filled />
                  </el-icon>选择文件</el-button>
                <template #tip>
                  <div class="el-upload__tip">
                    请上传大小不超过<span style="color:coral">10M</span>,格式为<span style="color:coral">json</span>的文件
                  </div>
                </template>
              </el-upload>
            </el-form-item>
          </el-col>

        </el-row>
      </el-form>
    </div>
    <div class="div-log" v-if="1 == 2">
      <div style="font-weight: bold;font-size:14px;padding:10px 10px">分割日志</div>
      <el-card class="split-log">
        <div v-for="(it, idx) in logList" :key="idx" class="log-item">
          <span>{{ it.date }}</span>
          <span>{{ it.log }}</span>
        </div>
      </el-card>
    </div>
    <el-card class="card-footer">
      <el-button type="primary" @click="doSave">分割</el-button>
      <el-button @click="doBack">取消</el-button>
    </el-card>
  </div>
  <JsonViewDlg ref="jsonDlg"></JsonViewDlg>
</template>

<script setup>
import ConstApi from '@/api/const'
import ModelApi from '@/api/models'
import request from "axios";
const router = useRouter();
let listOpt = reactive({
  modelType: [],
  modelFramework: [],
  modelNetType: [],
  modelFileType: [],
  modelSubType: [],
  modelNetSubType: [],
  upFiles: [],
})
let fileList = ref([])
const uploadRef1 = ref()
let jsonDlg = ref()

const doSave = () => {
  uploadForm.value?.validate((valid) => {
    if (valid) {
      ModelApi.add(upForm).then(d => {
        if (d.data.code == 0) {
          ElMessage.success("增加模型成功!");
          router.push({ path: "/modelMgr/index" })
        }
      })

    }
  });
}
const doBack = () => {
  router.push({ path: "/modelMgr/index" })
}
const uploadForm = ref(ElForm)
let upForm = reactive({
  model_name: '',
  model_version: '',
  model_desc: '',
  modl_main_type: '',
  modl_sub_type: '',
  modl_net_main_type: '',
  modl_net_type: '',
  modl_framework: '',
  modl_file_type: '',
  model_parameters: null,
  model_file_list: [

  ]
})
const showModelParameters = () => {
  jsonDlg.value.showDialog({
    title: '查看网络配置',
    width: '800px',
    data: upForm.model_parameters
  })
}
const logList = reactive([{
  date: '2024-05-06 18:34:36', log: '系统已启动编译'
}, { date: '2024-05-06 18:34:36', log: '系统正在分割目标文件' },
{ date: '2024-05-06 18:34:36', log: '运行时异常，系统编译已终止' }])

const upRules = computed(() => {
  return {
    model_name: [{ required: true, trigger: "blur", message: "请输入模型名称", },],
    modl_main_type: [{ required: true, trigger: "blur", message: "请选择主类型", }],
    modl_sub_type: [{ required: true, trigger: "blur", message: "请选择子类型", }],
    model_version: [{ required: true, trigger: "blur", message: "请输入模型版本", }],
    modl_framework: [{ required: true, trigger: "blur", message: "请选择算法框架", }],
    modl_net_main_type: [{ required: true, trigger: "blur", message: "请选择主模型网络", }],
    modl_net_type: [{ required: true, trigger: "blur", message: "请选择模型网络", }],
    modl_file_type: [{ required: true, trigger: "blur", message: "请选择文件类型", }],
    model_file_list: [{ required: true, trigger: "blur", message: "请上传网络参数", }],
    model_parameters: [{ required: true, trigger: "blur", message: "请上传网络配置", }],
  }
});

const handleFileRemoveCfg = (a, b) => {
  upForm.model_parameters = null;
}
const handleUploadCfg = (file) => {
  if (file.file.size > 10 * 1024 * 1024) {
    ElMessage.warning("文件大小不能超10M");
    file.onError("文件大小不能超10M")
    return;
  }
  let ext = file.file.name.split(".").pop().toLowerCase();
  if (["json"].indexOf(ext) == -1) {
    ElMessage.warning("请上传json格式文件");
    file.onError("请上传json格式文件")
    return;
  }
  //先创建一个读文件的对象 FileReader
  let reader = new FileReader();
  //判断浏览器是否支持 FileReader
  if (typeof FileReader === "undefined") {
    ElMessage.warning("您的浏览器不支持文件读取。");
    file.onError("您的浏览器不支持文件读取。")
    return;
  }
  uploadFile(file).then((res) => {
    if (isJSON(res)) {
      upForm.model_parameters = JSON.parse(res);
    }
  });
}

/** 解析json */
function isJSON(str) {
  try {
    // 尝试解析输入的字符串
    JSON.parse(str);
    return true;
  } catch (error) {
    return false;
  }
}

// 文件读取
function uploadFile(file) {
  return new Promise(function (resolve, reject) {
    let reader = new FileReader();
    reader.readAsArrayBuffer(file.file);
    reader.onload = function (e) {
      var ints = new Uint8Array(e.target.result); //要使用读取的内容，所以将读取内容转化成Uint8Array
      let snippets = new TextDecoder("UTF-8").decode(ints); //二进制缓存区内容转化成中文（即也就是读取到的内容）
      resolve(snippets);
    };
  });
}


// 文件上传
function handleFileChange(file, b) {
  if (file.file.size > 10 * 1024 * 1024) {
    ElMessage.warning("文件大小不能超10M");
    file.onError("文件大小不能超10M")
    return;
  }
  let ext = file.file.name.split(".").pop().toLowerCase();
  if (["onnx", "ts"].indexOf(ext) == -1) {
    ElMessage.warning("请上传onnx/ts格式文件");
    file.onError("请上传onnx/ts格式文件")
    return;
  }
  ModelApi.upload(file.file).then((res) => {
    listOpt.upFiles.push({
      name: file.file.name,
      serverName: res.data.data.file_name
    })
    upForm.model_file_list = listOpt.upFiles.map(it => it.serverName);
  });

}

function handleFileExceed() {
  ElMessage.warning("超过上传上限！");
}

function handleFileRemove(a, b, c) {
  let tmps = listOpt.upFiles.filter(d => d.name == a.name);
  if (tmps.length > 0) {
    let idx = listOpt.upFiles.indexOf(tmps[0]);
    listOpt.upFiles.splice(idx, 1);
  }
  upForm.model_file_list = listOpt.upFiles.map(it => it.serverName);
}

const initData = () => {
  let ajaxs = [];
  ajaxs.push(ConstApi.modlMainType());
  ajaxs.push(ConstApi.modlFramework());
  ajaxs.push(ConstApi.modlNetType());
  ajaxs.push(ConstApi.modlFileType());
  request.all(ajaxs).then(res => {
    listOpt.modelType = res[0].data?.data?.modl_main_type_list || [];
    listOpt.modelFramework = res[1].data?.data?.modl_framework_list || [];
    listOpt.modelNetType = (res[2].data?.data?.modl_net_type_list || []).map(it => {
      it.selected = false;
      it.subSelect = "";
      return it;
    });
    listOpt.modelFileType = res[3].data?.data?.modl_file_type_list || [];
  });
}
const doMainTypeChange = () => {
  let mainType = upForm.modl_main_type;
  let subList = listOpt.modelType.filter(d => d.modl_main_type == mainType);
  listOpt.modelSubType = subList.length > 0 ? subList[0].modl_sub_type_list || [] : [];
  if (listOpt.modelSubType.filter(d => d.modl_sub_type == upForm.modl_sub_type).length == 0) {
    upForm.modl_sub_type = '';
  }
}
const doNetMainTypeChange = () => {
  let tmps = listOpt.modelNetType.filter(d => d.model_net_serial == upForm.modl_net_main_type);
  listOpt.modelNetSubType = tmps.length > 0 ? tmps[0].model_net_type_list : [];
  upForm.modl_net_type = '';
}
onMounted(() => {
  initData();
});

</script>
<style scoped lang='scss'>
.card-footer {
  position: fixed;
  width: calc(100% - 215px);
  bottom: 0px;
}

.div-log {
  font-size: 12px;

  :deep(.el-card__body) {
    padding: 8px;
  }
}
</style>
<style lang="scss">
.upload-model {
  .div-mode-type {
    .form-item-sub-type {
      .el-form-item__content {
        margin-left: 10px !important;
      }
    }
  }
}
</style>