<!-- 用户管理 -->
<template>
  <div class="app-container model-detail">
    <!-- 用户新增/编辑表单 -->
    <el-card v-loading="loading">
      <template #header><svg-icon icon-class="pause" style="width: 20px; height: 20px" />数据集基本信息
      </template>
      <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
        <el-row>
          <el-col :lg="12" :xs="24">
            <el-form-item label="数据集名称" prop="dataset_name">
              <el-input v-model="form.dataset_name" placeholder="请输入数据集名称" />
            </el-form-item>
          </el-col>
          <el-col :lg="12" :xs="24">
            <el-form-item label="数据集版本" prop="dataset_version">
              <el-input v-model="form.dataset_version" type="number" placeholder="请输入数据集版本" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :lg="12" :xs="24">
            <el-form-item label="适合模型类型" prop="modl_sub_type">
              <el-select v-model="form.modl_sub_type" disabled placeholder="请选择适合模型类型">
                <el-option v-for="item in listOpt.modlSubTypeList" :key="item.modl_sub_type"
                  :label="item.modl_sub_type_name" :value="item.modl_sub_type" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :lg="12" :xs="24">
            <el-form-item label="数据集格式" prop="dats_dataset_format">
              <el-select v-model="form.dats_dataset_format" disabled placeholder="请选择数据集格式">
                <el-option v-for="item in listOpt.datasetFormatList" :key="item" :label="item" :value="item" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :lg="12" :xs="24">
            <el-form-item label="标注类型" prop="dats_label_type">
              <el-select v-model="form.dats_label_type" disabled placeholder="请选择标注类型">
                <el-option v-for="item in listOpt.labelTypeList" :key="item" :label="item" :value="item" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :lg="12" :xs="24">
            <el-form-item label="图像分辨率" prop="image_height">
              <el-row style="width: 100%">
                <el-col :lg="11">
                  <el-input v-model="form.image_width" disabled placeholder="请输入分辨率宽度">
                    <template #prepend> 宽 </template>
                  </el-input>
                </el-col>
                <el-col :lg="2" class="font-center"><el-icon>
                    <Rank />
                  </el-icon></el-col>
                <el-col :lg="11">
                  <el-input v-model="form.image_height" disabled placeholder="请输入分辨率高度">
                    <template #prepend> 高 </template>
                  </el-input>
                </el-col>
              </el-row>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :lg="12" :xs="24">
            <el-form-item label="数据集描述" prop="dataset_desc">
              <el-input v-model="form.dataset_desc" placeholder="请输入数据集描述" :rows="2" type="textarea" />
            </el-form-item>
          </el-col>
          <el-col :lg="12" :xs="24"> </el-col>
        </el-row>
        <el-row>
          <el-col :lg="12" :xs="24">
            <el-form-item label="数据集参数文件" prop="dataset_parameters">
              <el-upload ref="uploadRef" class="upload-demo upload-demo-1" :on-change="handleFileChange"
                :on-remove="handleFileRemove" :on-exceed="handleFileExceed" :auto-upload="false" :limit="1"
                accept="application/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">
                    请上传大小不超过 <strong style="color: red">10M</strong>，格式为
                    <strong style="color: red">json</strong> 的文件
                  </div>
                </template>
              </el-upload>
            </el-form-item>
          </el-col>
          <el-col :lg="12" :xs="24">
            <div style="padding-left: 35px" v-if="fileStatus">
              <el-divider content-position="left"><strong style="color: #409eff">数据集参数文件预览</strong></el-divider>
              <json-viewer :value="jsonData.data" copyable boxed sort theme="my-json-view jv-light" />
            </div>
          </el-col>
        </el-row>
      </el-form>
    </el-card>
    <el-card style="margin-top: 12px">
      <template #header><svg-icon icon-class="pause" style="width: 20px; height: 20px" />图片信息<strong
          style="color: #409eff">（{{ imgCount }}）</strong>
        <el-button type="primary" style="position: absolute; right: 30px" @click="handleRemoveAll"
          :disabled="imageList.length == 0"><i-ep-delete />清空全部</el-button>
      </template>
      <el-upload v-model:file-list="imageList" class="upload-demo upload-demo-2" :before-remove="beforeRemove" :on-preview="handlePreview"/>
      <el-empty v-if="imageList.length == 0" description="暂 无 数 据" />
    </el-card>
    <el-card class="card-footer">
      <el-button type="primary" @click="handleImageDialog"><i-ep-upload-filled />上传图片</el-button>
      <el-button type="primary" @click="handleSubmit"><i-ep-check />确 定</el-button>
      <el-button @click="closeBack"><i-ep-close />取 消</el-button>
    </el-card>
    <el-dialog v-model="dialogVisible" title="上传标注图片" width="880" append-to-body style="max-height:650px;">
      <el-card v-loading.fullscreen.lock="uploadLoading">
        <el-upload v-model:file-list="uploadImgFileList" class="upload-demo upload-demo-3"
          :before-remove="handleRemoveFiles" :auto-upload="autoUpload" :on-change="handleChangeFiles"
          list-type="picture" multiple accept="application/json,text/plain,image/jpeg">
          <!--accept="application/json,image/png,image/jpg,image/jpeg"-->
          <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">
              请上传大小不超过 <strong style="color: red">10M</strong>，格式为
              <strong style="color: red">json/txt/jpg</strong> 的文件
            </div>
          </template>
        </el-upload>
        <el-empty v-if="uploadImgFileList.length == 0" description="暂 无 数 据" />
      </el-card>
      <!-- 弹窗底部操作按钮 -->
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" :disabled="uploadImgFileList.length == 0" @click="checkUploadFiles">开始上传</el-button>
          <el-button @click="dialogVisible = false">取 消</el-button>
        </div>
      </template>
    </el-dialog>
    <div class="demo-image__preview">
      <el-image
        
        class="imgPreView"
        :src="imgPreSrc"
        :zoom-rate="1.2"
        :max-scale="7"
        :min-scale="0.2"
        :preview-src-list="imgPreSrcList"
        :initial-index="4"
        style="width: 1px; height: 1px"
        fit="cover"
      />
    </div>
  </div>
