<template>
  <el-dialog
    :visible.sync="visible"
    width="80%"
    :before-close="handleClose"
    top="2vh"
    lock-scroll
    v-loading="submitLoading"
    element-loading-background="rgba(0, 0, 0, 0.5)"
    :element-loading-text="loadingText"
  >
    <div class="title" slot="title">
      <div class="divider"></div>
      <div class="label">{{ title }}</div>
    </div>
    <div class="el-dialog-div">
      <div class="dialog-content">
        <el-form
          size="mini"
          :model="dialogForm"
          class="basic-info"
          :rules="rules"
          ref="form"
          status-icon
        >
          <el-row :gutter="50">
            <el-col :span="12">
              <el-form-item
                label="文物名称"
                :label-width="formLabelWidth"
                prop="name"
              >
                <el-input
                  v-model="dialogForm.name"
                  autocomplete="off"
                  placeholder="请输入文物名称"
                ></el-input>
              </el-form-item>
              <el-form-item
                label="馆藏单位"
                :label-width="formLabelWidth"
                prop="deptId"
              >
                <el-cascader
                  style="width: 100%"
                  v-model="dialogForm.deptId"
                  :options="orgTreeData"
                  :props="optionProps"
                  placeholder="请选择馆藏单位"
                  clearable
                >
                </el-cascader>
              </el-form-item>
              <el-form-item label="文物类别" :label-width="formLabelWidth">
                <el-select
                  v-model="dialogForm.type"
                  placeholder="请选择文物类别"
                  style="width: 100%"
                  filterable
                >
                  <el-option
                    v-for="(value, key) in dicts.culturalRelicType"
                    :key="key"
                    :label="value"
                    :value="key"
                  >
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item label="文物质地" :label-width="formLabelWidth">
                <el-cascader
                  style="width: 100%"
                  v-model="dialogForm.textureType"
                  :options="culturalRelicTextureType"
                  :props="props"
                  placeholder="请选择文物质地"
                  filterable
                >
                </el-cascader>
              </el-form-item>
              <el-form-item label="文物年代" :label-width="formLabelWidth">
                <el-cascader
                  style="width: 100%"
                  v-model="dialogForm.years"
                  :options="culturalRelicYears"
                  :props="props"
                  placeholder="请选择文物年代"
                  filterable
                >
                </el-cascader>
              </el-form-item>
              <el-form-item label="文物级别" :label-width="formLabelWidth">
                <el-select
                  v-model="dialogForm.level"
                  placeholder="请选择文物级别"
                  style="width: 100%"
                  filterable
                >
                  <el-option
                    v-for="(value, key) in dicts.culturalRelicLevel"
                    :key="key"
                    :label="value"
                    :value="key"
                  >
                  </el-option>
                </el-select>
              </el-form-item>

              <el-form-item label="具体尺寸" :label-width="formLabelWidth">
                <el-input
                  v-model="dialogForm.detailSize"
                  autocomplete="off"
                  placeholder="请输入具体尺寸"
                ></el-input>
              </el-form-item>

              <el-form-item label="文物数量" :label-width="formLabelWidth">
                <el-input-number
                  v-model="dialogForm.num"
                  :min="1"
                  :max="1000"
                  label="请输入文物数量"
                ></el-input-number>
              </el-form-item>

              <el-form-item label="关联文献" :label-width="formLabelWidth">
                <el-select
                  v-model="literatureIdArr"
                  multiple
                  filterable
                  remote
                  reserve-keyword
                  placeholder="请输入关键词搜索文献"
                  :remote-method="searchLiterature"
                  :loading="loading"
                  style="width: 100%"
                >
                  <el-option
                    v-for="item in literatureList"
                    :key="item.literatureId"
                    :label="item.name"
                    :value="item.literatureId"
                  >
                  </el-option>
                </el-select>
              </el-form-item>

              <el-form-item label="来源方式" :label-width="formLabelWidth">
                <el-select
                  v-model="dialogForm.sourceWay"
                  placeholder="请选择来源方式"
                  style="width: 100%"
                  filterable
                >
                  <el-option
                    v-for="(value, key) in dicts.culturalRelicSourceWay"
                    :key="key"
                    :label="value"
                    :value="key"
                  >
                  </el-option>
                </el-select>
              </el-form-item>

              <el-form-item label="是否上架" :label-width="formLabelWidth">
                <el-switch v-model="dialogForm.status"> </el-switch>
              </el-form-item>

              <el-form-item label="主题词" :label-width="formLabelWidth">
                <el-input
                  v-model="dialogForm.themeWord"
                  autocomplete="off"
                  placeholder="请输入主题词"
                ></el-input>
              </el-form-item>

              <el-form-item label="3durl链接" :label-width="formLabelWidth">
                <el-input
                  v-model="dialogForm.url3d"
                  autocomplete="off"
                  placeholder="请输入3durl链接"
                ></el-input>
              </el-form-item>

              <el-form-item label="备注" :label-width="formLabelWidth">
                <el-input
                  type="textarea"
                  placeholder="请输入备注"
                  v-model="dialogForm.remark"
                  maxlength="100"
                  show-word-limit
                >
                </el-input>
              </el-form-item>
            </el-col>

            <el-col :span="12">
              <el-form-item
                label="馆藏介绍"
                :label-width="formLabelWidth"
                prop="intro"
              >
                <VueQuillEditor
                  v-model="dialogForm.intro"
                  placeholder="请输入馆藏介绍"
                />
              </el-form-item>
              <el-form-item label="文物封面" :label-width="formLabelWidth">
                <ManualUploader
                  :files="faceImage"
                  :fileLimit="1"
                  :fileSize="200"
                  listType="picture-card"
                  :fileType="['png', 'jpeg', 'jpg']"
                  ref="faceImage"
                  @getRemovedIds="getRemovedIds"
                />
              </el-form-item>
              <el-form-item label="文物图片" :label-width="formLabelWidth">
                <ManualUploader
                  :files="images"
                  :fileLimit="20"
                  :fileSize="200"
                  listType="picture-card"
                  :fileType="['png', 'jpeg', 'jpg']"
                  ref="images"
                  @getRemovedIds="getRemovedIds"
                />
              </el-form-item>

              <el-form-item label="文物视频" :label-width="formLabelWidth">
                <ManualUploader
                  :files="videos"
                  :fileLimit="6"
                  :fileSize="500"
                  :fileType="['mp4']"
                  listType="text"
                  ref="videos"
                  @getRemovedIds="getRemovedIds"
                />
              </el-form-item>

              <el-form-item label="3D模型" :label-width="formLabelWidth">
                <ManualUploader
                  :files="file3d"
                  :fileLimit="1"
                  :fileSize="500"
                  :fileType="['OBJ', 'STL', 'FBX', '3DS', 'GLB']"
                  listType="text"
                  ref="file3d"
                  @getRemovedIds="getRemovedIds"
                />
              </el-form-item>
              <el-form-item label="文物音频" :label-width="formLabelWidth">
                <ManualUploader
                  :files="audios"
                  :fileLimit="1"
                  :fileSize="50"
                  :fileType="['mp3']"
                  listType="text"
                  ref="audios"
                  @getRemovedIds="getRemovedIds"
                />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>

        <div class="dialog-footer">
          <el-button @click="handleClose" size="mini">取 消</el-button>
          <el-button
            size="mini"
            type="primary"
            @click="handleSubmit(0)"
            :disabled="loading"
            icon="el-icon-document-checked"
          >
            只保存
          </el-button>
          <el-button
            size="mini"
            type="primary"
            @click="handleSubmit(1)"
            icon="el-icon-circle-check"
            :disabled="loading"
            >保存并提交审核
          </el-button>
        </div>
      </div>
    </div>
  </el-dialog>
