自建台站增加Reports和Log

This commit is contained in:
Xu Zhimeng 2024-08-12 16:49:19 +08:00
parent d82b894c0b
commit f7adc0f4fd
7 changed files with 753 additions and 13 deletions

View File

@ -98,6 +98,26 @@
<!-- Beta 按钮的弹窗 --> <!-- Beta 按钮的弹窗 -->
<beta-modal ref="betaModalRef" /> <beta-modal ref="betaModalRef" />
<!-- Beta 按钮的弹窗结束 --> <!-- Beta 按钮的弹窗结束 -->
<!-- Arr和RRR弹窗 -->
<self-station-arr-rrr-modal ref="ARR_RRRModalRef" />
<!-- Arr和RRR弹窗结束 -->
<!-- Spectrum弹窗 -->
<self-station-spectrum-modal ref="spectrumModalRef" />
<!-- Spectrum弹窗结束 -->
<!-- Peak Infomation弹窗 -->
<self-station-peak-infomation ref="peakInfoModalRef" />
<!-- Peak Infomation弹窗结束 -->
<!-- 自动分析日志弹窗 -->
<self-station-automatic-analysis-log-modal ref="autoAnalysisLogRef" />
<!-- 自动分析日志弹窗结束 -->
<!-- BgLog -->
<self-station-bg-log-viewer ref="bgLogViewerRef" />
<!-- BgLog结束 -->
</div> </div>
</template> </template>
@ -118,6 +138,11 @@ import { addSampleData, getSampleData, updateSampleData } from '@/utils/SampleSt
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import GammaModal from './components/Modals/SelfStation/GammaModal.vue' import GammaModal from './components/Modals/SelfStation/GammaModal.vue'
import BetaModal from './components/Modals/SelfStation/BetaModal.vue' import BetaModal from './components/Modals/SelfStation/BetaModal.vue'
import SelfStationArrRrrModal from './components/Modals/SelfStation/SelfStationArrRrrModal.vue'
import SelfStationSpectrumModal from './components/Modals/SelfStation/SelfStationSpectrumModal.vue'
import SelfStationPeakInfomation from './components/Modals/SelfStation/SelfStationPeakInfomation.vue'
import SelfStationAutomaticAnalysisLogModal from './components/Modals/SelfStation/SelfStationAutomaticAnalysisLogModal.vue'
import SelfStationBgLogViewer from './components/Modals/SelfStation/SelfStationBGLogViewer.vue'
const SampleType = [ const SampleType = [
{ {
@ -151,6 +176,11 @@ export default {
RoiParam, RoiParam,
GammaModal, GammaModal,
BetaModal, BetaModal,
SelfStationArrRrrModal,
SelfStationSpectrumModal,
SelfStationPeakInfomation,
SelfStationAutomaticAnalysisLogModal,
SelfStationBgLogViewer,
}, },
props: { props: {
sample: { sample: {
@ -303,6 +333,7 @@ export default {
this.isLoading = false this.isLoading = false
} }
}, },
getAnalyzeAllSpectrum() { getAnalyzeAllSpectrum() {
let XeData = [ let XeData = [
{ {
@ -357,6 +388,7 @@ export default {
this.resultDisplay = XeData this.resultDisplay = XeData
// this.$emit('reAnalyCurr', true, XeData) // this.$emit('reAnalyCurr', true, XeData)
}, },
// Update // Update
async handleUpdate() { async handleUpdate() {
const hasEmpty = this.roiParamList.some( const hasEmpty = this.roiParamList.some(
@ -394,7 +426,7 @@ export default {
for (let index = 0; index < 4; index++) { for (let index = 0; index < 4; index++) {
const key = `ROI${index + 1}` const key = `ROI${index + 1}`
const value = result[key] const value = result[key]
if(value) { if (value) {
this.$set(this.ROIAnalyzeLists, index, value) this.$set(this.ROIAnalyzeLists, index, value)
} }
} }
@ -431,17 +463,7 @@ export default {
this.isLoading = false this.isLoading = false
} }
}, },
// async handleDetalSelfStationCache() {
// const { inputFileName } = this.sample
// let params = {
// sampleFileName: inputFileName,
// }
// try {
// const { success, result, message } = await deleteAction('/selfStation/deleteSelfStationCache', params)
// } catch (error) {
// console.error(error)
// }
// },
async getSelfStationSampleDetail() { async getSelfStationSampleDetail() {
this.spectraType = this.SampleType[0].value this.spectraType = this.SampleType[0].value
const { inputFileName, detFileName, qcFileName } = this.sample const { inputFileName, detFileName, qcFileName } = this.sample
@ -468,11 +490,56 @@ export default {
this.isLoading = false this.isLoading = false
} else { } else {
this.$message.error(message) this.$message.error(message)
this.isLoading = false
} }
} catch (error) { } catch (error) {
console.error(error) console.error(error)
const isCancel = axios.isCancel(error)
if (!isCancel) {
this.isLoading = false
}
} }
}, },
//
async getSampleDetail() {
const { dbName, sampleId, analyst, inputFileName } = this.sample
try {
this.cancelLastRequest()
this.isLoading = true
const cancelToken = this.createCancelToken()
const { success, result, message } = await getAction(
'/selfStation/loadFromDB',
{
dbName,
sampleId,
analyst,
},
cancelToken
)
if (success) {
addSampleData({
inputFileName,
data: result,
from: 'db',
})
this.sampleDetail = result
this.changeChartByType('sample')
this.isLoading = false
} else {
this.$message.error(message)
this.isLoading = false
}
} catch (error) {
console.error(error)
const isCancel = axios.isCancel(error)
if (!isCancel) {
this.isLoading = false
}
}
},
changeChartByType(val) { changeChartByType(val) {
const currSampleDetail = this.sampleDetail[this.spectraType] const currSampleDetail = this.sampleDetail[this.spectraType]
if (!currSampleDetail) { if (!currSampleDetail) {
@ -643,6 +710,27 @@ export default {
throw new Error(message) throw new Error(message)
} }
}, },
// ARRRRR
showArrRRRModal(type) {
this.$refs.ARR_RRRModalRef.show(type)
},
showSpectrumModal() {
this.$refs.spectrumModalRef.show()
},
showPeakInfoModal() {
this.$refs.peakInfoModalRef.show()
},
showAutomaticAnalysisLog() {
this.$refs.autoAnalysisLogRef.show()
},
showBgLogViewer() {
this.$refs.bgLogViewerRef.show()
},
}, },
} }
</script> </script>

View File

@ -0,0 +1,129 @@
<template>
<custom-modal v-model="visible" :width="1200" :title="type == 1 || type == 3 ? 'ARR' : 'RRR'">
<a-spin :spinning="isLoading">
<a-tabs :animated="false" v-model="activeTab">
<a-tab-pane v-for="(title, index) in tabTitles" :tab="title" :key="index">
<a-textarea style="font-family: 仿宋" v-model="resultTxtArr[index]"></a-textarea>
</a-tab-pane>
</a-tabs>
</a-spin>
<div slot="custom-footer" style="text-align: center">
<a-space :size="20">
<a-button type="primary" @click="handleOk">Export</a-button>
<a-button @click="visible = false">Cancel</a-button>
</a-space>
</div>
</custom-modal>
</template>
<script>
import { getAction, postAction } from '@/api/manage'
import { saveAs } from 'file-saver'
import SampleDataMixin from '../../../SampleDataMixin'
import { getSampleData } from '@/utils/SampleStore'
//
const keyMapping = ['Beta', 'Gamma_ROI_1', 'Gamma_ROI_2', 'Gamma_ROI_3', 'Gamma_ROI_4']
const tabTitles = ['Beta', 'ROI_1', 'ROI_2', 'ROI_3', 'ROI_4']
export default {
mixins: [SampleDataMixin],
data() {
this.tabTitles = tabTitles
return {
resultTxtArr: [], //
isLoading: true,
type: 0,
visible: false,
activeTab: 0,
}
},
methods: {
async getContent() {
try {
this.resultTxtArr = []
this.isLoading = true
const { sampleId, inputFileName: fileName, dbName, detFileName, gasFileName, qcFileName } = this.newSampleData
let request = getAction,
url = '/selfStation/viewARR',
params = {
sampleId,
}
if (this.type == 2) {
url = '/selfStation/viewRRR'
params = {
dbName,
sampleId,
sampleData: false,
gasBgData: false,
detBgData: false,
qcData: false,
sampleFileName: fileName,
gasFileName,
detFileName,
qcFileName,
}
request = postAction
}
const { success, result, message } = await request(url, params)
if (success) {
this.resultTxtArr = keyMapping.map((k) => result[k])
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
} finally {
this.isLoading = false
}
},
show(type) {
if (type == 1 && !this.newSampleData.sampleId) {
this.$message.warning("The file isn't existed.")
return
}
if (type == 2) {
const sampleDetail = getSampleData(this.sampleData.inputFileName)
if (sampleDetail && !sampleDetail.data.ROIAnalyzeLists) {
this.$message.warning('Please analyze the spectrum first!')
return
}
}
this.type = type
this.activeTab = 0
this.visible = true
this.getContent()
},
handleOk() {
const text = this.resultTxtArr[this.activeTab]
if (text) {
const name = this.newSampleData.inputFileName.split('.')[0]
const strData = new Blob([text], { type: 'text/plain;charset=utf-8' })
const title = this.tabTitles[this.activeTab]
if (this.type == 1) {
saveAs(strData, `ARR_${name}_${title}.txt`)
} else {
saveAs(strData, `RRR_${name}_${title}.txt`)
}
} else {
this.$message.warning('No data can be saved!')
}
},
},
}
</script>
<style lang="less" scoped>
textarea {
height: calc(100vh - 350px);
padding: 5px;
overflow: auto;
background-color: #285367;
}
</style>

View File

@ -0,0 +1,94 @@
<template>
<custom-modal v-model="visible" :width="1000" title="Auto Process Log Viewer">
<a-spin :spinning="isLoading">
<a-tabs :animated="false" v-model="activeTab">
<a-tab-pane v-for="(title, index) in tabTitles" :tab="title" :key="index">
<pre style="font-family: 仿宋">
{{ resultTxtArr[index] }}
</pre>
</a-tab-pane>
</a-tabs>
</a-spin>
<div slot="custom-footer" style="text-align: center">
<a-space :size="20">
<a-button type="primary" @click="handleOk">Save</a-button>
<a-button @click="visible = false">Cancel</a-button>
</a-space>
</div>
</custom-modal>
</template>
<script>
import { getAction } from '@/api/manage'
import SampleDataMixin from '@/views/spectrumAnalysis/SampleDataMixin'
import { saveAs } from 'file-saver'
//
const keyMapping = ['Beta', 'Gamma_ROI_1', 'Gamma_ROI_2', 'Gamma_ROI_3', 'Gamma_ROI_4']
const tabTitles = ['Beta', 'ROI_1', 'ROI_2', 'ROI_3', 'ROI_4']
export default {
mixins: [SampleDataMixin],
data() {
this.tabTitles = tabTitles
return {
isLoading: false,
visible: false,
resultTxtArr: [],
activeTab: 0,
}
},
methods: {
async getInfo() {
try {
this.isLoading = true
const { sampleId, sampleFileName } = this.sampleData
const { success, result, message } = await getAction('/selfStation/viewAutomaticAnalysisLog', {
sampleId,
sampleFileName,
})
if (success) {
this.resultTxtArr = keyMapping.map((k) => result[k])
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
} finally {
this.isLoading = false
}
},
show() {
if (!this.sampleData.sampleId) {
this.$message.warning("The file isn't existed.")
return
}
this.activeTab = 0
this.resultTxtArr = []
this.visible = true
this.getInfo()
},
handleOk() {
const text = this.resultTxtArr[this.activeTab]
if (text) {
const name = this.newSampleData.inputFileName.split('.')[0]
const strData = new Blob([text], { type: 'text/plain;charset=utf-8' })
saveAs(strData, `${name}_Automatic Analysis Log.txt`)
} else {
this.$message.warning('No data can be saved!')
}
},
},
}
</script>
<style lang="less" scoped>
pre {
height: 450px;
padding: 5px;
overflow: auto;
background-color: #285367;
}
</style>

View File

@ -0,0 +1,99 @@
<template>
<custom-modal v-model="visible" title="BetaGamma Analyser Log" :width="1200">
<a-spin :spinning="isLoading">
<a-tabs :animated="false" v-model="activeTab">
<a-tab-pane v-for="(title, index) in tabTitles" :tab="title" :key="index">
<a-textarea v-model="resultTxtArr[index]" style="font-family: 仿宋"></a-textarea>
</a-tab-pane>
</a-tabs>
</a-spin>
<div slot="custom-footer">
<a-button type="primary" @click="handleClick">Save As</a-button>
</div>
</custom-modal>
</template>
<script>
import { getAction } from '@/api/manage'
import { getSampleData } from '@/utils/SampleStore'
import SampleDataMixin from '@/views/spectrumAnalysis/SampleDataMixin'
import { saveAs } from 'file-saver'
//
const keyMapping = ['Beta', 'Gamma_ROI_1', 'Gamma_ROI_2', 'Gamma_ROI_3', 'Gamma_ROI_4']
const tabTitles = ['Beta', 'ROI_1', 'ROI_2', 'ROI_3', 'ROI_4']
export default {
mixins: [SampleDataMixin],
data() {
this.tabTitles = tabTitles
return {
isLoading: false,
visible: false,
resultTxtArr: [],
activeTab: 0,
}
},
methods: {
async getDetail() {
try {
this.isLoading = true
const {
dbName,
sampleId,
inputFileName: sampleFileName,
gasFileName,
detFileName,
qcFileName,
} = this.newSampleData
const { success, result, message } = await getAction('/selfStation/viewBGLogViewer', {
dbName,
sampleId,
sampleFileName,
gasFileName,
detFileName,
qcFileName,
})
if (success) {
this.resultTxtArr = keyMapping.map((k) => result[k])
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
} finally {
this.isLoading = false
}
},
show() {
this.getDetail()
this.resultTxtArr = []
this.activeTab = 0
this.visible = true
},
handleClick() {
const text = this.resultTxtArr[this.activeTab]
if (text) {
const name = this.newSampleData.inputFileName.split('.')[0]
const blob = new Blob([text], { type: 'text/plain' })
const title = this.tabTitles[this.activeTab]
saveAs(blob, `${name}_beta ${title} analysis log.txt`)
} else {
this.$message.warning('No data can be saved!')
}
},
},
}
</script>
<style lang="less" scoped>
textarea {
height: calc(100vh - 350px);
padding: 5px;
overflow: auto;
background-color: #285367;
}
</style>

View File

@ -0,0 +1,179 @@
<template>
<custom-modal v-model="visible" title="Peak Infomation" :width="1231" :footer="null" class="peak-infomation">
<a-spin :spinning="isLoading">
<a-tabs :animated="false" v-model="activeTab">
<a-tab-pane v-for="(title, index) in tabTitles" :tab="title" :key="index">
<custom-table :columns="columns" :list="list[index]" :scroll="{ y: 460 }" :canSelect="false"></custom-table>
</a-tab-pane>
</a-tabs>
</a-spin>
<!-- 底部按钮 -->
<div class="peak-infomation-footer">
<a-space :size="20">
<a-button type="primary" @click="handleExportToExcel">
<img src="@/assets/images/spectrum/download.png" />
Export to Excel
</a-button>
</a-space>
</div>
</custom-modal>
</template>
<script>
import { getAction, getFileAction } from '@/api/manage'
import { saveAs } from 'file-saver'
import SampleDataMixin from '../../../SampleDataMixin'
const columns = [
{
title: 'Index',
dataIndex: 'index',
align: 'center',
customRender: (_, __, index) => {
return index + 1
},
},
{
title: 'Energy(keV)',
dataIndex: 'energy',
},
{
title: 'Centroid',
dataIndex: 'centroid',
},
{
title: 'Multiplet',
dataIndex: 'multiplet',
},
{
title: 'Fwhm(keV)',
dataIndex: 'fwhm',
},
{
title: 'NetArea',
dataIndex: 'netArea',
ellipsis: true,
},
{
title: 'AreaErr(%)',
dataIndex: 'areaErr',
ellipsis: true,
},
{
title: 'Significant',
dataIndex: 'significant',
},
{
title: 'Sensitivity',
dataIndex: 'sensitivity',
},
{
title: 'Indentify',
dataIndex: 'indentify',
ellipsis: true,
},
]
//
const keyMapping = ['Gamma_ROI_1', 'Gamma_ROI_2', 'Gamma_ROI_3', 'Gamma_ROI_4']
const tabTitles = ['ROI_1', 'ROI_2', 'ROI_3', 'ROI_4']
export default {
mixins: [SampleDataMixin],
data() {
this.columns = columns
this.tabTitles = tabTitles
return {
visible: false,
activeTab: 0,
list: [],
isLoading: false,
fileName: '',
}
},
methods: {
async getInfo() {
try {
this.isLoading = true
const { sampleFileName } = this.sampleData
const { success, result, message } = await getAction('/selfStation/peakInformation', {
sampleFileName,
})
if (success) {
this.list = keyMapping.map((k) => result[k])
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
} finally {
this.isLoading = false
}
},
show() {
this.getInfo()
this.activeTab = 0
this.visible = true
},
// Excel
handleExportToExcel() {
this.fileName = ''
const { sampleFileName } = this.sampleData
if (this.list.length > 0) {
const name = this.newSampleData.inputFileName.split('.')[0]
getFileAction('/selfStation/exportPeakInformation', {
sampleFileName,
}).then((res) => {
if (res.code && res.code == 500) {
this.$message.warning('This operation fails. Contact your system administrator')
} else {
const blob = new Blob([res], { type: 'application/vnd.ms-excel' })
saveAs(blob, `${name}_Peak Infomation`)
}
})
} else {
this.$message.warning('No downloadable data')
}
},
},
}
</script>
<style lang="less" scoped>
.peak-infomation {
::v-deep {
.ant-modal-body {
padding: 20px 16px 16px;
}
}
&-footer {
margin-top: 10px;
text-align: right;
.ant-btn {
display: flex;
align-items: center;
img {
margin-right: 10px;
}
}
}
}
.comparison-list {
&-item {
&-title {
color: #0cebc9;
}
&:last-child {
margin-top: 12px;
}
}
}
</style>

View File

@ -0,0 +1,99 @@
<template>
<custom-modal v-model="visible" :width="1200" title="View Spectrum" destroyOnClose @cancel="handleCancel">
<a-spin :spinning="isLoading">
<a-tabs :animated="false" v-model="currTab">
<a-tab-pane v-for="(title, index) in tabTitles" :tab="title" :key="index">
<a-textarea v-model="resultTxtArr[index]" style="font-family: 仿宋"></a-textarea>
</a-tab-pane>
</a-tabs>
</a-spin>
<div slot="custom-footer">
<a-space :size="20">
<a-button type="primary" @click="handleOk">Save Text</a-button>
<a-button @click="handleCancel">Cancel</a-button>
</a-space>
</div>
</custom-modal>
</template>
<script>
import { getAction } from '../../../../../api/manage'
import SampleDataMixin from '@/views/spectrumAnalysis/SampleDataMixin'
//
const keyMapping = ['sample', 'detBg', 'qc', 'Gamma_ROI_1', 'Gamma_ROI_2', 'Gamma_ROI_3', 'Gamma_ROI_4']
const tabTitles = [
'Sample Spectrum',
'DetBg Spectrum',
'Qc Spectrum',
// 'ROI_1 Spectrum',
// 'ROI_2 Spectrum',
// 'ROI_3 Spectrum',
// 'ROI_4 Spectrum',
]
export default {
mixins: [SampleDataMixin],
data() {
this.tabTitles = tabTitles
return {
visible: false,
resultTxtArr: [],
isLoading: true,
currTab: 0,
}
},
methods: {
async getContent() {
try {
this.currTab = 0
this.resultTxtArr = []
this.isLoading = true
const { inputFileName: fileName } = this.newSampleData
const { success, result, message } = await getAction('/selfStation/viewSpectrum', {
fileName,
})
if (success) {
this.resultTxtArr = keyMapping.map((k) => (result[k] ? result[k].join('\n') : ''))
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
} finally {
this.isLoading = false
}
},
show() {
this.visible = true
this.getContent()
},
handleOk() {
const text = this.resultTxtArr[this.currTab]
if (text) {
let name = this.newSampleData.inputFileName.split('.')[0]
let strData = new Blob([text], { type: 'text/plain;charset=utf-8' })
saveAs(strData, `${name}_${tabTitles[this.currTab]} Spectrum.txt`)
} else {
this.$message.warning('No data can be saved!')
}
},
handleCancel() {
this.currTab = 1
this.visible = false
},
},
}
</script>
<style lang="less" scoped>
textarea {
height: calc(100vh - 350px);
padding: 5px;
overflow: auto;
background-color: #285367;
}
</style>

View File

@ -879,7 +879,7 @@ export default {
} }
this.$message.success('Save Success') this.$message.success('Save Success')
} catch (error) { } catch (error) {
this.$message.error(error && (error.message || error)) this.$message.warning(error && (error.message || error))
} finally { } finally {
hideLoading() hideLoading()
this.isSaving = false this.isSaving = false
@ -1765,6 +1765,40 @@ export default {
handler: () => (this.betaGammaXeModalVisible = true), handler: () => (this.betaGammaXeModalVisible = true),
show: this.isBetaGamma, show: this.isBetaGamma,
}, },
//
{
type: 'a-menu-item',
title: 'View ARR',
show: this.isBeta,
handler: () => {
this.$refs.betaAnalysisRef.showArrRRRModal(1)
},
},
{
type: 'a-menu-item',
title: 'View RRR',
show: this.isBeta,
handler: () => {
this.$refs.betaAnalysisRef.showArrRRRModal(2)
},
},
{
type: 'a-menu-item',
title: 'View spectrum',
handler: () => {
this.$refs.betaAnalysisRef.showSpectrumModal()
},
show: this.isBeta,
},
{
type: 'a-menu-item',
title: 'Peak Infomation',
handler: () => {
this.$refs.betaAnalysisRef.showPeakInfoModal()
},
show: this.isBeta,
},
], ],
}, },
], ],
@ -1806,6 +1840,24 @@ export default {
show: this.isGamma, show: this.isGamma,
handler: () => (this.dataProcessingLogModalVisible = true), handler: () => (this.dataProcessingLogModalVisible = true),
}, },
//
{
type: 'a-menu-item',
title: 'Automatic Analysis Log',
show: this.isBeta,
handler: () => {
this.$refs.betaAnalysisRef.showAutomaticAnalysisLog()
},
},
{
type: 'a-menu-item',
title: 'BG log viewer',
show: this.isBeta,
handler: () => {
this.$refs.betaAnalysisRef.showBgLogViewer()
},
},
], ],
}, },
], ],