</template>

<script setup>
import ConstApi from "@/api/const";
import DataSetApi from "@/api/dataSet";
const route = useRoute();
const router = useRouter();

const ID = ref(""); // 编号
const form = ref({}); // 基础表单
const formRef = ref(ElForm); // 表单
const loading = ref(false); //  加载状态
const dialogOpen = ref(false); //  加载状态
const fileStatus = ref(false); //  文件状态
const codeHtml = ref(""); //  文件信息
const jsonData = reactive({
  data: {}
})
const imgViewer = ref(false);
const imgPreSrc = ref("");
const imgPreSrcList = ref([]);
const imgViewerRef = ref(""); // 图片预览组件
const imgCount = ref(0); //  图片信息
const imageList = ref([]); //  图片列表
const remImageList = ref([]); //  删除图片列表
// 上传组件
const uploadRef = ref();

const autoTime = ref(""); //  自动上传
const autoUpload = ref(false); //  自动上传
const dialogVisible = ref(false); //  加载状态
const uploadLoading = ref(false); //  加载状态
const uploadAllList = ref([]); //  待上传文件列表
const uploadJsonList = ref([]); //  待上传JSON列表
const uploadImgFileList = ref([]); //  待上传图片列表

// 基础数据列表
let listOpt = reactive({
  labelTypeList: [],
  modlSubTypeList: [],
  datasetFormatList: [],
});

// 校验规则
const rules = reactive({
  dataset_name: [{ required: true, message: "数据集名称不能为空", trigger: "blur" }],
  dataset_version: [{ required: true, message: "数据集版本不能为空", trigger: "blur" }],
  modl_sub_type: [{ required: true, message: "适合模型类型不能为空", trigger: "change" }],
  dats_dataset_format: [
    { required: true, message: "数据集格式不能为空", trigger: "change" },
  ],
  dats_label_type: [{ required: true, message: "标注类型不能为空", trigger: "change" }],
  image_width: [{ required: true, message: "分辨率宽度不能为空", trigger: "blur" }],
  image_height: [{ required: true, message: "分辨率高度不能为空", trigger: "blur" }],
  dataset_desc: [{ required: false, message: "数据集描述不能为空", trigger: "blur" }],
  dataset_parameters: [
    { required: true, message: "数据集参数文件不能为空", trigger: "blur" },
  ],
});

/** 表单提交 */
const handleSubmit = useThrottleFn(() => {
  formRef.value.validate((valid) => {
    if (valid) {
      if (!form.value.image_width) {
        ElMessage.error("请输入图片分辨率宽度！");
        return false;
      }
      loading.value = true;
      DataSetApi.updateDataSet(form.value.dataset_id, form.value)
        .then((res) => {
          if (res.data.code == 0) {
            ElMessage.success("保存成功");
            closeBack();
          }
        })
        .finally(() => {
          loading.value = false;
        });
    }
  });
}, 3000);

/** 上传文件 */
function handleChangeFiles(uploadFile, uploadFiles) {
  //uploadFile.status = 'success';
  clearTimeout(autoTime.value);
  if (uploadFile.raw.type == "application/json" || uploadFile.raw.type == "text/plain") {
    uploadJsonList.value.push(uploadFile);
  }
  autoTime.value = setTimeout(doEquipmentFiles, 280);
}

