<template>
  <div class="wh100">
    <a-upload
      name="file"
      :multiple="itemMultipleChoiceFlag"
      v-model:file-list="fileList"
      :default-file-list="fileList"
      :maxCount="itemMultipleChoiceFlag ? 10000000 : 1"
      :disabled="props.readonly || props.disabled"
      :action="fileUploadUrl"
      list-type="picture-card"
      :headers="headers"
      :before-upload="beforeUpload"
      accept=".jpeg,.jpg,.png,.tif,.jfif,.webp,.pjp,.apng,.pjpeg,.avif,.ico,.tiff,.bmp,.xbm,.jxl,.jpeg,.svgz,.gif,.svg"
      @preview="handlePreviewPhoto"
      @download="downloadPhoto"
      @change="handleFileChange"
      @remove="remove"
      :showUploadList="{
        showDownloadIcon: true
      }"
    >
      <plus-outlined
        style="font-size: 28px; font-weight: 200"
        v-if="itemMultipleChoiceFlag ? !(props.readonly || props.disabled) : fileList.length == 0"
      />
    </a-upload>

    <!-- 图标预览弹框 -->
    <a-modal :visible="previewVisible" :footer="null" @cancel="previewVisible = false">
      <img alt="example" style="width: 100%" :src="previewImage" />
    </a-modal>
  </div>
</template>

<script setup name="UploadPicComponent">
import { ref, onMounted, watch, computed } from 'vue';
import { message, Upload } from 'ant-design-vue';
import { getToken } from '@/utils/token-util';
import { API_BASE_PREFIX } from '@/config/setting';
import { FileApi, FileUploadUrl as fileUploadUrlPrefix } from '@/views/system/backend/file/api/FileApi';
import { deepClone } from '@/utils/common/util';

const props = defineProps({
  value: {
    type: String,
    default: ''
  },
  //是否禁用
  disabled: {
    type: Boolean,
    default: false
  },
  record: {
    type: Object,
    default: {}
  },
  // 是否只读
  readonly: {
    type: Boolean,
    default: false
  },
  multiple: {
    type: Boolean,
    default: false
  },
  // 是否正常保存，不是转json格式
  normal: {
    type: Boolean,
    default: false
  }
});

const emits = defineEmits(['update:value', 'onChange']);

// fileList
const fileList = ref([]);

// 上传文件的url
const fileUploadUrl = ref(`${API_BASE_PREFIX}${fileUploadUrlPrefix}?secretFlag=N`);
// 上传文件时候要带header
const headers = ref({
  Authorization: getToken()
});

// 选中的值
const dataValue = ref(null);

// 是否展示图片预览
const previewVisible = ref(false);
// 图片地址
const previewImage = ref(null);
// 是否自己改变值
const isOwnChange = ref(false);

// 是否多选
const itemMultipleChoiceFlag = computed(() => {
  if (props.record?.itemMultipleChoiceFlag || props.multiple) {
    return true;
  }
  return false;
});

onMounted(() => {
  setDataValue();
  getFileList();
});

// 设置选中的值
const setDataValue = () => {
  if (props.value) {
    if (itemMultipleChoiceFlag.value) {
      dataValue.value = props.normal ? props.value : JSON.parse(props.value);
    } else {
      dataValue.value = [props.value];
    }
  } else {
    dataValue.value = [];
  }
};

// 获取文件详情列表
const getFileList = () => {
  if (isOwnChange.value) return;
  if (dataValue.value?.length == 0) return;
  FileApi.getAntdVInfoBatch({ fileIdList: dataValue.value }).then(res => {
    res.data.forEach((item, index) => {
      item.fileId = dataValue.value[index];
    });
    fileList.value = deepClone(res.data);
  });
  isOwnChange.value = false;
};

//上传之前的回调
const beforeUpload = file => {
  const isJpgOrPng =
    file.type === 'image/jpeg' ||
    file.type === 'image/jpg' ||
    file.type === 'image/png' ||
    file.type === 'image/tif' ||
    file.type === 'image/jfif' ||
    file.type === 'image/webp' ||
    file.type === 'image/pjp' ||
    file.type === 'image/apng' ||
    file.type === 'image/pjpeg' ||
    file.type === 'image/avif' ||
    file.type === 'image/ico' ||
    file.type === 'image/tiff' ||
    file.type === 'image/bmp' ||
    file.type === 'image/xbm' ||
    file.type === 'image/jxl' ||
    file.type === 'image/svgz' ||
    file.type === 'image/gif' ||
    file.type === 'image/svg';
  if (!isJpgOrPng) {
    message.error('只能上传图片!');
    return Upload.LIST_IGNORE; //阻止列表展现
  }
  const isLt5M = file.size / 1024 / 1024 < 5;
  if (!isLt5M) {
    message.error('图片大小不能超过5MB!');
  }
  return isJpgOrPng && isLt5M;
};

// 点击预览图片
const handlePreviewPhoto = async file => {
  previewImage.value = file.url || file.preview || file.thumbUrl;
  previewVisible.value = true;
};

/**
 * 上传文件改变时的状态
 *
 * @param info 组件回调原有参数
 * @param fieldCode 文件表单字段名称
 * @author fengshuonan
 * @date 2021/12/29 14:25:18
 */
const handleFileChange = info => {
  if (info.file.status === 'done') {
    info.file.fileId = info.file.response.data.fileId;
    isOwnChange.value = true;
    // 设置临时fileList的值
    if (itemMultipleChoiceFlag.value) {
      dataValue.value.push(info.file.response.data.fileId);
    } else {
      dataValue.value = [info.file.response.data.fileId];
    }
    dataValueChange();
    // 将文件属性名和文件编码存入数组中
    message.success(`${info.file.name} 图片上传成功`);
  } else if (info.file.status === 'error') {
    message.error(`${info.file.name} 图片上传失败`);
  }
};

//下载图片
const downloadPhoto = file => {
  FileApi.download({ token: getToken(), fileId: file.fileId });
};

// 更改值
const dataValueChange = () => {
  let data;
  if (itemMultipleChoiceFlag.value) {
    data = props.normal ? dataValue.value : JSON.stringify(dataValue.value);
  } else {
    data = dataValue.value[0] ?? '';
  }
  emits('update:value', data);
  emits('onChange', props.record);
};

// 删除文件
const remove = file => {
  let fileId = file.fileId;
  if (fileId) {
    // 查找需要删除的文件所在文件数组中的索引
    let findIndex = fileList.value.findIndex(item => item.fileId === fileId);
    if (findIndex !== -1) {
      fileList.value.splice(findIndex, 1);
      dataValue.value.splice(findIndex, 1);
      isOwnChange.value = true;
      dataValueChange();
    }
  }
};

watch(
  () => props.value,
  val => {
    setDataValue();
    getFileList();
  },
  { deep: true }
);
</script>

<style scoped lang="less">
.wh100 {
  width: 100%;
  height: 100%;
}
</style>
