|
@@ -0,0 +1,249 @@
|
|
|
|
|
+<!-- 资料导入 -->
|
|
|
|
|
+<template>
|
|
|
|
|
+ <hc-new-dialog v-model="dataModal" title="资料批量导入" @close="closeModal">
|
|
|
|
|
+ <div style="position: relative;">
|
|
|
|
|
+ <el-upload
|
|
|
|
|
+ ref="dialogBatchUploadRef" :headers="getHeader()" drag
|
|
|
|
|
+ action="/api/blade-manager/informationImportRecord/import"
|
|
|
|
|
+ :on-success="handleSuccess" :on-error="handleError" accept=".xls,.xlsx"
|
|
|
|
|
+ :auto-upload="false"
|
|
|
|
|
+ multiple
|
|
|
|
|
+ :on-exceed="handleExceed"
|
|
|
|
|
+ :before-upload="beforeUpload"
|
|
|
|
|
+ :show-file-list="false"
|
|
|
|
|
+ :on-change="handleChange"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="mt-24px text-black">将文件拖动到此处,<span class="text-blue">或点击上传</span></div>
|
|
|
|
|
+ <div class="mt-8px text-12px">支持的文件格式:.xls,.xlsx</div>
|
|
|
|
|
+ </el-upload>
|
|
|
|
|
+ <!-- 自定义文件列表 -->
|
|
|
|
|
+ <div v-if="fileList.length > 0" class="upload-file-list mt-4">
|
|
|
|
|
+ <div v-for="file in fileList" :key="file.uid" class="mb-2 flex items-center justify-between border rounded p-2">
|
|
|
|
|
+ <div class="flex items-center">
|
|
|
|
|
+ <HcIcon name="file-excel" class="mr-2 text-green-500" />
|
|
|
|
|
+ <span>{{ file.name }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-button type="danger" link @click="handleRemove(file)">
|
|
|
|
|
+ <HcIcon name="delete" />
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <!-- <div class="download-btn-container mt-2 text-right">
|
|
|
|
|
+ <el-button hc-btn type="primary" :loading="downLoadTemplateLoading" @click="downLoadTemplate">
|
|
|
|
|
+ <HcIcon name="download-2" />
|
|
|
|
|
+ 下载模板
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </div> -->
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <el-button @click="closeModal">取消</el-button>
|
|
|
|
|
+ <el-button type="primary" :loading="confirmLoading" @click="confirmTap">确认上传</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </hc-new-dialog>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup>
|
|
|
|
|
+import { nextTick, ref, watch } from 'vue'
|
|
|
|
|
+import { isNullES } from 'js-fast-way'
|
|
|
|
|
+// import { downloadBlob, getArrValue, getObjValue, isNullES } from 'js-fast-way'
|
|
|
|
|
+// import { useAppStore } from '~src/store'
|
|
|
|
|
+// import { HcDelMsg, getHeader } from 'hc-vue3-ui'
|
|
|
|
|
+import { getHeader } from 'hc-vue3-ui'
|
|
|
|
|
+
|
|
|
|
|
+// import wbsApi from '~api/data-fill/wbs'
|
|
|
|
|
+import divisionApi from '~api/data-fill/division'
|
|
|
|
|
+
|
|
|
|
|
+const props = defineProps({
|
|
|
|
|
+ nodeId: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: '',
|
|
|
|
|
+ },
|
|
|
|
|
+ classify: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: '',
|
|
|
|
|
+ },
|
|
|
|
|
+})
|
|
|
|
|
+//事件
|
|
|
|
|
+const emit = defineEmits(['close', 'save', 'success'])
|
|
|
|
|
+const nodeId = ref(props.nodeId)
|
|
|
|
|
+const classify = ref(props.classify)
|
|
|
|
|
+
|
|
|
|
|
+watch(
|
|
|
|
|
+ () => [props.nodeId, props.classify],
|
|
|
|
|
+ ([nid, clas]) => {
|
|
|
|
|
+ nodeId.value = nid
|
|
|
|
|
+ classify.value = clas
|
|
|
|
|
+ fileList.value = []
|
|
|
|
|
+ },
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+const dataModal = defineModel('modelValue', {
|
|
|
|
|
+ default: false,
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const closeModal = ()=>{
|
|
|
|
|
+ dataModal.value = false
|
|
|
|
|
+ fileList.value = []
|
|
|
|
|
+ emit('close')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+//上传文件
|
|
|
|
|
+const dialogBatchUploadRef = ref(null)
|
|
|
|
|
+// const pKeyIdData = ref('')
|
|
|
|
|
+// 文件类型验证
|
|
|
|
|
+const beforeUpload = (file) => {
|
|
|
|
|
+ const extension = file.name.split('.').pop().toLowerCase()
|
|
|
|
|
+ if (!['xls', 'xlsx'].includes(extension)) {
|
|
|
|
|
+ window.$message.error('仅支持上传 .xls 或 .xlsx 格式的表格文件')
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ return true
|
|
|
|
|
+}
|
|
|
|
|
+// 添加以下数据和方法
|
|
|
|
|
+const fileList = ref([])
|
|
|
|
|
+
|
|
|
|
|
+const handleChange = (file, files) => {
|
|
|
|
|
+ console.log('handleChange', file, files)
|
|
|
|
|
+ fileList.value = files
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleRemove = (file) => {
|
|
|
|
|
+ fileList.value = fileList.value.filter(item => item.uid !== file.uid)
|
|
|
|
|
+ dialogBatchUploadRef.value?.clearFiles()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleExceed = (files) => {
|
|
|
|
|
+ dialogBatchUploadRef.value.clearFiles()
|
|
|
|
|
+ const file = files[0]
|
|
|
|
|
+ dialogBatchUploadRef.value.handleStart(file)
|
|
|
|
|
+}
|
|
|
|
|
+//上传成功
|
|
|
|
|
+
|
|
|
|
|
+const confirmLoading = ref(false)
|
|
|
|
|
+const handleSuccess = (res) => {
|
|
|
|
|
+
|
|
|
|
|
+ confirmLoading.value = false
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ window.$message.success(res.msg || '上传成功')
|
|
|
|
|
+ emit('success', res)
|
|
|
|
|
+ nextTick(()=>{
|
|
|
|
|
+ fileList.value = []
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ closeModal()
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+
|
|
|
|
|
+ window.$message.error(res.msg || '上传失败')
|
|
|
|
|
+ nextTick(()=>{
|
|
|
|
|
+ fileList.value = []
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//上传失败
|
|
|
|
|
+const handleError = (error) => {
|
|
|
|
|
+ confirmLoading.value = false
|
|
|
|
|
+ const { msg } = !isNullES(error.message) ? JSON.parse(error.message) : {}
|
|
|
|
|
+ if (isNullES(msg)) {
|
|
|
|
|
+ window.$message.error('上传失败')
|
|
|
|
|
+ } else {
|
|
|
|
|
+ window.$message.error(msg)
|
|
|
|
|
+ }
|
|
|
|
|
+ fileList.value = []
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+const confirmTap = async ()=>{
|
|
|
|
|
+ if (!fileList.value.length) {
|
|
|
|
|
+ window.$message.warning('请先选择文件')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const formData = new FormData()
|
|
|
|
|
+ fileList.value.forEach(f => formData.append('files', f.raw))
|
|
|
|
|
+ formData.append('nodeId', nodeId.value)
|
|
|
|
|
+ formData.append('classify', classify.value)
|
|
|
|
|
+
|
|
|
|
|
+ confirmLoading.value = true
|
|
|
|
|
+ const { code, msg } = await divisionApi.batchImportExcel(formData)
|
|
|
|
|
+ if (code === 200) {
|
|
|
|
|
+ window.$message.success(msg || '上传成功')
|
|
|
|
|
+ emit('success')
|
|
|
|
|
+ nextTick(()=>{
|
|
|
|
|
+ fileList.value = []
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ closeModal()
|
|
|
|
|
+ }
|
|
|
|
|
+ confirmLoading.value = false
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+// const parseFileName = (disposition) => {
|
|
|
|
|
+// const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
|
|
|
|
|
+// const matches = filenameRegex.exec(disposition)
|
|
|
|
|
+// if (matches && matches[1]) {
|
|
|
|
|
+// return decodeURIComponent(matches[1].replace(/['"]/g, ''))
|
|
|
|
|
+// }
|
|
|
|
|
+// return 'unknown'
|
|
|
|
|
+// }
|
|
|
|
|
+
|
|
|
|
|
+// const downloadBlob1 = (data, disposition = '', type = 'application/vnd.ms-excel')=> {
|
|
|
|
|
+// const blob = new Blob([data], { type: type })
|
|
|
|
|
+// const blobURL = window.URL.createObjectURL(blob)
|
|
|
|
|
+// const tempLink = document.createElement('a')
|
|
|
|
|
+// tempLink.style.display = 'none'
|
|
|
|
|
+// tempLink.href = blobURL
|
|
|
|
|
+
|
|
|
|
|
+// // 1. 解析文件名
|
|
|
|
|
+// let filename = parseFileName(disposition)
|
|
|
|
|
+
|
|
|
|
|
+// // 2. 关键修复:过滤特殊字符并确保.xlsx后缀
|
|
|
|
|
+// // 过滤不安全字符:#、/、%等,替换为_
|
|
|
|
|
+// filename = filename.replace(/[#%/\\:*?"<>|]/g, '_')
|
|
|
|
|
+// // 强制确保以.xlsx结尾(移除可能的多余字符)
|
|
|
|
|
+// if (!filename.endsWith('.xlsx')) {
|
|
|
|
|
+// // 先移除现有后缀(如果有),再补全.xlsx
|
|
|
|
|
+// filename = filename.replace(/\.[^.]*$/, '') + '.xlsx'
|
|
|
|
|
+// }
|
|
|
|
|
+
|
|
|
|
|
+// tempLink.setAttribute('download', filename)
|
|
|
|
|
+// if (typeof tempLink.download === 'undefined') {
|
|
|
|
|
+// tempLink.setAttribute('target', '_blank')
|
|
|
|
|
+// }
|
|
|
|
|
+// document.body.appendChild(tempLink)
|
|
|
|
|
+// tempLink.click()
|
|
|
|
|
+// document.body.removeChild(tempLink)
|
|
|
|
|
+// window.URL.revokeObjectURL(blobURL)
|
|
|
|
|
+// }
|
|
|
|
|
+//导入模板
|
|
|
|
|
+// const downLoadTemplate = async ()=>{
|
|
|
|
|
+// downLoadTemplateLoading.value = true
|
|
|
|
|
+// const { error, disposition, res, msg } = await divisionApi.downloadNodeExcel({
|
|
|
|
|
+// nodeId:nodeId.value,
|
|
|
|
|
+// classify:classify.value,
|
|
|
|
|
+
|
|
|
|
|
+// })
|
|
|
|
|
+// downLoadTemplateLoading.value = false
|
|
|
|
|
+// if (!error) {
|
|
|
|
|
+// if (disposition) {
|
|
|
|
|
+// downloadBlob1(res, disposition)
|
|
|
|
|
+// } else {
|
|
|
|
|
+// window.$message?.error(msg || '数据异常')
|
|
|
|
|
+// }
|
|
|
|
|
+// }
|
|
|
|
|
+// }
|
|
|
|
|
+// const downLoadTemplateLoading = ref(false)
|
|
|
|
|
+
|
|
|
|
|
+//获取两棵树的数据
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style lang='scss' scoped>
|
|
|
|
|
+.download-btn-container {
|
|
|
|
|
+ overflow: hidden; /* 限制溢出,避免尺寸变化导致滚动 */
|
|
|
|
|
+ white-space: nowrap; /* 防止按钮内容换行导致高度变化 */
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|
|
|
|
|
+
|