spring
7 小时以前 ebe3507d1382bb124c1fb895a5e27f7063fdffdc
src/components/Dialog/FileListDialog.vue
@@ -5,6 +5,37 @@
    :width="width" 
    :before-close="handleClose"
  >
    <div class="file-list-toolbar" v-if="showToolbar">
      <template v-if="useBuiltInUpload">
        <el-upload
          v-model:file-list="uploadFileList"
          class="upload-demo"
          :action="uploadAction"
          :headers="uploadHeaders"
          :show-file-list="false"
          :on-success="handleDefaultUploadSuccess"
          :on-error="handleDefaultUploadError"
        >
          <el-button
            v-if="showUploadButton"
            type="primary"
            size="small"
          >
            上传附件
          </el-button>
        </el-upload>
      </template>
      <template v-else>
        <el-button
          v-if="showUploadButton"
          type="primary"
          size="small"
          @click="handleUpload"
        >
          新增附件
        </el-button>
      </template>
    </div>
    <el-table :data="tableData" border :height="tableHeight">
      <el-table-column 
        :label="nameColumnLabel" 
@@ -38,6 +69,15 @@
          >
            预览
          </el-button>
          <el-button
            v-if="showDeleteButton"
            link
            type="danger"
            size="small"
            @click="handleDelete(scope.row, scope.$index)"
          >
            删除
          </el-button>
          <slot name="actions" :row="scope.row"></slot>
        </template>
      </el-table-column>
@@ -49,7 +89,9 @@
<script setup>
import { ref, computed, getCurrentInstance } from 'vue'
import { ElMessage } from 'element-plus'
import filePreview from '@/components/filePreview/index.vue'
import { getToken } from '@/utils/auth'
const props = defineProps({
  modelValue: {
@@ -82,7 +124,7 @@
  },
  actionColumnWidth: {
    type: [String, Number],
    default: 100
    default: 160
  },
  showActions: {
    type: Boolean,
@@ -96,6 +138,14 @@
    type: Boolean,
    default: true
  },
  showUploadButton: {
    type: Boolean,
    default: false
  },
  showDeleteButton: {
    type: Boolean,
    default: false
  },
  urlField: {
    type: String,
    default: 'url'
@@ -107,13 +157,30 @@
  previewMethod: {
    type: Function,
    default: null
  },
  uploadMethod: {
    type: Function,
    default: null
  },
  deleteMethod: {
    type: Function,
    default: null
  },
  rulesRegulationsManagementId: {
    type: [String, Number],
    default: ''
  },
  uploadUrl: {
    type: String,
    default: `${import.meta.env.VITE_APP_BASE_API}/file/upload`
  }
})
const emit = defineEmits(['update:modelValue', 'close', 'download', 'preview'])
const emit = defineEmits(['update:modelValue', 'close', 'download', 'preview', 'upload', 'delete'])
const { proxy } = getCurrentInstance()
const filePreviewRef = ref(null)
const uploadFileList = ref([])
const dialogVisible = computed({
  get: () => props.modelValue,
@@ -121,6 +188,12 @@
})
const tableData = ref([])
const showToolbar = computed(() => props.showUploadButton)
const useBuiltInUpload = computed(() => !props.uploadMethod)
const uploadAction = computed(() => props.uploadUrl)
const uploadHeaders = computed(() => ({
  Authorization: `Bearer ${getToken()}`
}))
const handleClose = () => {
  emit('close')
@@ -154,11 +227,84 @@
  tableData.value = list || []
}
const handleUpload = async () => {
  if (props.uploadMethod) {
    const newItem = await props.uploadMethod()
    if (newItem) {
      addAttachment(newItem)
    }
  }
  emit('upload')
}
const handleDelete = async (row, index) => {
  if (props.deleteMethod) {
    const result = await props.deleteMethod(row, index)
    if (result === false) {
      return
    }
    // 如果提供了 deleteMethod,由父组件负责刷新列表,不在这里删除
  } else {
    // 如果没有提供 deleteMethod,才在组件内部删除
    removeAttachment(index)
  }
  emit('delete', row)
}
const addAttachment = (item) => {
  tableData.value = [...tableData.value, item]
}
const handleDefaultUploadSuccess = async (res, file) => {
  if (res?.code !== 200) {
    ElMessage.error(res?.msg || '文件上传失败')
    return
  }
  if (!props.rulesRegulationsManagementId) {
    ElMessage.error('缺少规章制度ID,无法保存附件')
    return
  }
  const fileName = res?.data?.originalName || file?.name
  const fileUrl = res?.data?.tempPath || res?.data?.url
  const payload = {
    fileName,
    fileUrl,
    rulesRegulationsManagementId: props.rulesRegulationsManagementId,
    raw: res?.data || {}
  }
  emit('upload', payload)
}
const handleDefaultUploadError = () => {
  ElMessage.error('文件上传失败')
}
const removeAttachment = (index) => {
  if (index > -1 && index < tableData.value.length) {
    const newList = [...tableData.value]
    newList.splice(index, 1)
    tableData.value = newList
  }
}
const setList = (list) => {
  tableData.value = list || []
}
defineExpose({
  open
  open,
  addAttachment,
  removeAttachment,
  setList,
  handleUpload,
  handleDelete
})
</script>
<style scoped>
.file-list-toolbar {
  margin-bottom: 8px;
  text-align: right;
}
</style>