Merge branch 'feature/spectrum-analysis' of http://git.hivekion.com:3000/xiaoguangbin/AnalysisSystemForRadionuclide_vue into feature-analysis-RLR-renpy

This commit is contained in:
renpy 2023-09-05 14:26:55 +08:00
commit 595e71c2f4
12 changed files with 617 additions and 443 deletions

View File

@ -89,3 +89,8 @@ export function buildLineSeries(name, data, color, extra = {}) {
...extra ...extra
} }
} }
// 根据name查找series
export function findSeriesByName(series, seriesName) {
return series.find(item => item.name == seriesName)
}

View File

@ -0,0 +1,8 @@
export default {
inject: ['sample'],
computed: {
sampleData() {
return this.sample()
}
}
}

View File

@ -11,7 +11,7 @@
<div slot="custom-footer"> <div slot="custom-footer">
<a-space> <a-space>
<a-button type="primary" @click="handlePeaks">Peaks</a-button> <a-button type="primary" @click="handlePeaks">Peaks</a-button>
<a-button>Cancel</a-button> <a-button @click="visible = false">Cancel</a-button>
</a-space> </a-space>
</div> </div>
</custom-modal> </custom-modal>

View File

@ -2,6 +2,7 @@
<custom-chart :option="option" /> <custom-chart :option="option" />
</template> </template>
<script> <script>
import { cloneDeep } from 'lodash'
import CustomChart from '@/components/CustomChart/index.vue' import CustomChart from '@/components/CustomChart/index.vue'
const initialOption = { const initialOption = {
grid: { grid: {
@ -20,9 +21,6 @@ const initialOption = {
bottom: 5 bottom: 5
}, },
xAxis: { xAxis: {
min: 620.68,
max: 629.16,
splitNumber: 3,
axisLine: { axisLine: {
lineStyle: { lineStyle: {
color: '#fff' color: '#fff'
@ -33,12 +31,12 @@ const initialOption = {
}, },
axisLabel: { axisLabel: {
color: '#fff' color: '#fff'
} },
min: 'dataMin',
max: 'dataMax',
animation: false
}, },
yAxis: { yAxis: {
min: 417,
max: 327,
interval: 90,
axisLine: { axisLine: {
lineStyle: { lineStyle: {
color: '#fff' color: '#fff'
@ -57,30 +55,48 @@ const initialOption = {
nameTextStyle: { nameTextStyle: {
color: '#8FD4F8', color: '#8FD4F8',
fontSize: 14 fontSize: 14
},
animation: false
},
series: []
}
export default {
components: {
CustomChart
},
props: {
data: {
type: Object,
default: () => ({})
} }
}, },
series: [ data() {
{ return {
option: cloneDeep(initialOption)
}
},
watch: {
data: {
handler() {
const { chartData, selPos } = this.data
const series = []
chartData.forEach(({ pointlist, color }) => {
series.push({
type: 'line', type: 'line',
data: [ data: pointlist.map(({ x, y }) => [x, y]),
[620.68, 410],
[621.98, 390],
[622.12, 337],
[623.53, 400],
[624.37, 410],
[625.37, 410],
[626.37, 410],
[627.37, 410],
[628.37, 410]
],
itemStyle: { itemStyle: {
color: '#8BB93C' color: `rgb(${color})`
}, },
symbol: 'none', symbol: 'none',
markLine: { animation: false
})
})
series[0].markLine = {
data: [ data: [
{ {
xAxis: 625.14, xAxis: selPos,
label: { label: {
formatter: '{c} keV', formatter: '{c} keV',
color: '#f00', color: '#f00',
@ -92,36 +108,15 @@ const initialOption = {
symbol: 'none', symbol: 'none',
lineStyle: { lineStyle: {
color: '#f00' color: '#f00'
},
emphasis: {
disabled: true
} }
} }
this.option.series = series
}, },
{ immediate: true
type: 'line',
data: [
[620.68, 367],
[622, 367],
[623, 367],
[624, 367],
[625, 367],
[626, 367],
[627, 367],
[628, 367],
[629, 367]
],
itemStyle: {
color: '#8FD4F8'
},
symbol: 'none'
}
]
}
export default {
components: {
CustomChart
},
data() {
return {
option: initialOption
} }
} }
} }

View File

@ -1,13 +1,14 @@
<template> <template>
<custom-modal v-model="visible" :width="1200" title="Nuclide Review" :footer="null"> <custom-modal v-model="visible" :width="1200" title="Nuclide Review" :footer="null" destroy-on-close>
<a-spin :spinning="isLoading">
<div class="nuclide-review-search"> <div class="nuclide-review-search">
<span @click="handleNuclideChange('prev')">&lt;</span> <span @click="handleNuclideChange('prev')">&lt;</span>
<a-form-model layout="inline"> <a-form-model layout="inline">
<a-form-model-item label="Energy"> <a-form-model-item label="Energy">
<a-input-number></a-input-number> <a-input-number v-model="model.energy"></a-input-number>
</a-form-model-item> </a-form-model-item>
<a-form-model-item label="Tolerance"> <a-form-model-item label="Tolerance">
<a-input-number></a-input-number> <a-input-number v-model="model.tolerance"></a-input-number>
</a-form-model-item> </a-form-model-item>
<a-button type="primary">Search</a-button> <a-button type="primary">Search</a-button>
</a-form-model> </a-form-model>
@ -23,10 +24,10 @@
class="nuclide-review-table-nuclide-item" class="nuclide-review-table-nuclide-item"
:class="currNuclide == item ? 'active' : ''" :class="currNuclide == item ? 'active' : ''"
v-for="(item, index) in nuclideList" v-for="(item, index) in nuclideList"
:key="item.id" :key="item"
@click="handleNuclideClick(index)" @click="handleNuclideClick(index)"
> >
{{ item.title }} {{ item }}
</div> </div>
</div> </div>
</div> </div>
@ -36,22 +37,22 @@
<a-row> <a-row>
<a-col :span="6"> <a-col :span="6">
<a-form-model-item label="Name"> <a-form-model-item label="Name">
{{ currNuclide.title }} {{ info.name }}
</a-form-model-item> </a-form-model-item>
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
<a-form-model-item label="Half Life"> <a-form-model-item label="Half Life">
2 {{ info.halfLife }}
</a-form-model-item> </a-form-model-item>
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
<a-form-model-item label="Half Life Err"> <a-form-model-item label="Half Life Err">
3 {{ info.halfLifeErr }}
</a-form-model-item> </a-form-model-item>
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
<a-form-model-item label="Lines"> <a-form-model-item label="Lines">
4 {{ info.lines }}
</a-form-model-item> </a-form-model-item>
</a-col> </a-col>
</a-row> </a-row>
@ -64,7 +65,11 @@
:scroll="{ y: 180 }" :scroll="{ y: 180 }"
:customRow="customRow" :customRow="customRow"
:pagination="false" :pagination="false"
/> >
<template slot="keyLine" slot-scope="text">
<span v-if="text == 1" class="green-check-mark"> </span>
</template>
</a-table>
</div> </div>
</div> </div>
<!-- 表格部分结束 --> <!-- 表格部分结束 -->
@ -78,11 +83,14 @@
</div> </div>
<a-row class="nuclide-review-chart-list"> <a-row class="nuclide-review-chart-list">
<a-col class="nuclide-review-chart-item" :span="8" v-for="(chartItem, index) in currChartList" :key="index"> <a-col class="nuclide-review-chart-item" :span="8" v-for="(chartItem, index) in currChartList" :key="index">
<p>Line{{ chartItem.id }}</p> <p>{{ chartItem.title }}</p>
<div class="nuclide-review-chart-item-chart" :class="currTableItem.id == chartItem.id ? 'active' : ''"> <div
<nuclide-review-chart /> class="nuclide-review-chart-item-chart"
:class="currSelectedTableIndex == chartItem._index ? 'active' : ''"
>
<nuclide-review-chart :data="chartItem" />
</div> </div>
<p>Abundance: {{ chartItem.abundance }}</p> <p>{{ chartItem.bottom }}</p>
</a-col> </a-col>
</a-row> </a-row>
<div class="nuclide-review-chart-next"> <div class="nuclide-review-chart-next">
@ -92,16 +100,23 @@
</div> </div>
</div> </div>
<!-- 图表部分结束 --> <!-- 图表部分结束 -->
</a-spin>
</custom-modal> </custom-modal>
</template> </template>
<script> <script>
import { getAction } from '@/api/manage'
import NuclideReviewChart from './NuclideReviewChart.vue' import NuclideReviewChart from './NuclideReviewChart.vue'
import ModalMixin from '@/mixins/ModalMixin'
import SampleDataMixin from '@/views/spectrumAnalysis/SampleDataMixin'
const columns = [ const columns = [
{ {
title: 'Id', title: 'Id',
dataIndex: 'id', width: '5%',
width: '5%' customRender: (_, __, index) => {
return index + 1
}
}, },
{ {
title: 'Full Name', title: 'Full Name',
@ -115,193 +130,51 @@ const columns = [
}, },
{ {
title: 'Energy Err', title: 'Energy Err',
dataIndex: 'energyErr', dataIndex: 'energyUncert',
width: '15%' width: '15%'
}, },
{ {
title: 'Abundance(%)', title: 'Abundance(%)',
dataIndex: 'abundance', dataIndex: 'yield',
width: '15%' width: '15%'
}, },
{ {
title: 'Abundance Err(%)', title: 'Abundance Err(%)',
dataIndex: 'abundanceErr', dataIndex: 'yieldUncert',
width: '15%' width: '15%'
}, },
{ {
title: 'KeyLine', title: 'KeyLine',
dataIndex: 'keyLine', dataIndex: 'keyFlag',
width: '15%' width: '15%',
align: 'center',
scopedSlots: {
customRender: 'keyLine'
}
} }
] ]
export default { export default {
components: { NuclideReviewChart }, components: { NuclideReviewChart },
mixins: [ModalMixin, SampleDataMixin],
props: { props: {
value: { channel: {
type: Boolean type: Number
} }
}, },
data() { data() {
this.columns = columns this.columns = columns
return { return {
nuclideList: [ nuclideList: [],
{
id: 1,
title: 'Ag111',
data: [
{
id: '1',
fullName: 'fullName',
energy: 'energy',
energyErr: 'energyErr',
abundance: 'abundance',
abundanceErr: 'abundanceErr',
keyLine: 'keyLine'
}
]
},
{
id: 2,
title: 'Eu157',
data: [
{
id: '1',
fullName: 'fullName',
energy: 'energy',
energyErr: 'energyErr',
abundance: 'abundance',
abundanceErr: 'abundanceErr',
keyLine: 'keyLine'
},
{
id: '2',
fullName: 'fullName',
energy: 'energy',
energyErr: 'energyErr',
abundance: 'abundance',
abundanceErr: 'abundanceErr',
keyLine: 'keyLine'
}
]
},
{
id: 3,
title: 'Mo99',
data: [
{
id: '1',
fullName: 'fullName',
energy: 'energy',
energyErr: 'energyErr',
abundance: 'abundance',
abundanceErr: 'abundanceErr',
keyLine: 'keyLine'
},
{
id: '2',
fullName: 'fullName',
energy: 'energy',
energyErr: 'energyErr',
abundance: 'abundance',
abundanceErr: 'abundanceErr',
keyLine: 'keyLine'
},
{
id: '3',
fullName: 'fullName',
energy: 'energy',
energyErr: 'energyErr',
abundance: 'abundance',
abundanceErr: 'abundanceErr',
keyLine: 'keyLine'
}
]
},
{
id: 4,
title: 'Pb204M',
data: [
{
id: '1',
fullName: 'fullName',
energy: 'energy',
energyErr: 'energyErr',
abundance: 'abundance',
abundanceErr: 'abundanceErr',
keyLine: 'keyLine'
},
{
id: '2',
fullName: 'fullName',
energy: 'energy',
energyErr: 'energyErr',
abundance: 'abundance',
abundanceErr: 'abundanceErr',
keyLine: 'keyLine'
},
{
id: '3',
fullName: 'fullName',
energy: 'energy',
energyErr: 'energyErr',
abundance: 'abundance',
abundanceErr: 'abundanceErr',
keyLine: 'keyLine'
},
{
id: '4',
fullName: 'fullName',
energy: 'energy',
energyErr: 'energyErr',
abundance: 'abundance',
abundanceErr: 'abundanceErr',
keyLine: 'keyLine'
},
{
id: '5',
fullName: 'fullName',
energy: 'energy',
energyErr: 'energyErr',
abundance: 'abundance',
abundanceErr: 'abundanceErr',
keyLine: 'keyLine'
},
{
id: '6',
fullName: 'fullName',
energy: 'energy',
energyErr: 'energyErr',
abundance: 'abundance',
abundanceErr: 'abundanceErr',
keyLine: 'keyLine'
},
{
id: '7',
fullName: 'fullName',
energy: 'energy',
energyErr: 'energyErr',
abundance: 'abundance',
abundanceErr: 'abundanceErr',
keyLine: 'keyLine'
},
{
id: '8',
fullName: 'fullName',
energy: 'energy',
energyErr: 'energyErr',
abundance: 'abundance',
abundanceErr: 'abundanceErr',
keyLine: 'keyLine'
}
]
}
],
list: [], // list: [], //
currNuclide: {}, currNuclide: '',
currTableItem: {}, // currSelectedTableIndex: 0, //
currChartList: [] // ,3 chartList: [],
currChartList: [], // ,3
model: {},
info: {}
} }
}, },
methods: { methods: {
@ -315,16 +188,14 @@ export default {
} }
}, },
//
handleNuclideClick(index) { handleNuclideClick(index) {
this.currNuclide = this.nuclideList[index] this.currNuclide = this.nuclideList[index]
this.list = this.currNuclide.data this.getInfoByNuclide()
this.selectTableRow(0)
}, },
selectTableRow(index) { selectTableRow(index) {
const record = this.list[index] this.currSelectedTableIndex = index
this.currTableItem = record
let startIndex = 0 let startIndex = 0
let endIndex = 0 let endIndex = 0
@ -342,27 +213,24 @@ export default {
if (startIndex < 0) { if (startIndex < 0) {
startIndex = 0 startIndex = 0
} }
this.currChartList = this.list.slice(startIndex, endIndex) this.currChartList = this.chartList.slice(startIndex, endIndex)
}, },
// / // /
handleChangeChart(direction) { handleChangeChart(direction) {
const currIndex = this.list.findIndex(item => item == this.currTableItem) const currIndex = this.currSelectedTableIndex
if (direction == 'prev') { if (direction == 'prev') {
const willJumpIndex = currIndex - 3 const willJumpIndex = currIndex - 3
if (willJumpIndex >= 0) { if (willJumpIndex >= 0) {
this.selectTableRow(willJumpIndex) this.selectTableRow(willJumpIndex)
} } else {
else {
this.selectTableRow(0) this.selectTableRow(0)
} }
} } else if (direction == 'next') {
else if (direction == 'next') {
const willJumpIndex = currIndex + 3 const willJumpIndex = currIndex + 3
if (willJumpIndex <= this.list.length - 2) { if (willJumpIndex <= this.list.length - 2) {
this.selectTableRow(willJumpIndex) this.selectTableRow(willJumpIndex)
} } else {
else {
this.selectTableRow(this.list.length - 1) this.selectTableRow(this.list.length - 1)
} }
} }
@ -371,26 +239,96 @@ export default {
// / // /
customRow(record, index) { customRow(record, index) {
return { return {
class: 'custom-table-row' + (this.currTableItem == record ? ' ant-table-row-selected' : ''), class: 'custom-table-row' + (this.currSelectedTableIndex == index ? ' ant-table-row-selected' : ''),
on: { on: {
click: () => { click: () => {
this.selectTableRow(index) this.selectTableRow(index)
} }
} }
} }
},
//
async getInfo() {
try {
this.isLoading = true
const { sampleId, inputFileName } = this.sampleData
const { success, result, message } = await getAction('/gamma/nuclideReview', {
sampleId: sampleId,
channel: this.channel,
fileName: inputFileName
})
if (success) {
const { chart, energy, halfLife, halfLifeErr, lines, list, name, table } = result
this.model = {
energy,
tolerance: 0.5
}
this.info = {
halfLife,
halfLifeErr,
lines,
name
}
this.list = table
this.nuclideList = list
chart.forEach((chartItem, index) => (chartItem._index = index))
this.chartList = chart
this.currNuclide = this.nuclideList[0]
this.selectTableRow(table.length > 1 ? 1 : 0)
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
} finally {
this.isLoading = false
} }
}, },
computed: {
visible: { // Nuclide
get() { async getInfoByNuclide() {
if (this.value) { try {
this.content = '' this.isLoading = true
const { sampleId, inputFileName } = this.sampleData
const { success, result, message } = await getAction('/gamma/changeNuclide', {
sampleId,
nuclideName: this.currNuclide,
fileName: inputFileName
})
if (success) {
console.log('%c [ ]-301', 'font-size:13px; background:pink; color:#bf2c9f;', result)
const { chart, halfLife, halfLifeErr, lines, name, table } = result
this.info = {
halfLife,
halfLifeErr,
lines,
name
}
this.list = table
chart.forEach((chartItem, index) => (chartItem._index = index))
this.chartList = chart
this.selectTableRow(table.length > 1 ? 1 : 0)
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
} finally {
this.isLoading = false
} }
return this.value
}, },
set(val) {
this.$emit('input', val) beforeModalOpen() {
} this.getInfo()
} }
} }
} }
@ -561,4 +499,19 @@ export default {
.custom-table-row { .custom-table-row {
cursor: pointer; cursor: pointer;
} }
.green-check-mark {
&::after {
@color: #3df9a7;
content: '';
border-radius: 0px;
width: 16px;
height: 9px;
display: inline-block;
border-bottom: 3px solid @color;
border-left: 3px solid @color;
transform: rotate(-45deg);
}
}
</style> </style>

View File

@ -41,7 +41,7 @@
<!-- 右侧 --> <!-- 右侧 -->
<div class="interactive-analysis-tools-right"> <div class="interactive-analysis-tools-right">
<title-over-border title="Peak"> <title-over-border :title="btnGroupType == 1 ? 'Peak' : 'Baseline Control Points'">
<div class="peak-box"> <div class="peak-box">
<!-- 按钮组1 --> <!-- 按钮组1 -->
<template v-if="btnGroupType == 1"> <template v-if="btnGroupType == 1">
@ -61,13 +61,13 @@
</div> </div>
<div class="peak-box-item base-line"> <div class="peak-box-item base-line">
<a-button type="primary" @click="btnGroupType = 2">BaseLine</a-button> <a-button type="primary" @click="handleSwitchOperation">BaseLine</a-button>
</div> </div>
</template> </template>
<!-- 按钮组2 --> <!-- 按钮组2 -->
<template v-if="btnGroupType == 2"> <template v-if="btnGroupType == 2">
<div class="peak-box-item"> <div class="peak-box-item">
<a-button type="primary">(A)dd CP</a-button> <a-button type="primary" @click="handleAddCP">(A)dd CP</a-button>
</div> </div>
<div class="peak-box-item"> <div class="peak-box-item">
<a-button type="primary">(R)emove CP</a-button> <a-button type="primary">(R)emove CP</a-button>
@ -85,10 +85,10 @@
<a-button type="primary">Replot</a-button> <a-button type="primary">Replot</a-button>
</div> </div>
<div class="peak-box-item"> <div class="peak-box-item">
<a-button type="primary" @click="btnGroupType = 1">Accept</a-button> <a-button type="primary" @click="handleAccept">Accept</a-button>
</div> </div>
<div class="peak-box-item"> <div class="peak-box-item">
<a-button type="primary" @click="btnGroupType = 1">Cancel</a-button> <a-button type="primary" @click="handleSwitchOperation">Cancel</a-button>
</div> </div>
</template> </template>
</div> </div>
@ -107,20 +107,42 @@
<div class="title"> <div class="title">
Possible Nuclide Possible Nuclide
</div> </div>
<div class="content"></div> <div class="content">
<template v-if="selectedTableItem && selectedTableItem._possible">
<div
class="item"
:class="{ active: possible == model.possibleNuclide }"
v-for="(possible, index) in selectedTableItem._possible"
:key="index"
@click="model.possibleNuclide = possible"
>
{{ possible }}
</div>
</template>
</div>
</div> </div>
<div class="identify-item"> <div class="identify-item">
<div class="title"> <div class="title">
Nuclide Identified Nuclide Identified
</div> </div>
<div class="content"></div> <div class="content">
<template v-if="selectedTableItem">
<div
class="item"
:class="{ active: identified == model.identifiedNuclide }"
v-for="(identified, index) in selectedTableItem.nuclides"
:key="index"
@click="model.identifiedNuclide = identified"
>
{{ identified }}
</div>
</template>
</div>
</div> </div>
<div class="identify-operators"> <div class="identify-operators">
<a-space> <span class="text">{{ model.possibleNuclide }}</span>
<a-input></a-input> <a-button type="primary" :disabled="!model.possibleNuclide" @click="handleAddNuclide">Add</a-button>
<a-button type="primary">Add</a-button> <a-button type="primary" @click="handleDelNuclide">Del</a-button>
<a-button type="primary" @click="handleDelCurrNuclide">Del</a-button>
</a-space>
</div> </div>
</title-over-border> </title-over-border>
</div> </div>
@ -135,7 +157,7 @@
<fit-peaks-and-base-line-modal v-model="fitPeaksAndBaselineModalVisible" /> <fit-peaks-and-base-line-modal v-model="fitPeaksAndBaselineModalVisible" />
<!-- Fit Peaks and Baseline弹窗 结束 --> <!-- Fit Peaks and Baseline弹窗 结束 -->
<!-- Nuclide Review 弹窗开始 --> <!-- Nuclide Review 弹窗开始 -->
<nuclide-review-modal v-model="nuclideReviewModalVisible" /> <nuclide-review-modal v-model="nuclideReviewModalVisible" :sampleId="sampleId" :channel="currChannel" />
<!-- Nuclide Review 弹窗结束 --> <!-- Nuclide Review 弹窗结束 -->
</custom-modal> </custom-modal>
</template> </template>
@ -150,14 +172,16 @@ import ModalMixin from '@/mixins/ModalMixin'
import { getAction } from '@/api/manage' import { getAction } from '@/api/manage'
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import Response from './Response.json' import Response from './Response.json'
import { getXAxisAndYAxisByPosition } from '@/utils/chartHelper' import { findSeriesByName, getXAxisAndYAxisByPosition } from '@/utils/chartHelper'
import SampleDataMixin from '@/views/spectrumAnalysis/SampleDataMixin'
// //
const initialOption = { const initialOption = {
grid: { grid: {
top: 40, top: 40,
left: 60, left: 40,
right: 50, right: 30,
bottom: 30,
containLabel: true containLabel: true
}, },
title: { title: {
@ -190,14 +214,6 @@ const initialOption = {
className: 'figure-chart-option-tooltip' className: 'figure-chart-option-tooltip'
}, },
xAxis: { xAxis: {
name: 'Channel',
nameTextStyle: {
color: '#8FD4F8',
fontSize: 16,
align: 'right',
verticalAlign: 'top',
padding: [30, 0, 0, 0]
},
axisLine: { axisLine: {
lineStyle: { lineStyle: {
color: '#ade6ee' color: '#ade6ee'
@ -217,6 +233,8 @@ const initialOption = {
}, },
yAxis: { yAxis: {
name: 'Counts', name: 'Counts',
nameLocation: 'center',
nameGap: 40,
nameTextStyle: { nameTextStyle: {
color: '#8FD4F8', color: '#8FD4F8',
fontSize: 16 fontSize: 16
@ -238,7 +256,7 @@ const initialOption = {
color: '#ade6ee' color: '#ade6ee'
} }
}, },
min: 1, min: 'dataMin',
max: 'dataMax', max: 'dataMax',
animation: false animation: false
}, },
@ -261,7 +279,7 @@ const columns = [
}, },
{ {
title: 'Centroid (C)', title: 'Centroid (C)',
dataIndex: 'centroid', dataIndex: 'peakCentroid',
width: 120 width: 120
}, },
{ {
@ -287,7 +305,10 @@ const columns = [
{ {
title: 'Nuclides', title: 'Nuclides',
dataIndex: 'nuclides', dataIndex: 'nuclides',
width: 120 width: 120,
customRender: text => {
return text && text.join(';')
}
} }
] ]
@ -329,7 +350,7 @@ const thumbnailOption = {
series: [] series: []
} }
export default { export default {
mixins: [ModalMixin], mixins: [ModalMixin, SampleDataMixin],
components: { components: {
CustomChart, CustomChart,
TitleOverBorder, TitleOverBorder,
@ -337,11 +358,6 @@ export default {
FitPeaksAndBaseLineModal, FitPeaksAndBaseLineModal,
NuclideReviewModal NuclideReviewModal
}, },
props: {
sampleId: {
type: Number
}
},
data() { data() {
this.columns = columns this.columns = columns
return { return {
@ -351,6 +367,7 @@ export default {
isLoading: false, isLoading: false,
list: [], list: [],
sampleId: -1,
commentModalVisible: false, // Comment commentModalVisible: false, // Comment
commentType: 'Peak', commentType: 'Peak',
@ -363,10 +380,13 @@ export default {
nuclideReviewModalVisible: false, // Nuclide Review nuclideReviewModalVisible: false, // Nuclide Review
model: { model: {
possibleNuclideList: [], possibleNuclide: '',
tolerance: 0.5, tolerance: 0.5,
identifiedNuclide: '', identifiedNuclide: ''
} },
currChannel: undefined, // currChannelchannel
selectedTableItem: undefined //
} }
}, },
methods: { methods: {
@ -375,10 +395,11 @@ export default {
this.isLoading = true this.isLoading = true
this.option.series = [] this.option.series = []
// const { success, result, message } = Response const { success, result, message } = Response
const { success, result, message } = await getAction('/gamma/InteractiveTool', { // const { success, result, message } = await getAction('/gamma/InteractiveTool', {
sampleId: this.sampleId // sampleId: this.sampleId,
}) // fileName: this.fileName
// })
if (success) { if (success) {
const { const {
barChart, barChart,
@ -465,7 +486,11 @@ export default {
this.thumbnailOption.series.push( this.thumbnailOption.series.push(
this.buildSeriesOption( this.buildSeriesOption(
'BarChart', 'BarChart',
barChart.map(({ x, y }) => [x, y]) barChart.map(({ x, y }) => [x, y]),
'#fff',
{
silent: true
}
) )
) )
@ -502,6 +527,13 @@ export default {
}, },
beforeModalOpen() { beforeModalOpen() {
const { sampleId, inputFileName } = this.sampleData
this.sampleId = sampleId
this.fileName = inputFileName
this.currChannel = undefined
this.btnGroupType = 1
this.getInfo() this.getInfo()
this.opts.notMerge = false this.opts.notMerge = false
@ -519,6 +551,8 @@ export default {
const xAxis = parseInt(point[0].toFixed()) const xAxis = parseInt(point[0].toFixed())
this.option.series[0].markLine.data[0].xAxis = xAxis this.option.series[0].markLine.data[0].xAxis = xAxis
this.currChannel = xAxis
// Channel // Channel
const maxXAxises = this.getPeakMaxValues() const maxXAxises = this.getPeakMaxValues()
@ -540,7 +574,12 @@ export default {
continue continue
} }
} }
this.selectedKeys = [this.list[index].index]
const selectedRow = this.list[index]
this.selectedKeys = [selectedRow.index]
this.getSelPosNuclide(selectedRow)
} }
}, },
@ -576,6 +615,31 @@ export default {
} }
}, },
// possible nuclide identified nuclide
async getSelPosNuclide(row) {
this.model.possibleNuclide = ''
this.model.identifiedNuclide = ''
if (!row._possible) {
try {
const { success, result, message } = await getAction('/gamma/getSelPosNuclide', {
sampleId: this.sampleId,
channel: parseInt(row.peakCentroid),
nuclides: row.nuclides.join(','),
fileName: this.fileName
})
if (success) {
const { possible } = result
this.$set(row, '_possible', possible)
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
}
}
},
// Channel // Channel
getPeakMaxValues() { getPeakMaxValues() {
const maxXAxises = this.channelPeakChart.map(item => { const maxXAxises = this.channelPeakChart.map(item => {
@ -631,19 +695,26 @@ export default {
// //
handleFit() { handleFit() {
if(!this.list.length) { if (!this.list.length) {
this.$message.warn('No peak to fit.') this.$message.warn('No peak to fit.')
return return
} }
}, },
// //
handleTableRowClick(_, index) { handleTableRowClick(row) {
const pointlist = this.channelPeakChart[index].pointlist if (this.selectedTableItem == row) {
return
}
const allY = pointlist.map(point => point.y) const channel = row.peakCentroid
const findMax = pointlist.find(point => point.y == Math.max(...allY)) this.currChannel = channel
this.option.series[0].markLine.data[0].xAxis = findMax.x
this.option.series[0].markLine.data[0].xAxis = channel
this.getSelPosNuclide(row)
this.selectedTableItem = row
}, },
// //
@ -660,9 +731,61 @@ export default {
}) })
}, },
// nuclide //
handleDelCurrNuclide() { handleSwitchOperation() {
// Base Line Control Point
if (this.btnGroupType == 1) {
this.btnGroupType = 2
const originalCPSeries = findSeriesByName(this.option.series, 'BaseLine')
this.option.series.push(
this.buildSeriesOption('Edit_BaseLine', originalCPSeries.data, '#fff', {
zlevel: 21
})
)
}
// Peak
else {
this.btnGroupType = 1
this.option.series.splice(this.option.series.length - 1, 1)
}
},
// 线
handleAddCP() {
const xAxis = this.option.series[0].markLine.data[0].xAxis
if (xAxis == -1) {
this.$message.warn("Can't insert Control Point out of range")
return
}
console.log('%c [ ]-735', 'font-size:13px; background:pink; color:#bf2c9f;', xAxis)
},
// Control Point
handleAccept() {},
// nuclide
handleAddNuclide() {
const nuclides = this.selectedTableItem.nuclides
const possibleNuclide = this.model.possibleNuclide
if (this.selectedTableItem && !nuclides.includes(possibleNuclide)) {
nuclides.push(possibleNuclide)
}
},
// nuclide
handleDelNuclide() {
const [willDelKey] = this.selectedKeys
const find = this.list.find(item => item.index == willDelKey)
console.log('%c [ find ]-762', 'font-size:13px; background:pink; color:#bf2c9f;', find)
if (find) {
const nuclides = find.nuclides
const findIndex = nuclides.findIndex(nuclide => nuclide == this.model.identifiedNuclide)
if (-1 !== findIndex) {
nuclides.splice(findIndex, 1)
}
}
} }
} }
} }
@ -682,8 +805,7 @@ export default {
.thumbnail { .thumbnail {
height: 50px; height: 50px;
margin-top: 10px; margin: 10px 10px 35px 40px;
margin-bottom: 35px;
background-color: #255369; background-color: #255369;
} }
@ -797,11 +919,30 @@ export default {
height: 80px; height: 80px;
background-color: #275466; background-color: #275466;
margin: 10px 0; margin: 10px 0;
padding: 5px;
overflow: auto;
.item {
cursor: pointer;
line-height: 26px;
padding: 0 5px;
&.active {
background: #296d81;
}
}
} }
} }
.identify-operators { .identify-operators {
display: flex; display: flex;
gap: 10px;
.text {
flex: 1;
line-height: 32px;
background-color: #285366;
padding: 0 10px;
}
.ant-btn { .ant-btn {
width: 50px; width: 50px;

View File

@ -1,15 +1,50 @@
<template> <template>
<custom-modal v-model="visible" :width="800" title="Auto Process Log Viewer" :okHandler="handleOk"> <custom-modal v-model="visible" :width="1000" title="Auto Process Log Viewer" :okHandler="handleOk">
<a-textarea :rows="18"></a-textarea> <a-spin :spinning="isLoading">
<pre>
{{ content }}
</pre>
</a-spin>
</custom-modal> </custom-modal>
</template> </template>
<script> <script>
import { getAction } from '@/api/manage'
import ModalMixin from '@/mixins/ModalMixin' import ModalMixin from '@/mixins/ModalMixin'
import SampleDataMixin from '@/views/spectrumAnalysis/SampleDataMixin'
export default { export default {
mixins: [ModalMixin], mixins: [ModalMixin, SampleDataMixin],
props: {
type: {
type: Number
}
},
data() {
return {
content: ''
}
},
methods: { methods: {
async getInfo() {
try {
this.isLoading = true
const { sampleId } = this.sampleData
const res = await getAction(this.type == 1 ? '/gamma/viewAutomaticAnalysisLog' : '', {
sampleId
})
this.content = res
} catch (error) {
console.error(error)
} finally {
this.isLoading = false
}
},
beforeModalOpen() {
this.getInfo()
},
handleOk() { handleOk() {
console.log('%c [ ]-15', 'font-size:13px; background:pink; color:#bf2c9f;') console.log('%c [ ]-15', 'font-size:13px; background:pink; color:#bf2c9f;')
} }
@ -17,4 +52,11 @@ export default {
} }
</script> </script>
<style></style> <style lang="less" scoped>
pre {
height: 450px;
padding: 5px;
overflow: auto;
background-color: #285367;
}
</style>

View File

@ -162,7 +162,17 @@ export default {
getAction(this.url.list, params) getAction(this.url.list, params)
.then(res => { .then(res => {
if (res.success) { if (res.success) {
this.dataSource = res.result.records || res.result const result = res.result.records || res.result
result.forEach(item => {
const fileName = item.inputFileName
if(fileName) {
const arr = fileName.split('/')
item.inputFileName = arr[arr.length - 1]
}
})
this.dataSource = result
if (res.result.total) { if (res.result.total) {
this.ipagination.total = res.result.total this.ipagination.total = res.result.total
} else { } else {

View File

@ -13,7 +13,7 @@
<div class="fission-product-list"> <div class="fission-product-list">
<div <div
class="fission-product-list-item" class="fission-product-list-item"
:class="fissionSelectedItem1 == item ? 'active' : ''" :class="model.nuclide1 == item ? 'active' : ''"
v-for="(item, index) in fissionProductList1" v-for="(item, index) in fissionProductList1"
:key="index" :key="index"
@click="handleFissonSelect(item, 1)" @click="handleFissonSelect(item, 1)"
@ -29,7 +29,7 @@
<div class="fission-product-list"> <div class="fission-product-list">
<div <div
class="fission-product-list-item" class="fission-product-list-item"
:class="fissionSelectedItem2 == item ? 'active' : ''" :class="model.nuclide2 == item ? 'active' : ''"
v-for="(item, index) in fissionProductList2" v-for="(item, index) in fissionProductList2"
:key="index" :key="index"
@click="handleFissonSelect(item, 2)" @click="handleFissonSelect(item, 2)"
@ -57,7 +57,7 @@
Fission Product 1 Fission Product 1
</div> </div>
<div> <div>
<a-input v-model="model.value1"></a-input> <a-input v-model="model.product1"></a-input>
</div> </div>
</div> </div>
<div class="operator"> <div class="operator">
@ -68,7 +68,7 @@
Fission Product 2 Fission Product 2
</div> </div>
<div> <div>
<a-input v-model="model.value2"></a-input> <a-input v-model="model.product2"></a-input>
</div> </div>
</div> </div>
</div> </div>
@ -76,14 +76,14 @@
<div class="zero-time-right-center mt-20"> <div class="zero-time-right-center mt-20">
<!-- Fission Target --> <!-- Fission Target -->
<title-over-border class="fission-target" title="Fission Target"> <title-over-border class="fission-target" title="Fission Target">
<a-radio-group v-model="model.fissionTarget"> <a-radio-group v-model="model.target">
<a-radio value="U-235">U-235</a-radio> <a-radio value="U-235">U-235</a-radio>
<a-radio value="U-238">U-238</a-radio> <a-radio value="U-238">U-238</a-radio>
<a-radio value="PU-239">PU-239</a-radio> <a-radio value="PU-239">PU-239</a-radio>
</a-radio-group> </a-radio-group>
</title-over-border> </title-over-border>
<title-over-border class="fission-energy" title="Energy of Fission Neutron"> <title-over-border class="fission-energy" title="Energy of Fission Neutron">
<a-radio-group v-model="model.fissionEnergy"> <a-radio-group v-model="model.energyTFH">
<a-radio value="T">T&gt;Thermal_spectrum</a-radio> <a-radio value="T">T&gt;Thermal_spectrum</a-radio>
<a-radio value="F">F&gt;Fission_spectrum</a-radio> <a-radio value="F">F&gt;Fission_spectrum</a-radio>
<a-radio value="H">H-&gt;Fast_Neutron</a-radio> <a-radio value="H">H-&gt;Fast_Neutron</a-radio>
@ -102,7 +102,9 @@
</title-over-border> </title-over-border>
<div class="zero-time-right-buttons mt-20"> <div class="zero-time-right-buttons mt-20">
<a-button type="primary" :disabled="disabled" @click="handleAnalysis">Analysis</a-button> <a-button type="primary" :disabled="disabled" :loading="isAnalyzing" @click="handleAnalysis">
Analysis
</a-button>
<a-button type="primary">Save</a-button> <a-button type="primary">Save</a-button>
<a-button type="primary">Exit</a-button> <a-button type="primary">Exit</a-button>
</div> </div>
@ -132,16 +134,10 @@ export default {
fissionProductList1: [], fissionProductList1: [],
fissionProductList2: [], fissionProductList2: [],
fissionSelectedItem1: null,
fissionSelectedItem2: null,
dateTime: '', dateTime: '',
model: { model: {},
date: undefined,
time: undefined, isAnalyzing: false
fissionTarget: '',
fissionEnergy: ''
}
} }
}, },
methods: { methods: {
@ -170,33 +166,53 @@ export default {
// Fission // Fission
handleFissonSelect(item, which) { handleFissonSelect(item, which) {
if (which == 1) { if (which == 1) {
this.fissionSelectedItem1 = item this.model.nuclide1 = item
} else { } else {
this.fissionSelectedItem2 = item this.model.nuclide2 = item
} }
}, },
beforeModalOpen() { beforeModalOpen() {
this.model.fissionTarget = 'U-235' this.model = {
this.model.fissionEnergy = 'T' nuclide1: '',
this.fissionSelectedItem1 = null nuclide2: '',
this.fissionSelectedItem2 = null product1: '',
product2: '',
target: 'U-235',
energyTFH: 'T',
date: undefined,
time: undefined
}
this.dateTime = '2015-05-30 17:30:60' this.dateTime = '2015-05-30 17:30:60'
this.getInfo() this.getInfo()
}, },
// //
handleAnalysis() { async handleAnalysis() {
console.log('%c [ ]-188', 'font-size:13px; background:pink; color:#bf2c9f;') if (!this.model.product1 || !this.model.product2) {
this.$message.warn('The Fission Product is invalid!')
return
}
try {
this.isAnalyzing = true
const { success, result, message } = await getAction('/gamma/ZeroTimeAnalyse', this.model)
if (success) {
this.dateTime = result
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
} finally {
this.isAnalyzing = false
}
} }
}, },
computed: { computed: {
disabled() { disabled() {
return ( return !this.model.nuclide1 || !this.model.nuclide2 || this.model.nuclide1 == this.model.nuclide2
!this.fissionSelectedItem1 ||
!this.fissionSelectedItem2 ||
this.fissionSelectedItem1 == this.fissionSelectedItem2
)
} }
} }
} }

View File

@ -4,7 +4,7 @@
<span class="checkbox"> <span class="checkbox">
<a-icon v-if="item.checked" type="check" style="color: #0de30d" /> <a-icon v-if="item.checked" type="check" style="color: #0de30d" />
</span> </span>
<span class="name">{{ getFileName(item.inputFileName) }}</span> <span class="name">{{ item.inputFileName }}</span>
<a-icon type="delete" @click.stop="handleRemove(item)" /> <a-icon type="delete" @click.stop="handleRemove(item)" />
</a-menu-item> </a-menu-item>
</a-menu> </a-menu>
@ -40,17 +40,6 @@ export default {
} }
} }
this.$forceUpdate() this.$forceUpdate()
},
/**
* 获取文件名
* @param {String} inputFileName
*/
getFileName(inputFileName) {
if (inputFileName) {
const arr = inputFileName.split('/')
return arr[arr.length - 1]
}
} }
}, },
watch: { watch: {

View File

@ -536,6 +536,7 @@ export default {
case 'Channel': case 'Channel':
case 'Energy': case 'Energy':
this.graphAssistance.axisType = label this.graphAssistance.axisType = label
this.option.xAxis.name = label
this.handleReset() this.handleReset()

View File

@ -152,7 +152,7 @@
<rlr-modal v-model="rlrModalVisible" :sampleId="sampleData.sampleId" /> <rlr-modal v-model="rlrModalVisible" :sampleId="sampleData.sampleId" />
<!-- RLR 弹窗结束 --> <!-- RLR 弹窗结束 -->
<automatic-analysis-log-modal v-model="autoAnalysisMogModalVisible" /> <automatic-analysis-log-modal v-model="autoAnalysisMogModalVisible" :type="autoAnalysisMogModalType" />
<!-- Beta-Gamma 的Comments 弹窗 --> <!-- Beta-Gamma 的Comments 弹窗 -->
<beta-gamma-comments-modal <beta-gamma-comments-modal
@ -286,6 +286,15 @@ export default {
AutomaticAnalysisLogModal, AutomaticAnalysisLogModal,
BetaGammaExtrapolationModal BetaGammaExtrapolationModal
}, },
provide() {
return {
sample: () => {
return this.sampleData
}
}
},
data() { data() {
this.ANALYZE_TYPE = ANALYZE_TYPE this.ANALYZE_TYPE = ANALYZE_TYPE
@ -335,6 +344,7 @@ export default {
rlrModalVisible: false, // Reports -> RLR rlrModalVisible: false, // Reports -> RLR
autoAnalysisMogModalVisible: false, // Log -> Automatic Analysis Log autoAnalysisMogModalVisible: false, // Log -> Automatic Analysis Log
autoAnalysisMogModalType: 1, // Log -> Automatic Analysis Log 1gamma 2 betagamma
/** /**
* 以下是beta-gamma跟前面不同的弹窗 * 以下是beta-gamma跟前面不同的弹窗
@ -357,7 +367,8 @@ export default {
this.loadSelectedSample({ this.loadSelectedSample({
sampleId: 426530, sampleId: 426530,
sampleType: 'G', sampleType: 'G',
dbName: 'auto' dbName: 'auto',
inputFileName: 'CAX05_001-20230731_1528_S_FULL_37563.6.PHD'
}) })
}, },
@ -378,6 +389,7 @@ export default {
// //
async loadSelectedSample(sample) { async loadSelectedSample(sample) {
console.log('%c [ sample ]-381', 'font-size:13px; background:pink; color:#bf2c9f;', sample)
// Bbeta-gamma P Ggamma // Bbeta-gamma P Ggamma
if (sample.sampleType == 'B') { if (sample.sampleType == 'B') {
this.analysisType = ANALYZE_TYPE.BETA_GAMMA this.analysisType = ANALYZE_TYPE.BETA_GAMMA
@ -884,8 +896,10 @@ export default {
{ {
type: 'a-menu-item', type: 'a-menu-item',
title: 'Automatic Analysis Log', title: 'Automatic Analysis Log',
show: this.isBetaGamma, handler: () => {
handler: () => (this.autoAnalysisMogModalVisible = true) this.autoAnalysisMogModalType = 1
this.autoAnalysisMogModalVisible = true
}
}, },
{ {
type: 'a-menu-item', type: 'a-menu-item',