<template>
  <div>
    <!-- 图片上传组件 -->
    <el-upload
      :action="uploadAction"                       <!-- 设置上传的服务器地址 -->
    :headers="uploadHeaders"                     <!-- 设置上传请求头，包含认证信息 -->
    list-type="picture-card"                     <!-- 使用卡片列表显示上传的图片 -->
    :on-preview="handlePictureCardPreview"       <!-- 点击预览图标时触发的事件 -->
    :on-remove="handleRemove"                    <!-- 点击移除图标时触发的事件 -->
    :on-success="handleUploadSuccess"            <!-- 文件上传成功后的回调 -->
    :file-list="imageList"                       <!-- 显示的文件列表 -->
    :before-upload="beforeAvatarUpload"          <!-- 上传前的钩子函数，用于限制文件类型和大小 -->
    >
    <el-icon><Plus /></el-icon>                  <!-- 上传按钮中的加号图标 -->
    </el-upload>

    <!-- 预览对话框 -->
    <el-dialog v-model="dialogVisible">            <!-- 对话框的显示状态由dialogVisible控制 -->
      <img
        width="100%"                               <!-- 图片宽度为100%，适应对话框大小 -->
      :src="dialogImageUrl"                      <!-- 动态绑定预览图片的URL -->
      alt=""
      >
    </el-dialog>
  </div>
</template>

<script setup>
import $cookie from 'vue-cookies'                   // 导入vue-cookies用于获取存储在客户端的token
import { ElMessage } from 'element-plus'            // 导入Element Plus的消息提示组件
import { computed, ref } from 'vue'                // 导入Vue的响应式API

// 定义上传请求头，包含从cookie中获取的Authorization令牌
const uploadHeaders = { Authorization: $cookie.get('Authorization') }

// 定义上传图片的服务器地址
const uploadAction = http.adornUrl('/admin/file/upload/element')

// 定义父组件传递的属性
const props = defineProps({
  modelValue: {
    default: '',                                   // 默认值为空字符串
    type: String                                   // 类型为字符串
  }
})

// 定义emit函数，用于向父组件发送更新
const emit = defineEmits(['update:modelValue'])

// 存储资源的基础URL
const resourcesUrl = import.meta.env.VITE_APP_RESOURCES_URL

// 存储预览对话框的可见性状态和图片URL
const dialogImageUrl = ref('')
const dialogVisible = ref(false)

// 计算属性：根据父组件传入的modelValue生成图片列表
const imageList = computed(() => {
  const res = []
  if (props.modelValue) {
    const imageArray = props.modelValue?.split(',') // 将modelValue按逗号分割成数组
    for (let i = 0; i < imageArray.length; i++) {
      res.push({ url: resourcesUrl + imageArray[i], response: imageArray[i] })
    }
  }
  emit('update:modelValue', props.modelValue) // 更新父组件的modelValue
  return res
})

/**
 * 图片上传成功的处理函数
 */
const handleUploadSuccess = (response, file, fileList) => {
  const pics = fileList.map(file => {
    if (typeof file.response === 'string') {
      return file.response
    }
    return file.response.data
  }).join(',')
  emit('update:modelValue', pics) // 更新父组件的modelValue
}

/**
 * 上传前的钩子函数，用于限制图片上传的格式和大小
 */
const beforeAvatarUpload = (file) => {
  const isJPG = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif' || file.type === 'image/jpg'
  if (!isJPG) {
    ElMessage.error('上传图片只能是jpeg/jpg/png/gif 格式!') // 提示错误信息
    return false
  }
  const isLt2M = file.size / 1024 / 1024 < 2
  if (!isLt2M) {
    ElMessage.error('上传图片大小不能超过 2MB!') // 提示错误信息
    return false
  }
  return isLt2M && isJPG
}

/**
 * 处理移除图片的操作
 */
const handleRemove = (file, fileList) => {
  const pics = fileList.map(file => {
    if (typeof file.response === 'string') {
      return file.response
    }
    return file.response.data
  }).join(',')
  emit('update:modelValue', pics) // 更新父组件的modelValue
}

/**
 * 处理图片预览操作
 */
const handlePictureCardPreview = (file) => {
  dialogImageUrl.value = file.url // 设置要预览的图片URL
  dialogVisible.value = true      // 打开预览对话框
}
</script>
