feat: 完成新版本Load From File功能

This commit is contained in:
Xu Zhimeng 2023-10-08 17:41:37 +08:00
parent 85f4ccb995
commit 671677a68e
4 changed files with 155 additions and 93 deletions

View File

@ -46,8 +46,7 @@ export class FilePicker {
*/ */
static async isFileInDirectory(directoryHandle, fileHandle) { static async isFileInDirectory(directoryHandle, fileHandle) {
const relativePaths = await directoryHandle.resolve(fileHandle) const relativePaths = await directoryHandle.resolve(fileHandle)
if (relativePaths === null || relativePaths.length > 1) {
if (relativePaths === null) {
return false return false
} else { } else {
return true return true

View File

@ -1,5 +1,6 @@
import { Modal } from 'ant-design-vue' import { Modal } from 'ant-design-vue'
import { saveAs } from 'file-saver' import { saveAs } from 'file-saver'
import JSZip from 'jszip'
/** /**
* 弹窗填入文件名保存文件 * 弹窗填入文件名保存文件
@ -55,3 +56,23 @@ export const readFile = (file, fileType = 'text') => {
} }
}) })
} }
/**
* 压缩文件
* @param {Array<File>} fileList
* @param {string} zipName
* @returns
*/
export const zipFile = async (fileList, zipName) => {
const zip = new JSZip()
const promises = []
fileList.forEach(file => {
promises.push(readFile(file, 'arrayBuffer'))
})
const result = await Promise.all(promises)
result.forEach(res => {
zip.file(res.fileName, res.data)
})
const content = await zip.generateAsync({ type: 'blob' })
return new File([content], zipName, { type: content.type })
}

View File

@ -23,12 +23,12 @@ export class PHDParser {
/** /**
* sample 谱的文件名 * sample 谱的文件名
*/ */
sampleFileName = '' sampleFilePrefix = ''
/** /**
* 其他文件名 * 其他文件名
*/ */
otherFileNames = [] otherFilePrefixes = []
/** /**
* 构造函数 * 构造函数
@ -53,9 +53,9 @@ export class PHDParser {
if (this.fileType == 'B') { if (this.fileType == 'B') {
// 如果解析的是sample 文件,则获取其他三个文件 // 如果解析的是sample 文件,则获取其他三个文件
if (this.dataType == PHD_DATA_TYPE.SAMPLEPHD) { if (this.dataType == PHD_DATA_TYPE.SAMPLEPHD) {
const fileNames = this.getFileNames(fileNameLine) const filePrefixes = this.getFilePrefixes(fileNameLine)
this.sampleFileName = fileNames.splice(0, 1)[0] this.sampleFilePrefix = filePrefixes.splice(0, 1)[0]
this.otherFileNames = fileNames this.otherFilePrefixes = filePrefixes
} }
} }
} }
@ -93,16 +93,15 @@ export class PHDParser {
* 获取全部文件名 * 获取全部文件名
* @param {string} text * @param {string} text
*/ */
getFileNames(text) { getFilePrefixes(text) {
const unHandledfileNames = this.splitLineText(text) const unHandledfilePrefixes = this.splitLineText(text)
const fileTypes = ['S', 'D', 'G'] const filePrefixes = unHandledfilePrefixes
const fileNames = unHandledfileNames .filter(filePrefix => filePrefix)
.filter(fileName => fileName) .map(filePrefix => {
.map((fileName, index) => { filePrefix = filePrefix.replace(/(\d{4})\/(\d{2})\/(\d{2})-(\d{2}):(\d{2})/, '$1$2$3_$4$5')
fileName = fileName.replace(/(\d{4})\/(\d{2})\/(\d{2})-(\d{2}):(\d{2})/, '$1$2$3_$4$5') return filePrefix + '_'
return `${fileName}_${fileTypes[index]}_${this.qualify}`
}) })
return fileNames return filePrefixes
} }
} }

View File

@ -10,53 +10,54 @@
bordered bordered
:scroll="{ y: 450 }" :scroll="{ y: 450 }"
> >
<template slot="sampleData" slot-scope="text, record"> <template slot="sampleData" slot-scope="text, record, index">
<div <div
class="file-name file-ellipsis" class="file-name file-ellipsis"
:title="text && text.fileName" :title="text && text.fileName"
@dblclick="useFilePicker('sampleFileName', record)" @dblclick="useFilePicker('sampleFileName', record, index)"
> >
{{ text && text.fileName }} {{ text && text.fileName }}
</div> </div>
</template> </template>
<template slot="gasBkData" slot-scope="text, record"> <template slot="gasBkData" slot-scope="text, record, index">
<div <div
:class="['file-ellipsis', !record.gasFileName ? 'file-name-color' : '']" :class="['file-ellipsis', text && text.file ? '' : 'file-name-color']"
:title="text && text.fileName" :title="text && text.fileName"
@dblclick="useFilePicker('gasFileName', record)" @dblclick="useFilePicker('gasFileName', record, index)"
> >
{{ text && text.fileName }} {{ text && text.fileName }}
</div> </div>
</template> </template>
<template slot="detBkData" slot-scope="text, record"> <template slot="detBkData" slot-scope="text, record, index">
<div <div
:class="['file-ellipsis', !record.detFileName ? 'file-name-color' : '']" :class="['file-ellipsis', text && text.file ? '' : 'file-name-color']"
:title="text && text.fileName" :title="text && text.fileName"
@dblclick="useFilePicker('detFileName', record)" @dblclick="useFilePicker('detFileName', record, index)"
> >
{{ text && text.fileName }} {{ text && text.fileName }}
</div> </div>
</template> </template>
<template slot="qcData" slot-scope="text, record"> <template slot="qcData" slot-scope="text, record, index">
<div <div
:class="['file-ellipsis', !record.qcFileName ? 'file-name-color' : '']" :class="['file-ellipsis', text && text.file ? '' : 'file-name-color']"
:title="text && text.fileName" :title="text && text.fileName"
@dblclick="useFilePicker('qcFileName', record)" @dblclick="useFilePicker('qcFileName', record, index)"
> >
{{ text && text.fileName }} {{ text && text.fileName }}
</div> </div>
</template> </template>
<template slot="status" slot-scope="text, record"> <template slot="status" slot-scope="text, record">
<span <template v-if="record.sampleFileName">
:class="[ <span
record.sampleFileName class="status"
? record.fileType == 'B' && !(record.gasFileName && record.detFileName) :class="
record.fileType == 'B' &&
!(record.gasFileName && record.gasFileName.file && record.detFileName && record.detFileName.file)
? 'status_false' ? 'status_false'
: 'status_true' : 'status_true'
: '', "
'status', ></span>
]" </template>
></span>
</template> </template>
</a-table> </a-table>
<!-- 不支持 File System Access 的情况 --> <!-- 不支持 File System Access 的情况 -->
@ -121,6 +122,7 @@
<template slot="custom-footer"> <template slot="custom-footer">
<a-space> <a-space>
<a-upload <a-upload
v-if="!canUseFilePicker"
accept=".PHD,.phd" accept=".PHD,.phd"
:custom-request="handleUpload" :custom-request="handleUpload"
:multiple="true" :multiple="true"
@ -130,7 +132,7 @@
<a-button type="primary" :loading="uploading"> Upload </a-button> <a-button type="primary" :loading="uploading"> Upload </a-button>
</a-upload> </a-upload>
<a-button type="primary" @click="handleReset">Reset</a-button> <a-button type="primary" @click="handleReset">Reset</a-button>
<a-button type="primary" @click="handleLoad">Load</a-button> <a-button :loading="isUploadingZip" type="primary" @click="handleLoad">Load</a-button>
<a-button type="primary" @click="handleCancel">Cancel</a-button> <a-button type="primary" @click="handleCancel">Cancel</a-button>
</a-space> </a-space>
</template> </template>
@ -200,10 +202,9 @@
</template> </template>
<script> <script>
import JSZip from 'jszip'
import { getAction, postAction } from '../../../../api/manage' import { getAction, postAction } from '../../../../api/manage'
import { FilePicker } from '@/utils/FilePicker' import { FilePicker } from '@/utils/FilePicker'
import { readFile } from '@/utils/file' import { readFile, zipFile } from '@/utils/file'
import { PHDParser, PHD_DATA_TYPE } from '@/utils/phdHelper' import { PHDParser, PHD_DATA_TYPE } from '@/utils/phdHelper'
import ModalMixin from '@/mixins/ModalMixin' import ModalMixin from '@/mixins/ModalMixin'
@ -289,6 +290,7 @@ export default {
columns_file, columns_file,
loading_file: false, loading_file: false,
loading_list: false, loading_list: false,
isUploadingZip: false,
list: [], list: [],
ipagination: { ipagination: {
current: 1, current: 1,
@ -360,29 +362,30 @@ export default {
}, },
// //
async useFilePicker(column, record) { async useFilePicker(column, record, rowIndex) {
// sampleFile // sampleFile
if (column !== 'sampleFileName' && (!record.sampleFileName || record.fileType !== 'B')) { if (column !== 'sampleFileName' && (!record.sampleFileName || record.fileType !== 'B')) {
return return
} }
if (this.directoryHanlder) { if (this.directoryHanlder) {
this.chooseFile(column, record) this.chooseFile(column, record, rowIndex)
} else { } else {
try { try {
this.directoryHanlder = await FilePicker.chooseDirectory() this.directoryHanlder = await FilePicker.chooseDirectory()
this.chooseFile(column, record) this.chooseFile(column, record, rowIndex)
} catch {} } catch {}
} }
}, },
async chooseFile(column, record) { async chooseFile(column, record, rowIndex) {
try { try {
const [fileHandle] = await FilePicker.chooseFile(false, [{ accept: { 'text/phd': ['.phd'] } }]) const [fileHandle] = await FilePicker.chooseFile(false, [{ accept: { 'text/phd': ['.phd'] } }])
try { try {
const isFileInDirectory = await FilePicker.isFileInDirectory(this.directoryHanlder, fileHandle) const isFileInDirectory = await FilePicker.isFileInDirectory(this.directoryHanlder, fileHandle)
if (!isFileInDirectory) { if (!isFileInDirectory) {
this.$message.warn('File and Directory Not in Same') this.$message.warn('File and Directory Not in Same')
this.directoryHanlder = undefined
return return
} }
@ -400,10 +403,18 @@ export default {
// sample // sample
if (column == 'sampleFileName') { if (column == 'sampleFileName') {
const { sampleFileName, otherFileNames, liveTime } = phdParser //
const findIndex = this.list.findIndex(
(item) => item.sampleFileName && item.sampleFileName.file && item.sampleFileName.file.name == file.name
)
if (-1 !== findIndex && findIndex !== rowIndex) {
return
}
const { sampleFilePrefix, otherFilePrefixes, qualify, liveTime } = phdParser
record.sampleFileName = { record.sampleFileName = {
file, file,
fileName: `${sampleFileName}_${liveTime}.PHD`, fileName: `${sampleFilePrefix}S_${qualify}_${liveTime}.PHD`,
} }
const iter = await this.directoryHanlder.values() const iter = await this.directoryHanlder.values()
@ -418,11 +429,13 @@ export default {
} }
const nameKeys = ['detFileName', 'gasFileName'] const nameKeys = ['detFileName', 'gasFileName']
const fileTypes = ['D', 'G']
otherFileNames.forEach((otherFileName, index) => { otherFilePrefixes.forEach((otherFilePrefix, index) => {
const fileType = fileTypes[index]
// sample // sample
const findFile = fileList.find((file) => { const findFile = fileList.find((file) => {
return file.name.includes(otherFileName) return file.name.includes(`${otherFilePrefix}${fileType}_${qualify}`)
}) })
if (findFile) { if (findFile) {
@ -431,16 +444,21 @@ export default {
fileName: findFile.name, fileName: findFile.name,
} }
} else { } else {
record[columns[index]] = undefined record[nameKeys[index]] = {
file: undefined,
fileName: `${otherFilePrefix}${fileType}.PHD`,
}
} }
}) })
// QC // QC
let qcFileInfo = undefined let qcFileInfo = {
file: undefined,
fileName: `${sampleFilePrefix}Q.PHD`,
}
const qcFileList = fileList.filter((file) => file.name.includes('_Q_')) const qcFileList = fileList.filter((file) => file.name.includes('_Q_'))
const compareFileName = sampleFileName.slice(0, 23)
for (const qcFile of qcFileList) { for (const qcFile of qcFileList) {
if (qcFile.name.slice(0, 23) <= compareFileName) { if (qcFile.name.slice(0, 23) <= sampleFilePrefix) {
qcFileInfo = { qcFileInfo = {
file: qcFile, file: qcFile,
fileName: qcFile.name, fileName: qcFile.name,
@ -466,7 +484,7 @@ export default {
/** /**
* 判断文件和列是否匹配 * 判断文件和列是否匹配
* @param {*} fileType * @param {*} column
* @param {*} dataType * @param {*} dataType
*/ */
fileNameAndColumnMatch(column, dataType) { fileNameAndColumnMatch(column, dataType) {
@ -569,60 +587,85 @@ export default {
beforeUpload(file, fileList) { beforeUpload(file, fileList) {
this.fileList = fileList this.fileList = fileList
}, },
handleUpload({ file }) { async handleUpload() {
this.uploading = true this.uploading = true
this.fileNum += 1 this.fileNum += 1
if (this.fileNum == this.fileList.length) { if (this.fileNum == this.fileList.length) {
this.zipFile(this.fileList) const file = await zipFile(this.fileList, 'test.zip')
const res = await this.uploadZipFile(file)
this.uploading = false
this.fileNum = 0
if (res.success) {
this.$message.success(res.message)
} else {
this.$message.warning(res.message)
}
} }
}, },
async zipFile(fileList, onProgress) {
const zip = new JSZip()
const promises = []
fileList.forEach((file) => {
promises.push(this.readAsArrayBuffer(file))
})
Promise.all(promises).then((result) => {
result.forEach((res) => {
zip.file(res.fileName, res.data)
})
zip.generateAsync({ type: 'blob' }).then((content) => {
let file = new File([content], 'test.zip', { type: content.type })
const formData = new FormData()
formData.append('file', file)
postAction('/spectrumFile/upload', formData).then((res) => {
this.uploading = false
this.fileNum = 0
if (res.success) {
this.$message.success(res.message)
} else {
this.$message.warning(res.message)
}
})
})
})
},
async readAsArrayBuffer(file) { // zip
return new Promise((resolve) => { async uploadZipFile(file) {
let reader = new FileReader() const formData = new FormData()
reader.readAsArrayBuffer(file) formData.append('file', file)
reader.onload = (e) => { const res = await postAction('/spectrumFile/upload', formData)
resolve({ return res
fileName: file.name,
data: e.target.result,
})
}
})
}, },
handleReset() { handleReset() {
this.list = this.getInitialList() this.list = this.getInitialList()
}, },
handleLoad() { async handleLoad() {
this.visible = false //
this.$emit('loadFormFile', this.list) if (this.canUseFilePicker) {
const propNames = ['sampleFileName', 'gasFileName', 'detFileName', 'qcFileName']
const files = []
for (const item of this.list) {
propNames.forEach((propName) => {
const value = item[propName]
if (value && value.file) {
files.push(value.file)
}
})
}
if(!files.length) {
this.$message.warn('File is Empty ')
return
}
const zipedFiles = await zipFile(files, 'test.zip')
this.isUploadingZip = true
try {
const { success, message } = await this.uploadZipFile(zipedFiles)
if (success) {
try {
const { success, result, message } = await getAction('/spectrumAnalysis/getFilesBySampleFile', {
fileName: this.list
.filter((item) => item.sampleFileName)
.map((item) => item.sampleFileName.file.name)
.join(','),
})
if (success) {
this.visible = false
this.$emit('loadFormFile', result)
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
} finally {
this.isUploadingZip = false
}
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
this.isUploadingZip = false
}
} else {
this.visible = false
this.$emit('loadFormFile', this.list)
}
}, },
handleCancel() { handleCancel() {