

<template>
  <div style="display: flex; gap: 15px; flex-wrap: wrap; width: 100%;justify-content: center">
    <!-- 已上传图片列表 -->
    <div class="skus-imgs"
         v-for="(item, i) in imgList"
         :key="i"
         :class="{ loading: isImgLoading[i] }"
         :style="imgStyle"
         @click.stop>
      <img class="coverImage"
           :src="item"
           :alt="`图片${i+1}`"
           @click="handlePictureCardPreview(item)"
           @load="isImgLoading[i] = false"
           @error="handleImgError(i)"
      />

      <div class="skus-imgs-del" @click.stop="handleDeleteImg(i)" :style="delStyle">
        <el-icon color="#fd4574" :size="iconSize"><Delete /></el-icon>
      </div>

      <!-- 上传按钮 -->
      <el-upload
          :action="actionUrl"
          :headers="{ Authorization }"
          :show-file-list="false"
          :on-success="handleSkuImgsSuccess"
          :on-progress="handleUploadProgress"
          :on-error="handleUploadError"
          :disabled="isUploading"
          :multiple="isMultiple"
          v-if="!isMultiple && !isPreview"
      >
        <div class="avatar-uploader-insert" :class="{ uploading: isUploading }"
             :style="{...uploadStyle, zIndex: isPreview ? -1 : 3}"
        >
          <template v-if="isUploading">
            <!-- 上传中显示加载图标 -->
            <el-icon :size="iconSize" color="#67c23a"><Loading /></el-icon>
          </template>
          <template v-else>
            <el-icon :size="iconSize" color="#909399"><Plus /></el-icon>
          </template>
        </div>
      </el-upload>
    </div>

    <!-- 上传按钮 -->
    <el-upload
        :action="actionUrl"
        :headers="{ Authorization }"
        :show-file-list="false"
        :on-success="handleSkuImgsSuccess"
        :on-progress="handleUploadProgress"
        :on-error="handleUploadError"
        :disabled="isUploading"
        :multiple="isMultiple"
        v-if="!(imgList.length === 1 && !isMultiple)"
    >
      <div class="avatar-uploader" :class="{ uploading: isUploading }"
           :style="uploadStyle"
      >
        <template v-if="isUploading">
          <!-- 上传中显示加载图标 -->
          <el-icon :size="iconSize" color="#67c23a"><Loading /></el-icon>
        </template>
        <template v-else>
          <el-icon :size="iconSize" color="#909399"><Plus /></el-icon>
        </template>
      </div>
    </el-upload>
  </div>

  <el-dialog v-model="dialogVisible" width="600px">
    <img :src="dialogImageUrl" style="width: 100%" />
  </el-dialog>
</template>

<script setup>
import {Delete, Loading, Plus} from "@element-plus/icons-vue";
import {ref} from "vue";
import {ElMessage} from "element-plus";
import {useI18n} from "vue-i18n";

const props = defineProps({
  // 是否可以上传多张
  isMultiple: {
    type: Boolean,
    default: false
  },
  // 默认图片列表
  defaultImgList: {
    type: Array,
    default: () => []
  },
  // 默认图片url
  defaultImgUrl: {
    type: String,
    default: ""
  },
  // 最多上传多少张
  limit: {
    type: Number,
    default: 20
  },
  imgStyle: {
    type: Object,
    default: () => ({})
  },
  uploadStyle: {
    type: Object,
    default: () => ({})
  },
  delStyle: {
    type: Object,
    default: () => ({})
  },
  iconSize: {
    type: Number,
    default: 27
  },
  isPreview: {
    type: Boolean,
    default: false
  }
})

const emits = defineEmits(["change"]);

const { t } = useI18n()

const dialogImageUrl = ref('')
const dialogVisible = ref(false)

const actionUrl = ref(`${window.global.baseURL}/upload/image`)
const Authorization = localStorage.getItem('token')

const isImgLoading = ref([])
const isUploading = ref(false)

const imgList = ref([])
const imgUrl = ref('')

watch(() => props.defaultImgList, () => {
  imgList.value = props.defaultImgList
}, { immediate: true });

watch(() => props.defaultImgUrl, () => {
  imgUrl.value = props.defaultImgUrl
  imgList.value = []
  if(imgUrl.value){
    imgList.value.push(imgUrl.value)
  }
}, { immediate: true });


