<template>
  <div class="header">
    <a-upload
      accept="image/*"
      multiple
      :beforeUpload="beforeUpload"
      :showUploadList="false"
      name="file"
    >
      <a-button
        v-if="butText"
        @click="addImage"
        :disabled="props.disabled"
        type="primary"
        size="samll"
        class="mr-10"
        >{{ butText }}</a-button
      >
    </a-upload>
    <div style="width: 300px" v-if="list.length">
      <a-slider
        :max="300"
        :min="60"
        id="test"
        v-model:value="baseSize"
        @change="changeZoom"
      />
    </div>
  </div>
  <div
    class="picture-wall-box"
    :style="{
      gridTemplateColumns: `repeat(auto-fill, ${baseSize}px)`,
    }"
  >
    <a-image-preview-group>
      <div
        class="picture-wall-item"
        v-for="(item, index) in list"
        :key="item.attachmentid"
        :style="{
          width: baseSize + 'px',
          height: baseSize + 'px',
        }"
        :draggable="!props.disabled && pic"
        @dragstart="dragStart(index)"
        @dragover="dragOver(index)"
        @dragend="dragEnd"
      >
        <div v-if="item.uid">
          <a-progress
            type="circle"
            :percent="item.progress"
            :status="item.exception"
            :size="[baseSize - 40, baseSize - 40]"
          />
        </div>
        <a-popover
          v-else
          :open="false && hovered == index"
          @openChange="handleHoverChange($event, index)"
        >
          <template #content>
            <a-image
              :src="item.cover"
              width="200px"
              :previewMask="false"
              fallback="data:image/png;base64,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"
            >
              <template #placeholder>
                <a-image :src="item.cover" :width="200" :preview="false" />
              </template>
            </a-image>
          </template>
          <div>
            <a-image
              :src="item.cover"
              :preview="{
                src: item.url,
              }"
              :style="{
                width: baseSize - (baseSize &gt; 100 ? 30 : 15) + 'px',
                height: baseSize - (baseSize &gt; 100 ? 30 : 15) + 'px',
                objectFit: 'cover',
                fontSize: 0,
              }"
              fallback="data:image/png;base64,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"
            >
              <template #previewMask>
                <a-popconfirm
                  v-if="!props.disabled"
                  :open="linksid == item.linksid"
                  title="确定删除当前资源吗?"
                  @confirm="confirmDeleteImage"
                  @cancel="linksid = null"
                >
                  <DeleteOutlined
                    v-if="isDeletable"
                    class="previewMaskIcon"
                    :style="{ fontSize: (baseSize &gt; 200 ? '24px' : '20px') }"
                    @click.stop="linksid = item.linksid"
                  />
                </a-popconfirm>
              </template>
            </a-image>
          </div>
        </a-popover>
      </div>
    </a-image-preview-group>
  </div>
  <div class="empty" v-if="!list.length">
    <a-empty :image="simpleImage" />
  </div>
</template>

<script setup>
import { ref, reactive, defineProps, watch } from "vue";
import Api from "@/api/api";
import Up from "@/api/upload";
import utils from "@/utils/utils";
import { ExpandOutlined, DeleteOutlined } from "@ant-design/icons-vue";

import { Empty } from "ant-design-vue";
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;

const props = defineProps({
  butText: {
    type: String,
    default: "添加图片",
  },
  disabled: {
    type: Boolean,
    default: true,
  },
  attinfos: {
    type: Array,
  },
  coverType: {
    //列表显示的类型
    type: String,
    default: "thumbnail",
  },
  pic: {
    //pic支持排序
    type: Boolean,
    default: false,
  },
  startSequence: {
    //设置排序的起量，比如说第二页每页20条数据 起量为21
    type: [String, Number],
    default: 0,
  },
  total: {
    //考虑分页情况传递,上传图片顺序会在此向后顺延
    type: [Number, String],
    default: 0,
  },
  ownertable: {
    type: String,
  },
  ownerid: {
    type: [String, Number],
  },
  isDeletable: {
    type: Boolean,
    default: true,
  },
});

let baseSize = ref("140"),
  zoom = ref("50"),
  list = ref([]);

const appfolderid = ref("");
Api.requested({
  classname: "webmanage.site.site",
  method: "querySite_Parameter",
  content: {},
}).then((res) => {
  appfolderid.value = res.data.appfolderid;
});

