Browse Source

资料导入功能恢复

duy 3 weeks ago
parent
commit
f88f611215

+ 249 - 0
src/views/data-fill/components/dataBatchImport.vue

@@ -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>
+

+ 9 - 17
src/views/data-fill/components/dataImport.vue

@@ -1,6 +1,6 @@
 <!-- 资料导入 -->
 <!-- 资料导入 -->
 <template>
 <template>
-    <hc-new-dialog v-model="dataModal" title="资料导入" @close="closeModal">
+    <hc-new-dialog v-model="dataModal" title="资料导入" :loading="confirmLoading" @close="closeModal">
         <div style="position: relative;">
         <div style="position: relative;">
             <el-upload
             <el-upload
                 ref="dialogUploadRef" :headers="getHeader()" drag 
                 ref="dialogUploadRef" :headers="getHeader()" drag 
@@ -22,7 +22,7 @@
                 <div v-for="file in fileList" :key="file.uid" class="mb-2 flex items-center justify-between border rounded p-2">
                 <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">
                     <div class="flex items-center">
                         <HcIcon name="file-excel" class="mr-2 text-green-500" />
                         <HcIcon name="file-excel" class="mr-2 text-green-500" />
-                        <span>{{ file.name }}</span>
+                        <span>{{ file.name }}{{ file.uid }}</span>
                     </div>
                     </div>
                     <el-button type="danger" link @click="handleRemove(file)">
                     <el-button type="danger" link @click="handleRemove(file)">
                         <HcIcon name="delete" />
                         <HcIcon name="delete" />
@@ -30,14 +30,12 @@
                 </div>
                 </div>
             </div>
             </div>
             <div class="download-btn-container mt-2 text-right">
             <div class="download-btn-container mt-2 text-right">
-                <!-- 添加类名 -->
                 <el-button hc-btn type="primary" :loading="downLoadTemplateLoading" @click="downLoadTemplate">
                 <el-button hc-btn type="primary" :loading="downLoadTemplateLoading" @click="downLoadTemplate">
                     <HcIcon name="download-2" />
                     <HcIcon name="download-2" />
                     下载模板
                     下载模板
                 </el-button>
                 </el-button>
             </div>
             </div>
-        </div>
-            
+        </div>            
         <template #footer>
         <template #footer>
             <el-button @click="closeModal">取消</el-button>
             <el-button @click="closeModal">取消</el-button>
             <el-button type="primary" :loading="confirmLoading" @click="confirmTap">确认上传</el-button>
             <el-button type="primary" :loading="confirmLoading" @click="confirmTap">确认上传</el-button>
@@ -47,11 +45,9 @@
 
 
 <script setup>
 <script setup>
 import { nextTick, ref, watch } from 'vue'
 import { nextTick, ref, watch } from 'vue'
