From db42d47f5692ef64e5436c5a6d29dcb537b44596 Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期一, 26 一月 2026 16:36:13 +0800
Subject: [PATCH] 浪潮对接单点登录:mis调整

---
 src/components/Dialog/FileListDialog.vue |  309 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 309 insertions(+), 0 deletions(-)

diff --git a/src/components/Dialog/FileListDialog.vue b/src/components/Dialog/FileListDialog.vue
new file mode 100644
index 0000000..0721a55
--- /dev/null
+++ b/src/components/Dialog/FileListDialog.vue
@@ -0,0 +1,309 @@
+<template>
+  <el-dialog 
+    v-model="dialogVisible" 
+    :title="title" 
+    :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" 
+        :prop="nameColumnProp" 
+        :min-width="nameColumnMinWidth" 
+        show-overflow-tooltip 
+      />
+      <el-table-column 
+        v-if="showActions"
+        fixed="right" 
+        label="鎿嶄綔" 
+        :width="actionColumnWidth" 
+        align="center"
+      >
+        <template #default="scope">
+          <el-button 
+            v-if="showDownload"
+            link 
+            type="primary" 
+            size="small" 
+            @click="handleDownload(scope.row)"
+          >
+            涓嬭浇
+          </el-button>
+          <el-button 
+            v-if="showPreview"
+            link 
+            type="primary" 
+            size="small" 
+            @click="handlePreview(scope.row)"
+          >
+            棰勮
+          </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>
+      <slot name="columns"></slot>
+    </el-table>
+  </el-dialog>
+  <filePreview v-if="showPreview" ref="filePreviewRef" />
+</template>
+
+<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: {
+    type: Boolean,
+    default: false
+  },
+  title: {
+    type: String,
+    default: '闄勪欢'
+  },
+  width: {
+    type: String,
+    default: '40%'
+  },
+  tableHeight: {
+    type: String,
+    default: '40vh'
+  },
+  nameColumnLabel: {
+    type: String,
+    default: '闄勪欢鍚嶇О'
+  },
+  nameColumnProp: {
+    type: String,
+    default: 'name'
+  },
+  nameColumnMinWidth: {
+    type: [String, Number],
+    default: 400
+  },
+  actionColumnWidth: {
+    type: [String, Number],
+    default: 160
+  },
+  showActions: {
+    type: Boolean,
+    default: true
+  },
+  showDownload: {
+    type: Boolean,
+    default: true
+  },
+  showPreview: {
+    type: Boolean,
+    default: true
+  },
+  showUploadButton: {
+    type: Boolean,
+    default: false
+  },
+  showDeleteButton: {
+    type: Boolean,
+    default: false
+  },
+  urlField: {
+    type: String,
+    default: 'url'
+  },
+  downloadMethod: {
+    type: Function,
+    default: null
+  },
+  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', 'upload', 'delete'])
+
+const { proxy } = getCurrentInstance()
+const filePreviewRef = ref(null)
+const uploadFileList = ref([])
+
+const dialogVisible = computed({
+  get: () => props.modelValue,
+  set: (val) => emit('update:modelValue', val)
+})
+
+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')
+  dialogVisible.value = false
+}
+
+const handleDownload = (row) => {
+  if (props.downloadMethod) {
+    props.downloadMethod(row)
+  } else {
+    // 榛樿涓嬭浇鏂规硶
+    proxy.$download.name(row[props.urlField])
+  }
+  emit('download', row)
+}
+
+const handlePreview = (row) => {
+  if (props.previewMethod) {
+    props.previewMethod(row)
+  } else {
+    // 榛樿棰勮鏂规硶
+    if (filePreviewRef.value) {
+      filePreviewRef.value.open(row[props.urlField])
+    }
+  }
+  emit('preview', row)
+}
+
+const open = (list) => {
+  dialogVisible.value = true
+  tableData.value = list || []
+}
+
+const handleUpload = async () => {
+  if (props.uploadMethod) {
+    // 濡傛灉鎻愪緵浜嗚嚜瀹氫箟涓婁紶鏂规硶锛岀敱鐖剁粍浠惰礋璐f洿鏂板垪琛紙閫氳繃 setList锛�
+    // 杩欓噷涓嶅啀鑷姩娣诲姞锛岄伩鍏嶄笌鐖剁粍浠剁殑 setList 閲嶅
+    await props.uploadMethod()
+  }
+  emit('upload')
+}
+
+const handleDelete = async (row, index) => {
+  if (props.deleteMethod) {
+    const result = await props.deleteMethod(row, index)
+    if (result === false) {
+      return
+    }
+    // 濡傛灉鎻愪緵浜� deleteMethod锛岀敱鐖剁粍浠惰礋璐e埛鏂板垪琛紝涓嶅湪杩欓噷鍒犻櫎
+  } 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,
+  addAttachment,
+  removeAttachment,
+  setList,
+  handleUpload,
+  handleDelete
+})
+</script>
+
+<style scoped>
+.file-list-toolbar {
+  margin-bottom: 8px;
+  text-align: right;
+}
+</style>
+

--
Gitblit v1.9.3