function handleImgError(index) {
  isImgLoading.value[index] = false
}
// 处理上传进度
function handleUploadProgress() {
  isUploading.value = true;
}
// 处理上传成功
function handleSkuImgsSuccess(res) {
  isUploading.value = false;
  if(res.code === -1) {
    ElMessage.error(res.msg)
  } else {
    if(imgList.value.length === props.limit) {
      ElMessage.warning(t(`最多可上传`) + props.limit + t('张图片'))
    } else {
      imgList.value.push(res.data.url)

      if(props.isMultiple) {
        emits('change', imgList.value, res.data.url)
      } else {
        emits('change', res.data.url)
      }
    }
  }

  // 添加新图片时初始化加载状态
  isImgLoading.value.push(true);
}
// 处理上传失败
function handleUploadError() {
  isUploading.value = false;
}
// 处理图片删除
function handleDeleteImg(index) {
  imgList.value.splice(index, 1);
  isImgLoading.value.splice(index, 1);
}

// 清空所有图片
function handleDeleteAllImg() {
  imgList.value = []
}

const handlePictureCardPreview = (url) => {
  dialogImageUrl.value = url
  dialogVisible.value = true
}

defineExpose({
  imgList,
  imgUrl,
  handleDeleteAllImg,
  handleDeleteImg
})
</script>

<style scoped lang="scss">
.upload-container {
  margin-bottom: 16px;
  margin-left: 16px;
}

.upload-area {
  width: 100%;
  min-height: 120px;
  //border: 2px dashed #ccc;
  border-radius: 6px;
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
}

.upload-area:hover {
  border-color: #f2ba45;
}

.upload-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 15px;
  cursor: pointer;
  box-sizing: border-box;
}

.upload-icon {
  font-size: 30px;
  color: #888;
  margin-bottom: 10px;
}

.upload-text {
  font-size: 14px;
  color: #666;
  margin: 0 0 5px 0;
  text-align: center;
}

.upload-hint {
  font-size: 12px;
  color: #999;
  margin: 0;
  text-align: center;
}

/* 上传预览样式 */
.upload-preview {
  width: 100%;
  min-height: 120px;
  position: relative;
}

.upload-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.upload-remove {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  line-height: 1;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.upload-preview:hover .upload-remove {
  opacity: 1;
}
.coverImage{
  width: 148px;height: 148px;
  object-fit: contain;
  border-radius: 4px;
}
.avatar-uploader{
  width: 148px;
  height: 148px;
  border-radius: 4px;
  box-sizing: border-box;
  border: 1px dashed #cdd0d6;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fafafa;
}
.avatar-uploader:hover{
  border-color: #f2ba45;
}

.skus-imgs {
  border-radius: 6px;
  border: 1px dashed #cdd0d6;
  width: 148px;
  height: 148px;
  box-sizing: border-box;
  position: relative;
  overflow: hidden;
  transition: all 0.3s ease;
  cursor: pointer;
}

.skus-imgs:hover {
  border-color: #f2ba45;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
  transform: translateY(-2px);
}

.skus-imgs .coverImage {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s ease;
}

.skus-imgs:hover .coverImage {
  transform: scale(1.05);
}

.skus-imgs-del {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 4;
  background: rgba(255, 255, 255, 0.8);
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 0 0 0 4px;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.skus-imgs:hover .skus-imgs-del {
  opacity: 1;
}

.skus-imgs-del:hover {
  background: #fff;
}

.avatar-uploader-insert{
  position: absolute;
  z-index: 3;
  top: 0;
  left: 0;

  width: 148px;
  height: 148px;
  opacity: 0;
}

.avatar-uploader {
  width: 148px;
  height: 148px;
  border-radius: 6px;
  border: 1px dashed #cdd0d6;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #909399;
  transition: all 0.3s ease;
  cursor: pointer;
  background-color: #2e2e2e;
}

.avatar-uploader:hover {
  border-color: #f2ba45;
  color: #f2ba45;
  background-color: #222;
}

/* 上传中状态样式 */
.avatar-uploader.uploading {
  border-color: #67c23a;
  background-color: #f0f9f0;
}

/* 图片加载中占位样式 */
.skus-imgs.loading::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.7);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.skus-imgs.loading::after {
  content: '';
  position: absolute;
  width: 20px;
  height: 20px;
  border: 3px solid #409eff;
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  z-index: 2;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}
</style>