</template>

<script>
import { getLiteratureList } from "@/api/literature";
import { addOrUpdateCulturalRelic } from "@/api/culturalRelic";
import { mapGetters, mapActions } from "vuex";
import { uploadV1 } from "@/utils/file";
import { rules } from "../configs/validateRules";
import fileUploadFunctions from "@/utils/bizUploadFunctions";
import transformData from "@/utils/bizTransform";
const {
  faceImageToClient,
  literatureIdArrToStr,
  literatureListToIds,
  statusBoolToNum,
  statusStrToBool,
  getDeptIdArr,
  getDeptIdStr,
  file3dToClient,
} = transformData;
export default {
  name: "InfoEditDialog",
  props: {
    form: {
      type: Object,
      default: () => ({}),
    },
    // 流程id，重传时需要
    flowId: {
      type: String,
      default: "",
    },
  },
  computed: {
    ...mapGetters(["userInfo", "dicts"]),
    title() {
      if (!this.dialogForm) {
        return;
      }
      if (this.dialogForm.crId) {
        return "修改文物信息";
      } else {
        return "新增文物";
      }
    },
  },
  watch: {
    form: {
      handler(value) {
        if (!value) {
          return;
        }
        this.covertServerData(value);
      },
      immediate: true,
      deep: true,
    },
  },
  data() {
    return {
      visible: false,
      formLabelWidth: "100px",
      loading: false,
      submitLoading: false,
      loadingText: "",
      dialogForm: {},
      literatureList: [], //服务器获得的文献列表
      literatureIdArr: [], //文献ID集合，用于绑定数据
      faceImage: [],
      file3d: [],
      images: [],
      videos: [],
      audios: [],
      culturalRelicTextureType: [],
      culturalRelicYears: [],
      props: {
        value: "value",
        label: "label",
        children: "children",
        checkStrictly: true,
      },
      orgTreeData: [],
      optionProps: {
        value: "id",
        label: "name",
        children: "children",
        checkStrictly: true,
      },
      rules,
      mediaKeys: ["faceImage", "images", "videos", "audios", "file3d"], //表单中的媒体
      removedIds: [], //被删除掉的文件
    };
  },
  async created() {
    await this.getDictList([
      "culturalRelicLevel",
      "culturalRelicType",
      "culturalRelicSourceWay",
    ]);
    const res = await this.getDictTree([
      "culturalRelicTextureType",
      "culturalRelicYears",
    ]);
    this.culturalRelicTextureType = res.culturalRelicTextureType;
    this.culturalRelicYears = res.culturalRelicYears;
    this.orgTreeData = await this.getMuseumTreeData(false);
    this.searchLiterature();
  },
  methods: {
    ...mapActions("dict", ["getDictList", "getDictTree"]),
    ...mapActions("org", ["getMuseumTreeData"]),
    //回显服务器传来的数据
    covertServerData(serverData) {
      this.dialogForm = JSON.parse(JSON.stringify(serverData));
      const {
        faceImage,
        faceImageUrl,
        faceImagePressUrl,
        imagesVo,
        videosVo,
        audiosVo,
        status,
        literatureVo,
        deptId,
        file3d,
        file3dUrl,
        file3dName,
      } = this.dialogForm;
      this.dialogForm.status = statusStrToBool(status);
      this.faceImage = faceImageToClient(
        faceImage,
        faceImageUrl,
        faceImagePressUrl
      );
      this.file3d = file3dToClient(file3d, file3dUrl, file3dName);
      this.images = imagesVo || [];
      this.videos = videosVo || [];
      this.audios = audiosVo || [];
      this.literatureIdArr = literatureListToIds(literatureVo);
      this.dialogForm.deptId = getDeptIdArr(deptId, this.userInfo);
    },
    // 关联文献查询
    searchLiterature(queryString) {
      if (!queryString || !queryString.trim()) {
        this.literatureList = [];
        return;
      }
      this.loading = true;
      const params = {
        name: queryString,
        page: "1",
        limit: "100",
      };
      setTimeout(async () => {
        this.loading = false;
        const res = await getLiteratureList(params);
        if (res.code == 0) {
          this.literatureList = res.data.records;
        } else {
          this.literatureList = [];
          this.$message.error(res.msg);
        }
      }, 500);
    },

    /**
     * @param {Object} dialogForm 当前表单
     * @param {Object} mediaForm 媒体文件ID键值对
     * @returns {Object} submitForm 最终返回的需要提交到服务器的表单
     */
    getSubmitForm(dialogForm, mediaForm) {
      let submitForm = {};
      submitForm = Object.assign(dialogForm, mediaForm);
      return submitForm;
    },
    // 提交表单
    handleSubmit(submitFlag) {
      this.$refs.form.validate(async (valid, err) => {
        if (valid) {
          this.submitLoading = true;
          this.uploadMediaFiles(this.mediaKeys, this.dialogForm)
            .then(async (mediaForm) => {
              this.loadingText = "正在提交表单...";
              const form = this.getSubmitForm(this.dialogForm, mediaForm);
              const { status, years, textureType, deptId } = form;
              const { literatureIdArr } = this;
              form.status = statusBoolToNum(status);
              form.literature = literatureIdArrToStr(literatureIdArr);
              form.years = this.processYear(years);
              form.textureType = this.processTextureType(textureType);
              form.deptId = getDeptIdStr(deptId);
              form.submitFlag = submitFlag;
              if (this.flowId) {
                form.flowId = this.flowId;
              }
              const res = await addOrUpdateCulturalRelic(form);
              this.submitLoading = false;
              if (res.code == 0) {
                this.$message.success("提交成功！");
                const { handleDeleteFiles } = fileUploadFunctions;
                handleDeleteFiles(this.removedIds);
                this.visible = false;
                this.reset();
                this.$emit("refresh");
              }
            })
            .catch((err) => {
              console.log(err);
              this.submitLoading = false;
            });
        } else {
          console.warn(err);
        }
      });
    },
    // 处理年份
    processYear(years) {
      if (years && years instanceof Array) {
        return years[years.length - 1];
      } else if (years) {
        return years;
      } else {
        return "";
      }
    },
    // 处理材质
    processTextureType(textureType) {
      if (textureType && textureType instanceof Array) {
        return textureType[textureType.length - 1];
      } else if (textureType) {
        return textureType;
      } else {
        return "";
      }
    },

    /**
     * 上传对应的媒体文件,并返回一个promise
     * @param {array} dialogForm 当前需要提交的表单
     * @param {array} mediaKeys 媒体keys数组
     * @returns {object} 传入的媒体key对应的id字符串，多个以逗号隔开
     */
    async uploadMediaFiles(mediaKeys, dialogForm) {
      return new Promise(async (resolve, reject) => {
        const {
          getNeedUploadFormData,
          getNewIdsObj,
          getOldIdsObj,
          getMergedIdsObj,
          isFormDataHasData,
        } = fileUploadFunctions;
        const formData = getNeedUploadFormData(this, mediaKeys);
        try {
          // formData有长度时再进行上传
          if (isFormDataHasData(formData)) {
            this.loadingText = "正在上传文件...请耐心等待";
            let upLoadRes = await uploadV1(formData);
            if (upLoadRes.code == 0) {
              const newIdObj = getNewIdsObj(mediaKeys, upLoadRes);
              const { removedIds } = this;
              const options = {
                mediaKeys,
                dialogForm,
                removedIds,
              };
              const oldIdObj = getOldIdsObj(options, this);
              const mediaForm = getMergedIdsObj(oldIdObj, newIdObj, mediaKeys);
              resolve(mediaForm);
            } else {
              this.$message.error("文件上传失败：" + upLoadRes.msg);
              reject(upLoadRes.msg);
            }
          } else {
            // 没有任何媒体需要上传的，把已有的交给后面
            const { removedIds } = this;
            const options = {
              mediaKeys,
              dialogForm,
              removedIds,
            };
            const mediaForm = getOldIdsObj(options, this);
            resolve(mediaForm);
          }
        } catch (error) {
          reject(error);
        }
      });
    },

    handleClose(done) {
      this.$confirm("确认关闭？")
        .then((_) => {
          this.visible = false;
          this.reset();
          if (this.loading) {
            this.loading = false;
          }
          if (this.submitLoading) {
            this.submitLoading = false;
          }
          done();
        })
        .catch((_) => {});
    },
    // 清空编辑组件中的所有值
    reset() {
      //父组件将清空form绑定的值
      this.dialogForm = {};
      this.literatureIdArr = [];
      this.images = [];
      this.videos = [];
      this.audios = [];
      this.faceImage = [];
      this.removedIds = [];
      this.file3d = [];
      this.$refs.form?.resetFields();
    },

    refresh() {
      this.$emit("refresh");
    },

    getRemovedIds(removedIds) {
      this.removedIds = [...new Set([...this.removedIds, ...removedIds])];
      console.log("this.removedIds", this.removedIds);
    },
  },
};
</script>

<style lang="scss" scoped>
.title {
  display: flex;
  margin-bottom: 16px;
  .divider {
    width: 8px;
    border-left: 4px solid #409eff;
    margin-right: 8px;
  }
  .label {
    font-weight: bold;
  }
}

.el-dialog-div {
  height: 80vh;
  overflow-x: hidden;
}

.dialog-content {
  padding: 0 32px;
  display: flex;
  .basic-info {
    flex: 1;
    margin-right: 48px;
  }
  .relate {
    flex: 1;
  }
}
.dialog-footer {
  display: flex;
  align-items: flex-end;
  margin: 20px 0;
}
</style>
@/utils/bizTransform@/utils/bizUploadFunctions