/** 上传文件>回调 */
const doEquipmentFiles = () => {
  uploadImgFileList.value = uploadImgFileList.value.filter(
    (it) => it.raw.type != "application/json" && it.raw.type != "text/plain"
  );
  if (form.value.dats_label_type != "no_label") {
    var element = document.getElementsByClassName("upload-demo-3")[0];
    var children = element.querySelectorAll(".el-upload-list__item");
    children.forEach((item) => {
      var mylabel = item.querySelectorAll(".mylabel");
      //console.log("mylabel.length==>" + mylabel.length);
      if (mylabel.length > 0) {
        mylabel.forEach((lab) => {
          lab.remove();
        });
      }
      let name = item.querySelector(".el-upload-list__item-file-name").textContent;
      let disp = uploadJsonList.value.filter((it) => disName(name, it.name));
      //console.log("disp==>" + disp.length);
      if (disp.length > 0) {
        item.insertAdjacentHTML(
          "beforeend",
          "<span class='el-tag el-tag--success el-tag--dark mylabel mylabel--success'><span class='el-tag__content'>已标注</span></span>"
        );
      } else {
        item.insertAdjacentHTML(
          "beforeend",
          "<span class='el-tag el-tag--danger el-tag--dark mylabel mylabel--error'><span class='el-tag__content'>未标注</span></span>"
        );
      }
    });
  }
};

/** 标注文件名称比对 */
function disName(img, json) {
  if (
    img.substring(0, img.lastIndexOf(".")) == json.substring(0, json.lastIndexOf("."))
  ) {
    return true;
  } else {
    return false;
  }
}

/** 删除图片的json标注 */
function handleRemoveFiles(uploadFile, uploadFiles) {
  uploadJsonList.value = uploadJsonList.value.filter(
    (it) => !disName(uploadFile.name, it.name)
  );
  return true;
}

/** 开始上传文件 */
function checkUploadFiles() {
  var element = document.getElementsByClassName("upload-demo-3")[0];
  var errors = element.querySelectorAll(".mylabel--error");
  if (errors.length > 0) {
    ElMessageBox.confirm(errors.length + " 个图片未上传标注文件！是否继续上传已标注数据集信息?", "警告", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    }).then(function () {
      startUploadFiles();
    });
  }else{
    startUploadFiles();
  }
}

/** 开始上传文件 */
function startUploadFiles() {
  uploadImgFileList.value.forEach((item) => {
    let json = uploadJsonList.value.filter((it) => disName(item.name, it.name));
    if(form.value.dats_label_type != "no_label" && json.length==0){
      return;
    }
    const formData = new FormData();
    formData.append("image_file_name", item.name);
    formData.append("image_file", item.raw);
    formData.append("label_file", json.length > 0 ? json[0].raw : null);
    uploadLoading.value = true;
    DataSetApi.rawUpload(form.value.dataset_id, formData)
      .then((res) => {
        if (res.data.code == 0) {
          uploadImgFileList.value = uploadImgFileList.value.filter(
            (it) => item.name != it.name
          );
          uploadJsonList.value = uploadJsonList.value.filter(
            (it) => !disName(item.name, it.name)
          );
          if (uploadImgFileList.value.length == 0) {
            handleQuery();
            dialogVisible.value = false;
          }
        }
      })
      .finally(() => {
        uploadLoading.value = false;
      });
  });
}

/** 删除文件 */
function beforeRemove(file) {
  remImageList.value.push(file.name);
  let remList = [];
  remList.push(file.name);
  return ElMessageBox.confirm("确认删除数据集图片?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(
    async () => {
      let res = await DataSetApi.deleteFile(ID.value, { file_name_list: remList });
      if (res.data.code == 0) {
        imgCount.value = imageList.value.length - 1;
        ElMessage.success("删除成功");
      }
      return true;
    },
    () => false
  );
}

/** 删除文件-清空所有 */
function handleRemoveAll() {
  ElMessageBox.confirm("确认删除全部数据集图片?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(function () {
    let list = [];
    imageList.value.forEach(item => {
      list.push(item.name);
    });
    DataSetApi.deleteFile(ID.value, { file_name_list: list }).then((res) => {
      if (res.data.code == 0) {
        imageList.value = [];
        imgCount.value = imageList.value.length;
        ElMessage.success("删除成功");
      }
    });
  });
}

/** 打开文件上传弹窗 */
function handleImageDialog() {
  dialogVisible.value = true;
}

// 文件上传
function handleFileChange(file) {
  //先创建一个读文件的对象 FileReader
  let reader = new FileReader();
  //判断浏览器是否支持 FileReader
  if (typeof FileReader === "undefined") {
    this.$message({
      type: "info",
      message: "您的浏览器不支持文件读取。",
    });
    return;
  }
  uploadFile(file).then((res) => {
    if (isJSON(res)) {
      form.value.dataset_parameters = JSON.parse(res);
      formRef.value.validateField("dataset_parameters");
      codeHtml.value = res;
      jsonData.data = res;
      fileStatus.value = true;
    }
  });
}