function beforeUpload(file) {
  file.document = file.name;
  const filetype = file.document.substr(file.document.lastIndexOf(".") + 1);
  file.sequence = list.value.length;
  file.progress = 0;
  file.linksid = -1;
  file.attachmentid = Date.now();
  list.value.push(reactive({ ...file }));
  Api.requested({
    classname: "system.attachment.huawei.OBS",
    method: "getFileName",
    content: {
      filename: file.name,
      filetype,
      parentid: appfolderid.value, //归属文件夹ID
    },
  }).then((res) => {
    if (res.code != 1)
      return (list.value[file.sequence].exception = "exception");
    console.log("获取上传链接", res);
    const { uploadurl, serialfilename } = res.data;
    Up.upload(uploadurl, file, {
      headers: {
        "Content-Type": "application/octet-stream",
      },
      onUploadProgress: function (e) {
        list.value[file.sequence].progress = parseInt(e.progress * 100);
        console.log(list.value[file.sequence]);
      },
    }).then((upload) => {
      console.log("上传结果", upload);
      if (upload.status != 200)
        return (list.value[file.sequence].exception = "exception");
      Api.requested({
        classname: "system.attachment.huawei.OBS",
        method: "uploadSuccess",
        content: {
          serialfilename,
          ownerid: props.ownerid,
          ownertable: props.ownertable,
          usetype: "file",
        },
      }).then((feedback) => {
        console.log("feedback", feedback);
        if (feedback.code != 1)
          return (list.value[file.sequence].exception = "exception");
        const attachmentid = feedback.data.attachmentids[0];
        Api.requested({
          id: 20240407135802,
          content: {
            ownerid: props.ownerid,
            ownertable: props.ownertable,
            attachmentid,
            sequence: file.sequence,
          },
        }).then((binding) => {
          console.log(binding, "binding");
          if (binding.code != 1)
            return (list.value[file.sequence].exception = "exception");
          Api.requested({
            id: "20240407140002",
            content: {
              ownerid: props.ownerid,
              ownertable: props.ownertable,
              pageNumber: 1,
              pageSize: 100,
              where: {
                // condition: serialfilename,
              },
            },
          }).then((getList) => {
            if (getList.code != 1)
              return (list.value[file.sequence].exception = "exception");
            list.value[file.sequence] = getList.data
              .filter((v) => v.attachmentid == attachmentid)
              .map((v) => {
                v = Object.assign(v, v.attinfos[0]);
                delete v.attinfos;
                v.cover = props.coverType
                  ? v.subfiles.find((s) => s.type == props.coverType).url ||
                    v.url
                  : v.url;
                return v;
              })[0];
          });
        });
      });
    });
  });
}
/* 初始化列表 */
watch(
  () => props.attinfos,
  (newVal) => {
    init(newVal);
  },
  () => showStyle,
  (newVal) => {
    console.log("showStyle", newVal);
  }
);
function init(attinfos, pic = props.pic) {
  if(!attinfos.length) return;
  list.value = pic ? attinfos : attinfos.filter((v) => v.fileType == "image");
  list.value = list.value.map((v) => {
    if (pic) {
      v = Object.assign(v, v.attinfos[0]);
      delete v.attinfos;
    }
    v.cover = props.coverType
      ? v.subfiles.find((s) => s.type == props.coverType).url || v.url
      : v.url;
    return v;
  });
  if (
    pic &&
    list.value[list.value.length - 1].sequence !=
      props.startSequence + list.value.length
  ) {
    setSequenceAll();
  }
}
function addImage() {
  console.log("添加图片");
}

let linksid = ref(null);
async function confirmDeleteImage() {
  await handleDeleteImage([linksid.value]);
  linksid.value = null;
}
/* 处理删除图片 */
function handleDeleteImage(linksids = [], setSequence = true) {
  return new Promise((resolve, reject) => {
    if (linksids.length) {
      Api.requested({
        id: "20240407135902",
        content: { linksids },
      }).then((res) => {
        console.log("删除图片", res);
        utils.message(res, "操作成功", async () => {
          list.value = list.value.filter((v) => !linksids.includes(v.linksid));
          //如果考虑分页情况再这个节点去重新获取数据 setSequence=false
          if (setSequence) await setSequenceAll();
        });
        resolve(res.code == 1);
      });
    } else {
      resolve();
    }
  });
}

/* 拖拽与显示气泡 */
let startIndex = null,
  targetIndex = null,
  hovered = ref(null),
  prohibitHovered = false;

function dragStart(index) {
  startIndex = index;
  targetIndex = index;
  prohibitHovered = true;
  hovered.value = null;
}

function dragOver(index) {
  if (targetIndex == index) return;
  let item = list.value.splice(targetIndex, 1);
  list.value.splice(index, 0, item[0]);
  targetIndex = index;
}

function dragEnd() {
  prohibitHovered = false;
  if (startIndex != targetIndex) setSequenceAll();
}

function setSequenceAll() {
  return new Promise((resolve, reject) => {
    Api.requested({
      id: "20221201134901",
      content: {
        ownertable: "sys_attachment_links",
        sequencesorts: list.value.map((v, i) => {
          return {
            ownerid: v.linksid,
            sequence: Number(props.startSequence) + i,
          };
        }),
      },
    }).then((res) => {
      console.log("设置排序", res);
      resolve(res.code == 1);
    });
  });
}

function handleHoverChange(visible, index) {
  if (prohibitHovered) return (hovered.value = null);
  hovered.value = visible ? index : null;
}
</script>

<style scoped>
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

.picture-wall-box {
  display: grid;
  justify-content: space-between;
  grid-gap: 10px;
  margin-top: 20px;
  user-select: none;
}

.picture-wall-box .picture-wall-item {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid #d9d9d9;
  border-radius: 8px;
  box-sizing: border-box;
}

.previewMaskIcon {
  opacity: 0.6;
}

.previewMaskIcon:hover {
  opacity: 1;
}

.empty {
  width: 100%;
  padding: 50px 0;
  display: flex;
  justify-content: center;
}
</style>