Merge branch 'feature-analysis-RLR-renpy' of http://git.hivekion.com:3000/xiaoguangbin/AnalysisSystemForRadionuclide_vue into master-dev
This commit is contained in:
commit
0d39833584
55
src/utils/FilePicker.js
Normal file
55
src/utils/FilePicker.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* 本地文件选择
|
||||||
|
*/
|
||||||
|
export class FilePicker {
|
||||||
|
/**
|
||||||
|
* 接口是否可用
|
||||||
|
* @returns { Boolean }
|
||||||
|
*/
|
||||||
|
static canUse() {
|
||||||
|
return !!(window.showDirectoryPicker && window.showOpenFilePicker)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择一个目录
|
||||||
|
* @returns { Promise<FileSystemDirectoryHandle> }
|
||||||
|
*/
|
||||||
|
static chooseDirectory() {
|
||||||
|
if (!this.canUse()) {
|
||||||
|
throw new Error('Not Support showDirectoryPicker')
|
||||||
|
}
|
||||||
|
return window.showDirectoryPicker()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择一个文件
|
||||||
|
* @param { Boolean } multiple
|
||||||
|
* @param { { description?: string; accept?: { [key: string]: string[]; } } } types
|
||||||
|
* @returns { Promise<FileSystemFileHandle[]> }
|
||||||
|
*/
|
||||||
|
static chooseFile(multiple, types) {
|
||||||
|
if (!this.canUse()) {
|
||||||
|
throw new Error('Not Support showOpenFilePicker')
|
||||||
|
}
|
||||||
|
const pickerOpts = {
|
||||||
|
multiple,
|
||||||
|
types,
|
||||||
|
excludeAcceptAllOption: true
|
||||||
|
}
|
||||||
|
return window.showOpenFilePicker(pickerOpts)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断一个文件是否在某个目录下
|
||||||
|
* @param {FileSystemDirectoryHandle} directoryHandle
|
||||||
|
* @param {FileSystemFileHandle} fileHandle
|
||||||
|
*/
|
||||||
|
static async isFileInDirectory(directoryHandle, fileHandle) {
|
||||||
|
const relativePaths = await directoryHandle.resolve(fileHandle)
|
||||||
|
if (relativePaths === null || relativePaths.length > 1) {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 弹窗填入文件名保存文件
|
* 弹窗填入文件名保存文件
|
||||||
|
@ -31,3 +32,56 @@ export const showSaveFileModal = (data, ext) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读文件
|
||||||
|
* @param {File} file
|
||||||
|
* @param { 'arrayBuffer' | 'text' | 'dataURL' | 'binaryString'} fileType
|
||||||
|
* @returns {Promise<string | ArrayBuffer}
|
||||||
|
*/
|
||||||
|
export const readFile = (file, fileType = 'text') => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const fileReader = new FileReader()
|
||||||
|
const category = {
|
||||||
|
arrayBuffer: 'readAsArrayBuffer',
|
||||||
|
text: 'readAsText',
|
||||||
|
dataURL: 'readAsDataURL',
|
||||||
|
binaryString: 'readAsBinaryString'
|
||||||
|
}
|
||||||
|
fileReader[category[fileType]](file)
|
||||||
|
fileReader.onload = event => {
|
||||||
|
resolve(event.target.result)
|
||||||
|
}
|
||||||
|
fileReader.onerror = error => {
|
||||||
|
reject(error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 压缩文件
|
||||||
|
* @param {Array<File>} fileList
|
||||||
|
* @param {string} zipName
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const zipFile = async (fileList, zipName) => {
|
||||||
|
const zip = new JSZip()
|
||||||
|
const promises = []
|
||||||
|
|
||||||
|
const readFileWithName = async file => {
|
||||||
|
const data = await readFile(file, 'arrayBuffer')
|
||||||
|
return {
|
||||||
|
fileName: file.name,
|
||||||
|
data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fileList.forEach(file => {
|
||||||
|
promises.push(readFileWithName(file))
|
||||||
|
})
|
||||||
|
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 })
|
||||||
|
}
|
||||||
|
|
182
src/utils/phdHelper.js
Normal file
182
src/utils/phdHelper.js
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
/**
|
||||||
|
* PHD 类型
|
||||||
|
*/
|
||||||
|
export const PHD_DATA_TYPE = {
|
||||||
|
QCPHD: 'QCPHD',
|
||||||
|
DETBKPHD: 'DETBKPHD',
|
||||||
|
SAMPLEPHD: 'SAMPLEPHD',
|
||||||
|
GASBKPHD: 'GASBKPHD'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是不是sample
|
||||||
|
* @param {*} dataType
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const isSample = dataType => {
|
||||||
|
return ['SAMPLEPHD', 'SPHDP', 'SPHDF'].includes(dataType)
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PHDParser {
|
||||||
|
/**
|
||||||
|
* 根据Block解析出的结果集
|
||||||
|
*/
|
||||||
|
blocks = {
|
||||||
|
baseInfo: []
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据类型
|
||||||
|
*/
|
||||||
|
dataType = ''
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型 B G 等
|
||||||
|
*/
|
||||||
|
fileType = ''
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 质量 FULL 等
|
||||||
|
*/
|
||||||
|
qualify = ''
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生存时间
|
||||||
|
*/
|
||||||
|
|
||||||
|
liveTime = ''
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sample 谱的文件名
|
||||||
|
*/
|
||||||
|
sampleFilePrefix = ''
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 其他文件名
|
||||||
|
*/
|
||||||
|
otherFilePrefixes = []
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 该文件是不是sample
|
||||||
|
*/
|
||||||
|
isSample = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数
|
||||||
|
* @param {string} text
|
||||||
|
*/
|
||||||
|
constructor(text) {
|
||||||
|
this.splitByBlock(text)
|
||||||
|
this.dataType = this.getBaseInfoByTag('DATA_TYPE')[0]
|
||||||
|
this.isSample = isSample(this.dataType)
|
||||||
|
|
||||||
|
const headerInfo = this.getBlockInfo('Header')
|
||||||
|
const headerInfoLine1 = this.splitLineText(headerInfo[0])
|
||||||
|
this.fileType = headerInfoLine1[2]
|
||||||
|
this.qualify = headerInfoLine1[4]
|
||||||
|
|
||||||
|
const liveTime = parseFloat(this.getBlockStr('Acquisition', 0, 3)).toFixed(1)
|
||||||
|
this.liveTime = liveTime.indexOf('.0') == -1 ? liveTime : liveTime.slice(0, -2)
|
||||||
|
|
||||||
|
// 如果解析的是sample 文件,则解析相关联的文件
|
||||||
|
if (this.isSample) {
|
||||||
|
const filePrefixes = this.getFilePrefixes(headerInfo[2])
|
||||||
|
this.sampleFilePrefix = filePrefixes.splice(0, 1)[0]
|
||||||
|
this.otherFilePrefixes = filePrefixes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据块类型分割
|
||||||
|
* @param {string} text
|
||||||
|
*/
|
||||||
|
splitByBlock(text) {
|
||||||
|
const lines = (text = text.replace(/\r{0,1}\n/g, '\n').split('\n'))
|
||||||
|
let blockType = 'baseInfo'
|
||||||
|
for (const line of lines) {
|
||||||
|
// 如果以#开头
|
||||||
|
if (line.startsWith('#')) {
|
||||||
|
blockType = line.slice(1)
|
||||||
|
if (blockType.startsWith('Header')) {
|
||||||
|
blockType = 'Header'
|
||||||
|
}
|
||||||
|
this.blocks[blockType] = []
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
this.blocks[blockType].push(line.trim())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据块名拿到块内容
|
||||||
|
* @param {string} blockName
|
||||||
|
* @returns {Array<string>}
|
||||||
|
*/
|
||||||
|
getBlockInfo(blockName) {
|
||||||
|
return this.blocks[blockName]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在baseInfo中根据tag查找值
|
||||||
|
* @param {*} tag
|
||||||
|
* @returns {Array<string>}
|
||||||
|
*/
|
||||||
|
getBaseInfoByTag(tag) {
|
||||||
|
const baseInfo = this.getBlockInfo('baseInfo')
|
||||||
|
const map = new Map()
|
||||||
|
baseInfo.forEach(line => {
|
||||||
|
if (line.startsWith(tag)) {
|
||||||
|
map.set(tag, this.getOnymousData(line))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return map.get(tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据行号和位置在block中查找字符
|
||||||
|
* @param {string} blockName
|
||||||
|
* @param {number} lineNum
|
||||||
|
* @param {number} index
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
getBlockStr(blockName, lineNum, index) {
|
||||||
|
const blockInfo = this.getBlockInfo(blockName)
|
||||||
|
const lineText = blockInfo[lineNum]
|
||||||
|
const splited = this.splitLineText(lineText)
|
||||||
|
return splited[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 具名 行的数据
|
||||||
|
* @param {string} text
|
||||||
|
* @example DATA_TYPE SAMPLEPHD 返回['SAMPLEPHD']
|
||||||
|
* @returns {string[]}
|
||||||
|
*/
|
||||||
|
getOnymousData(text) {
|
||||||
|
return text.split(' ').slice(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将一行中的文本按空格切割
|
||||||
|
* @param {string} text
|
||||||
|
*/
|
||||||
|
splitLineText(text) {
|
||||||
|
return text.replace(/\s+/g, ',').split(',')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取全部文件名
|
||||||
|
* @param {string} text
|
||||||
|
*/
|
||||||
|
getFilePrefixes(text) {
|
||||||
|
const unHandledfilePrefixes = this.splitLineText(text)
|
||||||
|
const filePrefixes = unHandledfilePrefixes
|
||||||
|
.filter(filePrefix => filePrefix)
|
||||||
|
.map(filePrefix => {
|
||||||
|
filePrefix = filePrefix.replace(/(\d{4})\/(\d{2})\/(\d{2})-(\d{2}):(\d{2})(:\d{2}\.\d)?/, '$1$2$3_$4$5')
|
||||||
|
return filePrefix + '_'
|
||||||
|
})
|
||||||
|
return filePrefixes
|
||||||
|
}
|
||||||
|
}
|
|
@ -197,7 +197,7 @@ export default {
|
||||||
*/
|
*/
|
||||||
async handleLoad() {
|
async handleLoad() {
|
||||||
if (!this.selectedRowKeys.length) {
|
if (!this.selectedRowKeys.length) {
|
||||||
this.$message.warn('Please Select Databases To Load')
|
this.$message.warn('Please Select Sample To Load')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.selectedRowKeys = []
|
this.selectedRowKeys = []
|
||||||
|
|
|
@ -1,7 +1,68 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<custom-modal v-model="visible" :width="1200" title="Load Data From File">
|
<custom-modal v-model="visible" :width="1200" title="Load Data From File">
|
||||||
|
<!-- 支持 File System Access 的情况 -->
|
||||||
<a-table
|
<a-table
|
||||||
|
v-if="canUseFilePicker"
|
||||||
|
:dataSource="list"
|
||||||
|
:columns="columns"
|
||||||
|
:pagination="false"
|
||||||
|
bordered
|
||||||
|
:scroll="{ y: 450 }"
|
||||||
|
>
|
||||||
|
<template slot="sampleData" slot-scope="text, record, index">
|
||||||
|
<div
|
||||||
|
class="file-name file-ellipsis"
|
||||||
|
:title="text && text.fileName"
|
||||||
|
@dblclick="useFilePicker('sampleFileName', record, index)"
|
||||||
|
>
|
||||||
|
{{ text && text.fileName }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template slot="gasBkData" slot-scope="text, record, index">
|
||||||
|
<div
|
||||||
|
:class="['file-ellipsis', text && text.file ? '' : 'file-name-color']"
|
||||||
|
:title="text && text.fileName"
|
||||||
|
@dblclick="useFilePicker('gasFileName', record, index)"
|
||||||
|
>
|
||||||
|
{{ text && text.fileName }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template slot="detBkData" slot-scope="text, record, index">
|
||||||
|
<div
|
||||||
|
:class="['file-ellipsis', text && text.file ? '' : 'file-name-color']"
|
||||||
|
:title="text && text.fileName"
|
||||||
|
@dblclick="useFilePicker('detFileName', record, index)"
|
||||||
|
>
|
||||||
|
{{ text && text.fileName }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template slot="qcData" slot-scope="text, record, index">
|
||||||
|
<div
|
||||||
|
:class="['file-ellipsis', text && text.file ? '' : 'file-name-color']"
|
||||||
|
:title="text && text.fileName"
|
||||||
|
@dblclick="useFilePicker('qcFileName', record, index)"
|
||||||
|
>
|
||||||
|
{{ text && text.fileName }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template slot="status" slot-scope="text, record">
|
||||||
|
<template v-if="record.sampleFileName">
|
||||||
|
<span
|
||||||
|
class="status"
|
||||||
|
:class="
|
||||||
|
record.fileType == 'B' &&
|
||||||
|
!(record.gasFileName && record.gasFileName.file && record.detFileName && record.detFileName.file)
|
||||||
|
? 'status_false'
|
||||||
|
: 'status_true'
|
||||||
|
"
|
||||||
|
></span>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
<!-- 不支持 File System Access 的情况 -->
|
||||||
|
<a-table
|
||||||
|
v-else
|
||||||
:data-source="list"
|
:data-source="list"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:loading="loading_list"
|
:loading="loading_list"
|
||||||
|
@ -13,7 +74,7 @@
|
||||||
<div class="file-name file-ellipsis" :title="text" @dblclick="handleFileSelect('_S_', record)">
|
<div class="file-name file-ellipsis" :title="text" @dblclick="handleFileSelect('_S_', record)">
|
||||||
{{ text }}
|
{{ text }}
|
||||||
</div>
|
</div>
|
||||||
<!-- <phd-select type="file" @change="handleFileChange(record, 'sampleData', $event)" @select="handleFileSelect" :title="text && text.name">
|
<!-- <phd-select type="file" @change="handleFileChange(record, 'sampleData', $event)" @select="handleFileSelect" :title="text && text.fileName">
|
||||||
{{ text }}
|
{{ text }}
|
||||||
</phd-select> -->
|
</phd-select> -->
|
||||||
</template>
|
</template>
|
||||||
|
@ -61,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"
|
||||||
|
@ -70,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>
|
||||||
|
@ -140,10 +202,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import JSZip from 'jszip'
|
|
||||||
import FileSaver from 'file-saver'
|
|
||||||
import PhdSelect from '../PHDSelect.vue'
|
|
||||||
import { getAction, postAction } from '../../../../api/manage'
|
import { getAction, postAction } from '../../../../api/manage'
|
||||||
|
import { FilePicker } from '@/utils/FilePicker'
|
||||||
|
import { readFile, zipFile } from '@/utils/file'
|
||||||
|
import { isSample, PHDParser, PHD_DATA_TYPE } from '@/utils/phdHelper'
|
||||||
|
import ModalMixin from '@/mixins/ModalMixin'
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: 'SampleData',
|
title: 'SampleData',
|
||||||
|
@ -208,8 +272,11 @@ const columns_file = [
|
||||||
align: 'left',
|
align: 'left',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const canUseFilePicker = FilePicker.canUse()
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { PhdSelect },
|
mixins: [ModalMixin],
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -223,7 +290,8 @@ export default {
|
||||||
columns_file,
|
columns_file,
|
||||||
loading_file: false,
|
loading_file: false,
|
||||||
loading_list: false,
|
loading_list: false,
|
||||||
list: this.getInitialList(),
|
isUploadingZip: false,
|
||||||
|
list: [],
|
||||||
ipagination: {
|
ipagination: {
|
||||||
current: 1,
|
current: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
|
@ -247,6 +315,8 @@ export default {
|
||||||
selectionRows_edit: [],
|
selectionRows_edit: [],
|
||||||
tableType: 'multiple',
|
tableType: 'multiple',
|
||||||
searchName: '',
|
searchName: '',
|
||||||
|
|
||||||
|
canUseFilePicker,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -290,6 +360,161 @@ export default {
|
||||||
this.tableType = str === '_S_' ? 'multiple' : 'single'
|
this.tableType = str === '_S_' ? 'multiple' : 'single'
|
||||||
this.getSpectrumFile({ pageNo: 1, pageSize: 10 })
|
this.getSpectrumFile({ pageNo: 1, pageSize: 10 })
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 用新的文件操作接口
|
||||||
|
async useFilePicker(column, record, rowIndex) {
|
||||||
|
// 如果没有选择sampleFile,则不允许选其他的
|
||||||
|
if (column !== 'sampleFileName' && (!record.sampleFileName || record.fileType !== 'B')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.directoryHanlder) {
|
||||||
|
this.chooseFile(column, record, rowIndex)
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
this.directoryHanlder = await FilePicker.chooseDirectory()
|
||||||
|
this.chooseFile(column, record, rowIndex)
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async chooseFile(column, record, rowIndex) {
|
||||||
|
try {
|
||||||
|
const [fileHandle] = await FilePicker.chooseFile(false, [{ accept: { 'text/phd': ['.phd'] } }])
|
||||||
|
try {
|
||||||
|
const isFileInDirectory = await FilePicker.isFileInDirectory(this.directoryHanlder, fileHandle)
|
||||||
|
if (!isFileInDirectory) {
|
||||||
|
this.$message.warn('File and Directory Not in Same')
|
||||||
|
this.directoryHanlder = undefined
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const file = await fileHandle.getFile()
|
||||||
|
const text = await readFile(file)
|
||||||
|
const phdParser = new PHDParser(text)
|
||||||
|
console.log('%c [ phdParser ]-313', 'font-size:13px; background:pink; color:#bf2c9f;', phdParser)
|
||||||
|
const match = this.fileNameAndColumnMatch(column, phdParser.dataType)
|
||||||
|
if (!match) {
|
||||||
|
this.$message.warn('File Type Error')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
record.fileType = phdParser.fileType
|
||||||
|
|
||||||
|
// 如果是sample
|
||||||
|
if (column == 'sampleFileName') {
|
||||||
|
// 看看之前有没有选中过该文件,非同一行,则只能选择文件名不同的
|
||||||
|
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 = {
|
||||||
|
file,
|
||||||
|
fileName: `${sampleFilePrefix}S_${qualify}_${liveTime}.PHD`,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是Beta Gamma,则查找其他的文件
|
||||||
|
if (phdParser.fileType == 'B') {
|
||||||
|
const iter = await this.directoryHanlder.values()
|
||||||
|
const fileList = []
|
||||||
|
|
||||||
|
let result = await iter.next()
|
||||||
|
while (!result.done) {
|
||||||
|
const fileHandle = result.value
|
||||||
|
const file = await fileHandle.getFile()
|
||||||
|
fileList.push(file)
|
||||||
|
result = await iter.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
const nameKeys = ['detFileName', 'gasFileName']
|
||||||
|
const fileTypes = ['D', 'G']
|
||||||
|
|
||||||
|
otherFilePrefixes.forEach((otherFilePrefix, index) => {
|
||||||
|
const fileType = fileTypes[index]
|
||||||
|
// 在所有文件中查找 名字含有 从sample文件解析出的文件名 的文件
|
||||||
|
const findFile = fileList.find((file) => {
|
||||||
|
return file.name.includes(`${otherFilePrefix}${fileType}_${qualify}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (findFile) {
|
||||||
|
record[nameKeys[index]] = {
|
||||||
|
file: findFile,
|
||||||
|
fileName: findFile.name,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
record[nameKeys[index]] = {
|
||||||
|
file: undefined,
|
||||||
|
fileName: `${otherFilePrefix}${fileType}.PHD`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 查找 QC 文件
|
||||||
|
let qcFileInfo = {
|
||||||
|
file: undefined,
|
||||||
|
fileName: `${sampleFilePrefix}Q.PHD`,
|
||||||
|
}
|
||||||
|
const qcFileList = fileList.filter((file) => file.name.includes('_Q_'))
|
||||||
|
for (const qcFile of qcFileList) {
|
||||||
|
if (qcFile.name.slice(0, 23) <= sampleFilePrefix) {
|
||||||
|
qcFileInfo = {
|
||||||
|
file: qcFile,
|
||||||
|
fileName: qcFile.name,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
record.qcFileName = qcFileInfo
|
||||||
|
} else {
|
||||||
|
Object.assign(record, {
|
||||||
|
gasFileName: undefined,
|
||||||
|
detFileName: undefined,
|
||||||
|
qcFileName: undefined,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 非sample
|
||||||
|
else {
|
||||||
|
record[column] = {
|
||||||
|
file,
|
||||||
|
fileName: file.name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断文件和列是否匹配
|
||||||
|
* @param {*} column
|
||||||
|
* @param {*} dataType
|
||||||
|
*/
|
||||||
|
fileNameAndColumnMatch(column, dataType) {
|
||||||
|
let currDataType = ''
|
||||||
|
switch (column) {
|
||||||
|
case 'sampleFileName':
|
||||||
|
return isSample(dataType)
|
||||||
|
case 'gasFileName':
|
||||||
|
currDataType = PHD_DATA_TYPE.GASBKPHD
|
||||||
|
break
|
||||||
|
case 'detFileName':
|
||||||
|
currDataType = PHD_DATA_TYPE.DETBKPHD
|
||||||
|
break
|
||||||
|
case 'qcFileName':
|
||||||
|
currDataType = PHD_DATA_TYPE.QCPHD
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return currDataType == dataType
|
||||||
|
},
|
||||||
|
|
||||||
onSearchFileName() {
|
onSearchFileName() {
|
||||||
this.getSpectrumFile({ pageNo: 1, pageSize: 10 })
|
this.getSpectrumFile({ pageNo: 1, pageSize: 10 })
|
||||||
},
|
},
|
||||||
|
@ -370,74 +595,93 @@ 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() {
|
||||||
this.visible = false
|
this.visible = false
|
||||||
},
|
},
|
||||||
},
|
|
||||||
computed: {
|
beforeModalOpen() {
|
||||||
visible: {
|
this.handleReset()
|
||||||
get() {
|
|
||||||
return this.value
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$emit('input', val)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -451,7 +695,7 @@ export default {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
|
|
||||||
background-color: #00e170;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
.status_true {
|
.status_true {
|
||||||
background-color: #00e170;
|
background-color: #00e170;
|
||||||
|
@ -525,6 +769,9 @@ export default {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
user-select: none;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
}
|
}
|
||||||
/deep/.ant-table-tbody .ant-table-row td {
|
/deep/.ant-table-tbody .ant-table-row td {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<div class="nuclide-library-settings">
|
<div class="nuclide-library-settings">
|
||||||
<div class="nuclide-library-settings-select">
|
<div class="nuclide-library-settings-select">
|
||||||
<title-over-border class="select-library" title="Select Library">
|
<title-over-border class="select-library" title="Select Library">
|
||||||
<a-radio-group v-model="model.libraryName" @change="handleSearch">
|
<a-radio-group v-model="model.libraryName" @change="handleChangeLibraryType">
|
||||||
<a-radio value="UserLibrary">User Library</a-radio>
|
<a-radio value="UserLibrary">User Library</a-radio>
|
||||||
<a-radio value="FULLLibrary">Full Library</a-radio>
|
<a-radio value="FULLLibrary">Full Library</a-radio>
|
||||||
<a-radio value="RelevantLibrary">Relevant Library</a-radio>
|
<a-radio value="RelevantLibrary">Relevant Library</a-radio>
|
||||||
|
@ -275,6 +275,12 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 修改Library类型
|
||||||
|
handleChangeLibraryType() {
|
||||||
|
this.model.nuclideName = ''
|
||||||
|
this.handleSearch()
|
||||||
|
},
|
||||||
|
|
||||||
// 搜索
|
// 搜索
|
||||||
handleSearch() {
|
handleSearch() {
|
||||||
this.getInfo(true)
|
this.getInfo(true)
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
<title-over-border title="Format">
|
<title-over-border title="Format">
|
||||||
<a-radio-group v-model="saveFormat" class="format-radio-group">
|
<a-radio-group v-model="saveFormat" class="format-radio-group">
|
||||||
<a-radio value="txt">Save as Txt</a-radio>
|
<a-radio value="txt">Save as Txt</a-radio>
|
||||||
<a-radio value="excel">Save as Excel</a-radio>
|
<a-radio value="xls">Save as Excel</a-radio>
|
||||||
|
<a-radio value="html">Save as Html</a-radio>
|
||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
</title-over-border>
|
</title-over-border>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,7 +20,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { downloadFile } from '../../../../api/manage'
|
|
||||||
import TitleOverBorder from '../TitleOverBorder.vue'
|
import TitleOverBorder from '../TitleOverBorder.vue'
|
||||||
export default {
|
export default {
|
||||||
components: { TitleOverBorder },
|
components: { TitleOverBorder },
|
||||||
|
@ -41,8 +41,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
handleOk() {
|
handleOk() {
|
||||||
console.log('%c [ save ]-22', 'font-size:13px; background:pink; color:#bf2c9f;')
|
this.$emit('save', this.saveFormat)
|
||||||
downloadFile('', 'result.' + this.saveFormat, {})
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -73,7 +72,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.format-radio-group {
|
.format-radio-group {
|
||||||
.ant-radio-wrapper:first-child {
|
.ant-radio-wrapper:not(:last-child) {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
<!-- Nuclide Activity and MDC 弹窗结束 -->
|
<!-- Nuclide Activity and MDC 弹窗结束 -->
|
||||||
|
|
||||||
<!-- Save Setting 弹窗开始 -->
|
<!-- Save Setting 弹窗开始 -->
|
||||||
<save-setting-modal v-model="saveSettingModalVisible" />
|
<save-setting-modal v-model="saveSettingModalVisible" @save="handleSaveResultsToFile" />
|
||||||
<!-- Save Setting 弹窗结束 -->
|
<!-- Save Setting 弹窗结束 -->
|
||||||
|
|
||||||
<!-- 分析-设置弹窗开始 -->
|
<!-- 分析-设置弹窗开始 -->
|
||||||
|
@ -156,10 +156,7 @@
|
||||||
<!-- Beta-Gamma 的Comments 结束 -->
|
<!-- Beta-Gamma 的Comments 结束 -->
|
||||||
|
|
||||||
<!-- Beta-Gamma 的Energy Calibration开始 -->
|
<!-- Beta-Gamma 的Energy Calibration开始 -->
|
||||||
<beta-gamma-energy-calibration-modal
|
<beta-gamma-energy-calibration-modal v-model="betaGammaEnergyCalibrationModalVisible" @sendInfo="getCheckFlag" />
|
||||||
v-model="betaGammaEnergyCalibrationModalVisible"
|
|
||||||
@sendInfo="getCheckFlag"
|
|
||||||
/>
|
|
||||||
<!-- Beta-Gamma 的Energy Calibration结束 -->
|
<!-- Beta-Gamma 的Energy Calibration结束 -->
|
||||||
|
|
||||||
<!-- Beta-Gamma 的 Extrapolation 弹窗开始 -->
|
<!-- Beta-Gamma 的 Extrapolation 弹窗开始 -->
|
||||||
|
@ -191,7 +188,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { postAction } from '@/api/manage'
|
import { downloadFile, postAction } from '@/api/manage'
|
||||||
import GammaAnalysis from './gamma-analysis.vue'
|
import GammaAnalysis from './gamma-analysis.vue'
|
||||||
import BetaGammaAnalysis from './beta-gamma-analysis.vue'
|
import BetaGammaAnalysis from './beta-gamma-analysis.vue'
|
||||||
import SpectraListInMenu from './components/SpectraListInMenu.vue'
|
import SpectraListInMenu from './components/SpectraListInMenu.vue'
|
||||||
|
@ -460,8 +457,31 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
// 保存结果到文件, 服务端生成文件,前端下载
|
// 保存结果到文件, 服务端生成文件,前端下载
|
||||||
handleSaveResultsToFile() {
|
async handleSaveResultsToFile(saveFormat) {
|
||||||
this.saveSettingModalVisible = true
|
const url =
|
||||||
|
saveFormat == 'xls'
|
||||||
|
? '/spectrumAnalysis/saveToExcel'
|
||||||
|
: saveFormat == 'txt'
|
||||||
|
? '/spectrumAnalysis/saveToTxt'
|
||||||
|
: saveFormat == 'html'
|
||||||
|
? '/spectrumAnalysis/saveToHTML'
|
||||||
|
: ''
|
||||||
|
if (!this.resultDisplayFlag) {
|
||||||
|
this.$message.warn('Please Analyse Spectrum First')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.resultDisplayFlag.forEach((item) => {
|
||||||
|
this.params_toDB[`${item.nuclideName.toLowerCase()}Flag`] = item.nidFlag
|
||||||
|
})
|
||||||
|
|
||||||
|
this.params_toDB.sampleFileName = this.newSampleData.inputFileName
|
||||||
|
this.params_toDB.gasFileName = this.newSampleData.gasFileName
|
||||||
|
this.params_toDB.detFileName = this.newSampleData.detFileName
|
||||||
|
this.params_toDB.qcFileName = this.newSampleData.qcFileName
|
||||||
|
this.params_toDB.dbName = this.newSampleData.dbName
|
||||||
|
|
||||||
|
downloadFile(url, `result.${saveFormat}`, this.params_toDB, 'post')
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -478,7 +498,7 @@ export default {
|
||||||
const hideLoading = this.$message.loading('Saving...', 0)
|
const hideLoading = this.$message.loading('Saving...', 0)
|
||||||
try {
|
try {
|
||||||
const { success, message } = await getAction('/gamma/saveToDB', {
|
const { success, message } = await getAction('/gamma/saveToDB', {
|
||||||
fileName: this.sampleData.inputFileName
|
fileName: this.sampleData.inputFileName,
|
||||||
})
|
})
|
||||||
if (success) {
|
if (success) {
|
||||||
this.$message.success('Save Success')
|
this.$message.success('Save Success')
|
||||||
|
@ -727,7 +747,7 @@ export default {
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
menuClick: () => {
|
menuClick: () => {
|
||||||
this.handleSaveResultsToFile()
|
this.saveSettingModalVisible = true
|
||||||
},
|
},
|
||||||
submenuClick: ({ item, child }) => {
|
submenuClick: ({ item, child }) => {
|
||||||
if (item.title == 'Save Results to DB') {
|
if (item.title == 'Save Results to DB') {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user