From c8db1c78f00c3167d6bc3d49d568ade313a206eb Mon Sep 17 00:00:00 2001 From: fengyuan_yang <1976974459@qq.com> Date: Wed, 5 Aug 2026 16:29:00 +0800 Subject: [PATCH] =?UTF-8?q?2026-08-05=20=E7=89=A9=E6=96=99=E6=A1=A3?= =?UTF-8?q?=E6=A1=88=E7=AE=A1=E7=90=86-=E3=80=8BSOP=E6=B8=85=E5=8D=95-?= =?UTF-8?q?=E3=80=8B=E4=BB=8E=E6=96=87=E4=BB=B6=E5=BA=93=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E3=80=90=E5=88=A0=E9=99=A4=E3=80=91=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/qc/qc.js | 1 + src/views/modules/qc/sopFileUpload.vue | 154 ++++++++++++++++++++----- 2 files changed, 127 insertions(+), 28 deletions(-) diff --git a/src/api/qc/qc.js b/src/api/qc/qc.js index 18c3c0f..6cec992 100644 --- a/src/api/qc/qc.js +++ b/src/api/qc/qc.js @@ -261,6 +261,7 @@ export const getCustomerList = data => createAPI(`/pms/qc/getCustomerList`,'post // ===================================== SOP清单 ===================================== export const sopListSearch = data => createAPI(`/pms/qc/sopListSearch`,'post',data) export const sopAvailableFiles = data => createAPI(`/pms/qc/sopAvailableFiles`,'post',data) +export const sopAvailableFilesDelete = data => createAPI(`/pms/qc/sopAvailableFiles/delete`,'post',data) /** 物料SOP「文件上传」弹窗:批量本地上传,写入 file_management(D:\\sop_files + UspInsertSOP) */ export const sopFileBatchUpload = data => createAPI(`/pms/qc/sopFileBatchUpload`, 'post', data) // 查询检验页面的SOP文件列表(IPQC/IQC/FQC/OQC/过程检验) diff --git a/src/views/modules/qc/sopFileUpload.vue b/src/views/modules/qc/sopFileUpload.vue index 5c0e8dc..06a9e7c 100644 --- a/src/views/modules/qc/sopFileUpload.vue +++ b/src/views/modules/qc/sopFileUpload.vue @@ -27,6 +27,7 @@ 查询 上传文件 + 删除 @@ -219,7 +220,8 @@ import SopFileManagementUpload from './sopFileManagementUpload' import { sopAvailableFiles, sopFileUploadSave, - getStandardOperation + getStandardOperation, + sopAvailableFilesDelete } from '@/api/qc/qc.js' export default { @@ -243,9 +245,12 @@ export default { filePageIndex: 1, filePageSize: 10, fileTotalPage: 0, + serverFileTotalPage: 0, // 服务端返回的原始总数 fileListLoading: false, selectedFiles: [], + deleteLoading: false, uploadedFileList: [], + pendingAddedFiles: [], // 已添加到下方、需从上方隐藏的文件 selectedUploadedFiles: [], // 已上传文件表格中选中的文件 operationList: [] } @@ -282,15 +287,71 @@ export default { } this.selectedFiles = [] this.uploadedFileList = [] + this.pendingAddedFiles = [] this.selectedUploadedFiles = [] + this.fileList = [] this.originalFileList = [] this.filePageIndex = 1 + this.fileTotalPage = 0 + this.serverFileTotalPage = 0 }, openUploadDialog () { this.$nextTick(() => { this.$refs.sopFileManagementUpload.init(this.currentSite, this.currentBuNo) }) }, + // 生成文件唯一键 + getFileKey (file) { + if (!file) { + return '' + } + if (file.id !== null && file.id !== undefined && file.id !== '') { + return `id_${file.id}` + } + const site = file.site || '' + const buNo = file.buNo || '' + const fileNo = file.fileNo || '' + const sopRevNo = file.sopRevNo || '' + return `${site}__${buNo}__${fileNo}__${sopRevNo}` + }, + // 同步「下方已添加文件」到上方隐藏集合 + syncPendingAddedFiles () { + this.pendingAddedFiles = this.uploadedFileList.map(file => ({ + id: file.id, + site: file.site, + buNo: file.buNo, + fileNo: file.fileNo, + fileName: file.fileName, + fileType: file.fileType, + sopRevNo: file.sopRevNo + })) + }, + // 判断文件是否命中当前搜索条件 + isFileMatchCurrentSearch (file) { + const fileNoKeyword = (this.searchForm.fileNo || '').trim().toLowerCase() + const fileNameKeyword = (this.searchForm.fileName || '').trim().toLowerCase() + const fileTypeKeyword = (this.searchForm.fileType || '').trim().toLowerCase() + const sopRevNoKeyword = (this.searchForm.sopRevNo || '').trim().toLowerCase() + const fileNo = String(file.fileNo || '').toLowerCase() + const fileName = String(file.fileName || '').toLowerCase() + const fileType = String(file.fileType || '').toLowerCase() + const sopRevNo = String(file.sopRevNo || '').toLowerCase() + return (!fileNoKeyword || fileNo.indexOf(fileNoKeyword) > -1) && + (!fileNameKeyword || fileName.indexOf(fileNameKeyword) > -1) && + (!fileTypeKeyword || fileType.indexOf(fileTypeKeyword) > -1) && + (!sopRevNoKeyword || sopRevNo.indexOf(sopRevNoKeyword) > -1) + }, + // 获取当前查询条件下已添加到下方的条数(用于动态更新上方总数) + getPendingAddedCountForCurrentSearch () { + return this.pendingAddedFiles.filter(file => this.isFileMatchCurrentSearch(file)).length + }, + // 刷新上方列表展示(行数据 + 总条数) + refreshFileListView () { + const pendingFileKeys = new Set(this.pendingAddedFiles.map(file => this.getFileKey(file))) + this.fileList = this.originalFileList.filter(file => !pendingFileKeys.has(this.getFileKey(file))) + const pendingCount = this.getPendingAddedCountForCurrentSearch() + this.fileTotalPage = Math.max((this.serverFileTotalPage || 0) - pendingCount, 0) + }, // 获取文件列表 getFileList () { this.fileListLoading = true @@ -306,17 +367,21 @@ export default { }).then(({data}) => { if (data && data.code === 0) { this.originalFileList = data.page.list || [] // 保存原始数据 - // 过滤掉已添加的文件 - this.fileList = this.originalFileList.filter(file => - !this.uploadedFileList.some(uploaded => uploaded.fileNo === file.fileNo && uploaded.sopRevNo === file.sopRevNo) - ) - this.fileTotalPage = data.page.totalCount || 0 + this.serverFileTotalPage = data.page.totalCount || 0 + this.refreshFileListView() } else { this.fileList = [] this.originalFileList = [] + this.serverFileTotalPage = 0 this.fileTotalPage = 0 } this.fileListLoading = false + }).catch(() => { + this.fileList = [] + this.originalFileList = [] + this.serverFileTotalPage = 0 + this.fileTotalPage = 0 + this.fileListLoading = false }) }, // 重置搜索 @@ -346,10 +411,51 @@ export default { // 确保选中的文件包含完整数据 this.selectedFiles = val.map(selectedFile => { // 从原始文件列表中找到完整的文件信息 - const completeFile = this.fileList.find(file => file.fileNo === selectedFile.fileNo && file.sopRevNo === selectedFile.sopRevNo) + const selectedFileKey = this.getFileKey(selectedFile) + const completeFile = this.fileList.find(file => this.getFileKey(file) === selectedFileKey) return completeFile || selectedFile }) }, + // 删除上方列表中选中的文件(真实删除file_management) + deleteSelectedFiles () { + if (this.selectedFiles.length === 0) { + this.$message.warning('请先选择要删除的文件') + return + } + + this.$confirm(`确定删除选中的 ${this.selectedFiles.length} 个文件吗?`, '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + this.deleteLoading = true + const deleteList = this.selectedFiles.map(file => ({ + id: file.id, + site: file.site, + buNo: file.buNo, + fileNo: file.fileNo, + sopRevNo: file.sopRevNo, + sopUrl: file.sopUrl || '' + })) + sopAvailableFilesDelete(deleteList).then(({ data }) => { + if (data && data.code === 0) { + this.$message.success(`成功删除 ${this.selectedFiles.length} 个文件`) + const deleteFileKeys = new Set(deleteList.map(file => this.getFileKey(file))) + this.uploadedFileList = this.uploadedFileList.filter(file => !deleteFileKeys.has(this.getFileKey(file))) + this.syncPendingAddedFiles() + this.$refs.fileTable && this.$refs.fileTable.clearSelection() + this.selectedFiles = [] + this.getFileList() + } else { + this.$message.error((data && data.msg) || '删除失败') + } + }).catch(() => { + this.$message.error('删除失败') + }).finally(() => { + this.deleteLoading = false + }) + }).catch(() => {}) + }, // 添加选中的文件 addSelectedFiles () { if (this.selectedFiles.length === 0) { @@ -362,11 +468,13 @@ export default { // 添加到已上传列表 this.selectedFiles.forEach(file => { - const exists = this.uploadedFileList.some(uploaded => uploaded.fileNo === file.fileNo && uploaded.sopRevNo === file.sopRevNo) + const fileKey = this.getFileKey(file) + const exists = this.uploadedFileList.some(uploaded => this.getFileKey(uploaded) === fileKey) if (exists) { duplicateCount++ } else { this.uploadedFileList.push({ + id: file.id, site: file.site, buNo: file.buNo, fileNo: file.fileNo, @@ -388,11 +496,8 @@ export default { if (duplicateCount > 0) { this.$message.warning(`存在 ${duplicateCount} 个文件编码和版本号重复的文件,不能重复添加`) } - - // 从上方列表中移除已添加的文件 - this.fileList = this.fileList.filter(file => - !this.uploadedFileList.some(uploaded => uploaded.fileNo === file.fileNo && uploaded.sopRevNo === file.sopRevNo) - ) + this.syncPendingAddedFiles() + this.refreshFileListView() if (addedCount > 0) { this.$message.success(`已添加 ${addedCount} 个文件`) @@ -408,26 +513,17 @@ export default { this.$message.warning('请先选择要删除的文件') return } - - // 将删除的文件重新添加到上方列表 - this.selectedUploadedFiles.forEach(file => { - // 检查原始列表中是否存在该文件 - const originalFile = this.originalFileList.find(original => original.fileNo === file.fileNo && original.sopRevNo === file.sopRevNo) - if (originalFile) { - // 检查上方列表中是否已存在 - const exists = this.fileList.some(existing => existing.fileNo === file.fileNo && existing.sopRevNo === file.sopRevNo) - if (!exists) { - this.fileList.push(originalFile) - } - } - }) + const selectedCount = this.selectedUploadedFiles.length + const selectedFileKeys = new Set(this.selectedUploadedFiles.map(file => this.getFileKey(file))) // 从已上传列表中移除 this.uploadedFileList = this.uploadedFileList.filter(file => - !this.selectedUploadedFiles.some(selected => selected.fileNo === file.fileNo && selected.sopRevNo === file.sopRevNo) + !selectedFileKeys.has(this.getFileKey(file)) ) + this.syncPendingAddedFiles() + this.refreshFileListView() - this.$message.success(`已删除${this.selectedUploadedFiles.length}个文件`) + this.$message.success(`已删除${selectedCount}个文件`) // 清空选择 this.$refs.uploadedFileTable && this.$refs.uploadedFileTable.clearSelection() @@ -440,6 +536,8 @@ export default { // 删除已上传的文件 removeUploadedFile (index) { this.uploadedFileList.splice(index, 1) + this.syncPendingAddedFiles() + this.refreshFileListView() this.$message.success('文件已移除') }, // 保存文件