/** 解析json */
function isJSON(str) {
  try {
    // 尝试解析输入的字符串
    JSON.parse(str);
    ElMessage.success("JSON文件解析成功");
    return true;
    // 成功解析
  } catch (error) {
    // 解析失败
    ElMessage.error("JSON文件解析失败");
    uploadRef.value.clearFiles();
    fileStatus.value = false;
    form.value.dataset_parameters = "";
    return false;
  }
}

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

// 文件删除
function handleFileRemove() {
  form.value.dataset_parameters = "";
  codeHtml.value = "";
  jsonData.data = {};
  fileStatus.value = false;
}

// 超出限制，清空文件列表
function handleFileExceed() {
  uploadRef.value.clearFiles();
  ElMessage.warning("已清空文件列表,请重新上传！");
  handleFileRemove();
}

/** 返回默认页面 */
function closeBack() {
  router.push({ path: "/dataMgr/datas" });
}

/** 预览图片 */
function handlePreview(file) {
  imgPreSrcList.value = [];
  DataSetApi.downloadFile(ID.value,file.name).then(res =>{
    console.log(res)
    if(res.data.code==0){
      imgPreSrc.value = "data:image/gif;base64," + res.data.data.file_content;
      imgPreSrcList.value.push(imgPreSrc.value);
      setTimeout(() => {
        console.log("点击事件===>");
        imgViewer.value = true;
        document.getElementsByClassName("imgPreView")[0].children[0].click();
      }, 50);
    }
  });
}

// 初始化选项列表
const initData = () => {
  let id = route.query.id;
  ID.value = id;
  DataSetApi.dataSetInfo(id).then((res) => {
    if (res.data.code == 0) {
      let resolution = res.data.data.image_resolution.split("x");
      res.data.data.image_width = resolution[0];
      res.data.data.image_height = resolution[1];
      form.value = res.data.data;
      codeHtml.value = JSON.stringify(res.data.data.dataset_parameters);
      jsonData.data = res.data.data.dataset_parameters;
      if (codeHtml.value == "{}") {
        fileStatus.value = false;
      } else {
        fileStatus.value = true;
      }
    }
  });
  handleQuery();
  ConstApi.modlSubType().then((res) => {
    if (res.data.code == 0) {
      listOpt.modlSubTypeList = res.data.data.modl_sub_type_list || [];
    }
  });
  ConstApi.datasetFormatType().then((res) => {
    if (res.data.code == 0) {
      listOpt.datasetFormatList = res.data.data.dats_dataset_format_list || [];
    }
  });
  ConstApi.datsLabelType().then((res) => {
    if (res.data.code == 0) {
      listOpt.labelTypeList = res.data.data.dats_label_type_list || [];
    }
  });
};

// 初始化选项列表
const handleQuery = () => {
  DataSetApi.rawFiles(ID.value).then((res) => {
    if (res.data.code == 0) {
      if (res.data.data.file_name_list) {
        let list = [];
        res.data.data.file_name_list.forEach((item) => {
          list.push({ name: item, url: item });
        });
        imageList.value = list;
        imgCount.value = imageList.value.length;
      }
    }
  });
};

onMounted(() => {
  initData();
});
</script>
<style scoped lang="scss">
.model-detail {
  :deep(.el-card__header) {
    padding: 8px 4px;
    display: flex;
    align-items: center;
  }
}

.sp-file {
  color: #29d;
}

.tb-base-info {
  line-height: 30px;
}

:deep(.svg-icon) {
  margin-right: 8px;
}

.card-footer {
  position: fixed;
  width: calc(100% - 215px);
  bottom: 0px;

  :deep(.el-card__body) {
    padding: 10px;

    .el-pagination {
      justify-content: end;
    }
  }
}

.font-center {
  text-align: center;
  color: #cccccc;
}
</style>
<style scope>
.el-dialog__body {
  overflow: auto;
}

.el-card__body {
  overflow: auto;
}

.upload-demo-2>.el-upload {
  display: none !important;
}

.upload-demo-2>.el-upload-list {
  margin: 0 !important;
}

.upload-demo-2>*>.el-upload-list__item {
  float: left !important;
  width: 25% !important;
}

.upload-demo-3>*>.el-upload-list__item {
  float: left !important;
  width: 49% !important;
}

.upload-demo-3>*>.el-upload-list__item:nth-child(even) {
  margin-left: 10px;
}

.el-dialog__body{
  max-height: 520px;
}

.dialog-footer {
  text-align: center;
}

.mylabel {
  position: absolute;
  right: 10px;
  bottom: 10px;
}
</style>