-import { downloadBlob, getArrValue, getObjValue, isNullES } from 'js-fast-way'
-import { useAppStore } from '~src/store'
-import { HcDelMsg, getHeader } from 'hc-vue3-ui'
+import { isNullES } from 'js-fast-way'
+import { getHeader } from 'hc-vue3-ui'
 
 
-import wbsApi from '~api/data-fill/wbs'
 import divisionApi from '~api/data-fill/division'
 import divisionApi from '~api/data-fill/division'
 
 
 const props = defineProps({
 const props = defineProps({
@@ -110,8 +106,9 @@ const beforeUpload = (file) => {
 // 添加以下数据和方法
 // 添加以下数据和方法
 const fileList = ref([])
 const fileList = ref([])
 
 
-const handleChange = (file, files) => {
-    fileList.value = [file] // 由于限制为1个文件,直接替换
+const handleChange = (file) => {
+    fileList.value = [file] // // 由于限制为1个文件,直接替换
+    console.log('fileList', fileList)
 }
 }
 
 
 const handleRemove = (file) => {
 const handleRemove = (file) => {
@@ -167,11 +164,6 @@ const confirmTap = async ()=>{
     }
     }
     confirmLoading.value = true
     confirmLoading.value = true
     dialogUploadRef.value.submit()
     dialogUploadRef.value.submit()
-    
-
-
-
-    
 }
 }
 const parseFileName = (disposition) => {
 const parseFileName = (disposition) => {
     const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
     const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
@@ -210,7 +202,7 @@ const downloadBlob1 = (data, disposition = '', type = 'application/vnd.ms-excel'
     document.body.removeChild(tempLink)
     document.body.removeChild(tempLink)
     window.URL.revokeObjectURL(blobURL)
     window.URL.revokeObjectURL(blobURL)
 }
 }
-//导入模板
+// 导入模板
 const downLoadTemplate = async ()=>{
 const downLoadTemplate = async ()=>{
     downLoadTemplateLoading.value = true
     downLoadTemplateLoading.value = true
     const { error, disposition, res, msg } = await divisionApi.downloadNodeExcel({
     const { error, disposition, res, msg } = await divisionApi.downloadNodeExcel({

+ 68 - 7
src/views/data-fill/wbs.vue

@@ -1533,6 +1533,63 @@
             :classify="authBtnTabKey"
             :classify="authBtnTabKey"
             @success="importSaveClick"
             @success="importSaveClick"
         />
         />
+
+        <FileBatchUploadDialog v-model="divisionBatchImportDialog" :node-id="primaryKeyId" :classify="authBtnTabKey" />
+
+        <!-- 批量导入资料-台账记录 -->
+        <hc-new-dialog v-model="batchImportVisible" title="批量导入资料-台账记录" widths="800px" :footer="false">
+            <div class="mb-5 flex">
+                <div class="w-50">
+                    <el-input v-model="batchImportParams.fileName" clearable placeholder="文件名称" @clear="getBatchImportRecord" />
+                </div>
+                <div class="ml-2 w-70">
+                    <HcDatePicker :dates="betweenTime" clearable @change="betweenTimeUpdate" @clear="getBatchImportRecord" />
+                </div>
+                <div class="ml-2 w-25">
+                    <el-select v-model="batchImportParams.status" clearable placeholder="状态">
+                        <el-option v-for="(value, key) in IMPORT_STATUS" :key="key" :label="value" :value="key" @clear="getBatchImportRecord" />
+                    </el-select>
+                </div>
+                <div class="ml-2 w-25">
+                    <el-select v-model="batchImportParams.userId" clearable placeholder="操作人" @clear="getBatchImportRecord">
+                        <el-option
+                            v-for="item in createUserList" :key="item.userId" :label="item.userName"
+                            :value="item.userId"
+                        />
+                    </el-select>
+                </div>
+                <div class="ml-2 w-25">
+                    <el-select v-model="batchImportParams.classify" clearable placeholder="所属方" @clear="getBatchImportRecord">
+                        <el-option label="施工" :value="1" />
+                        <el-option label="监理" :value="2" />
+                    </el-select>
+                </div>
+                <el-button class="ml-2" type="primary" @click="getBatchImportRecord">搜索</el-button>
+            </div>
+            <el-table :data="batchImportData.table" :border="true" :height="550">
+                <el-table-column label="序号" type="index" width="55" align="center" />
+                <el-table-column label="所属方" prop="classify" width="75" align="center">
+                    <template #default="{ row }">
+                        <span>{{ row.classify === 1 ? '施工' : '监理' }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="文件名称" prop="fileName" />
+                <el-table-column label="操作人" prop="createUserName" width="75" align="center" />
+                <el-table-column label="导入时间" prop="createTime" width="170" align="center" />
+
+                <el-table-column label="导入状态" prop="status" width="85" align="center">
+                    <template #default="{ row }">
+                        <span>{{ IMPORT_STATUS[row?.status] }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="备注" prop="remark" width="150" />
+            </el-table>
+            <hc-pages
+                ui="mt-5"
+                :pages="{ current: batchImportParams.current, size: batchImportParams.size, total: batchImportData.total }"
+                @change="pageChange"
+            />
+        </hc-new-dialog>
     </div>
     </div>
 </template>
 </template>
 
 
@@ -1579,6 +1636,7 @@ import JumpTreeDialog from './components/JumpTreeDialog.vue'
 import collectApi from '~api/data-fill/collect'
 import collectApi from '~api/data-fill/collect'
 import linkData from './components/linkData.vue'
 import linkData from './components/linkData.vue'
 import FileUploadDialog from './components/dataImport.vue'
 import FileUploadDialog from './components/dataImport.vue'
+import FileBatchUploadDialog from './components/dataBatchImport.vue'
 //初始变量
 //初始变量
 const router = useRouter()
 const router = useRouter()
 const useRoutes = useRoute()
 const useRoutes = useRoute()
@@ -2369,6 +2427,8 @@ const setTreeMenuDataClick = ({ key, node, data }) => {
     } else if (key === 'wbsLink') {
     } else if (key === 'wbsLink') {
         console.log('wbsLink')
         console.log('wbsLink')
         wbsLinkModal.value = true
         wbsLinkModal.value = true
+    } else if (key === 'batchImport') {
+        dataBatchImportDialogClick()
     }
     }
         
         
 }
 }
@@ -4468,9 +4528,9 @@ const selCollectMneu = ()=>{
 }
 }
 
 
 // 输入框失焦处理
 // 输入框失焦处理
-const handleEditBlur = (folder) => {
+// const handleEditBlur = (folder) => {
 
 
-}
+// }
 
 
 // 获取文件夹列表的方法需要修改,为每个文件夹添加编辑相关属性
 // 获取文件夹列表的方法需要修改,为每个文件夹添加编辑相关属性
 
 
@@ -4565,15 +4625,16 @@ const linkModalClose = ()=>{
 }
 }
 //资料导入
 //资料导入
 const divisionImportDialog = ref(false)
 const divisionImportDialog = ref(false)
+const divisionBatchImportDialog = ref(false)
 
 
 const dataImportDialogClick = ()=>{
 const dataImportDialogClick = ()=>{
     divisionImportDialog.value = true
     divisionImportDialog.value = true
 }
 }
-const importSaveClick = ()=>{
-
-      getTableDataAll()
-    
-
+const dataBatchImportDialogClick = () => {
+    divisionBatchImportDialog.value = true
+}
+const importSaveClick = () => {
+    getTableDataAll()
 }
 }
 </script>
 </script>