feat: 增加道址显示,修改ROI范围后Update按钮变红,交互分析弹窗中表格增加感兴趣元素高亮显示,增加Apply按钮以更新XeData

This commit is contained in:
Xu Zhimeng 2025-08-11 10:37:34 +08:00
parent 6deaca4d4b
commit 1c8de3ecfb
3 changed files with 322 additions and 192 deletions

View File

@ -11,7 +11,7 @@
:loading="loading" :loading="loading"
:pagination="pagination" :pagination="pagination"
:customRow="multiple && mouseMoveSelect ? customMouseMoveSelectRow : customRow" :customRow="multiple && mouseMoveSelect ? customMouseMoveSelectRow : customRow"
:rowClassName="() => (canSelect ? 'custom-table-row' : '')" :rowClassName="(record, index) => innerRowClassName(record, index)"
@change="handleTableChange" @change="handleTableChange"
> >
<!-- 处理 scopedSlots --> <!-- 处理 scopedSlots -->
@ -25,55 +25,58 @@ export default {
props: { props: {
list: { list: {
type: Array, type: Array,
default: () => [], default: () => []
}, },
columns: { columns: {
type: Array, type: Array,
default: () => [], default: () => []
}, },
size: { size: {
type: String, type: String,
default: 'middle', default: 'middle'
}, },
rowKey: { rowKey: {
type: String, type: String,
default: 'id', default: 'id'
}, },
loading: { loading: {
type: Boolean, type: Boolean
}, },
pagination: { pagination: {
type: [Object, Boolean], type: [Object, Boolean]
}, },
selectedRowKeys: { selectedRowKeys: {
type: Array, type: Array
}, },
selectionRows: { selectionRows: {
type: Array, type: Array
}, },
canSelect: { canSelect: {
type: Boolean, type: Boolean,
default: true, default: true
}, },
canDeselect: { canDeselect: {
type: Boolean, type: Boolean,
default: true, default: true
}, },
// //
multiple: { multiple: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
// //
mouseMoveSelect: { mouseMoveSelect: {
type: Boolean, type: Boolean,
default: true, default: true
}, },
customRowClassName: {
type: Function
}
}, },
data() { data() {
return { return {
innerSelectedRowKeys: [], innerSelectedRowKeys: [],
innerSelectedRows: [], innerSelectedRows: []
} }
}, },
mounted() { mounted() {
@ -85,6 +88,14 @@ export default {
} }
}, },
methods: { methods: {
innerRowClassName(record, index) {
let className = ''
if (this.customRowClassName) {
className = this.customRowClassName({ record, index })
}
return (this.canSelect ? 'custom-table-row' : '') + ' ' + className
},
// / // /
customRow(record, index) { customRow(record, index) {
const key = record[this.rowKey] const key = record[this.rowKey]
@ -98,7 +109,7 @@ export default {
// //
if (this.innerSelectedRowKeys.includes(key)) { if (this.innerSelectedRowKeys.includes(key)) {
if (this.multiple || this.canDeselect) { if (this.multiple || this.canDeselect) {
const findIndex = this.innerSelectedRowKeys.findIndex((k) => k == key) const findIndex = this.innerSelectedRowKeys.findIndex(k => k == key)
this.innerSelectedRowKeys.splice(findIndex, 1) this.innerSelectedRowKeys.splice(findIndex, 1)
} }
} }
@ -116,8 +127,8 @@ export default {
}, },
dblclick: () => { dblclick: () => {
this.$emit('rowDblClick', record, index) this.$emit('rowDblClick', record, index)
}, }
}, }
} }
}, },
@ -134,7 +145,7 @@ export default {
mouseenter: () => { mouseenter: () => {
if (this.mouseMoveStartIndex !== undefined) { if (this.mouseMoveStartIndex !== undefined) {
const indexes = [this.mouseMoveStartIndex, index].sort((a, b) => a - b) const indexes = [this.mouseMoveStartIndex, index].sort((a, b) => a - b)
this.innerSelectedRowKeys = this.list.slice(indexes[0], indexes[1] + 1).map((item) => item[this.rowKey]) this.innerSelectedRowKeys = this.list.slice(indexes[0], indexes[1] + 1).map(item => item[this.rowKey])
} }
}, },
mouseup: () => { mouseup: () => {
@ -143,8 +154,8 @@ export default {
this.innerSelectedRowKeys = [key] this.innerSelectedRowKeys = [key]
} }
this.mouseMoveStartIndex = undefined this.mouseMoveStartIndex = undefined
}, }
}, }
} }
}, },
@ -158,7 +169,7 @@ export default {
const tableBodyEle = tableEle.querySelector('.ant-table-body') const tableBodyEle = tableEle.querySelector('.ant-table-body')
const prevEle = tableBodyEle.querySelector(`.ant-table-row:nth-child(${index + 1})`) const prevEle = tableBodyEle.querySelector(`.ant-table-row:nth-child(${index + 1})`)
tableBodyEle.scrollTop = prevEle.offsetTop tableBodyEle.scrollTop = prevEle.offsetTop
}, }
}, },
watch: { watch: {
selectedRowKeys(val) { selectedRowKeys(val) {
@ -166,17 +177,17 @@ export default {
}, },
innerSelectedRowKeys() { innerSelectedRowKeys() {
this.$emit('update:selectedRowKeys', this.innerSelectedRowKeys) this.$emit('update:selectedRowKeys', this.innerSelectedRowKeys)
this.innerSelectedRows = this.innerSelectedRowKeys.map((key) => { this.innerSelectedRows = this.innerSelectedRowKeys.map(key => {
return this.list.find((item) => item[this.rowKey] === key) return this.list.find(item => item[this.rowKey] === key)
}) })
this.$emit('update:selectionRows', this.innerSelectedRows) this.$emit('update:selectionRows', this.innerSelectedRows)
}, }
}, },
computed: { computed: {
scopedSlotsKeys() { scopedSlotsKeys() {
return Object.keys(this.$scopedSlots) return Object.keys(this.$scopedSlots)
}, }
}, }
} }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@ -192,7 +203,8 @@ export default {
border-color: #416f7f; border-color: #416f7f;
} }
.ant-table-bordered .ant-table-thead > tr > th, .ant-table-bordered .ant-table-tbody > tr > td { .ant-table-bordered .ant-table-thead > tr > th,
.ant-table-bordered .ant-table-tbody > tr > td {
border-color: #416f7f; border-color: #416f7f;
} }
} }

View File

@ -19,26 +19,33 @@
ROI{{ index + 1 }} ROI{{ index + 1 }}
</div> </div>
<a-input-group> <a-input-group>
<a-input <div>
type="number" <a-input
v-model="roiParamList[index][0]" type="number"
class="spectrum-analysis-sub-operators-roi-input" v-model="roiParamList[index][0]"
placeholder="Beta1" class="spectrum-analysis-sub-operators-roi-input"
:disabled="spectraType !== 'sample'" placeholder="Beta1"
/> :disabled="spectraType !== 'sample'"
/>
<span class="spectrum-analysis-sub-operators-roi-energy">({{ getEnergy(roiParamList[index][0]) }})</span>
</div>
<span class="spectrum-analysis-sub-operators-roi-split">,</span> <span class="spectrum-analysis-sub-operators-roi-split">,</span>
<a-input <div>
type="number" <a-input
v-model="roiParamList[index][1]" type="number"
class="spectrum-analysis-sub-operators-roi-input" v-model="roiParamList[index][1]"
placeholder="Beta2" class="spectrum-analysis-sub-operators-roi-input"
:disabled="spectraType !== 'sample'" placeholder="Beta2"
/> :disabled="spectraType !== 'sample'"
/>
<span class="spectrum-analysis-sub-operators-roi-energy">({{ getEnergy(roiParamList[index][1]) }})</span>
</div>
</a-input-group> </a-input-group>
</div> </div>
<a-button <a-button
type="primary" type="primary"
class="spectrum-analysis-sub-operators-button" class="spectrum-analysis-sub-operators-button"
:class="{ 'is-changed': isChanged }"
:disabled="spectraType !== 'sample'" :disabled="spectraType !== 'sample'"
@click="handleUpdate" @click="handleUpdate"
> >
@ -142,16 +149,16 @@ import SelfStationBgLogViewer from './components/Modals/SelfStation/SelfStationB
const SampleType = [ const SampleType = [
{ {
label: 'Sample Data', label: 'Sample Data',
value: 'sample', value: 'sample'
}, },
{ {
label: 'DetBg Data', label: 'DetBg Data',
value: 'det', value: 'det'
}, },
{ {
label: 'QC Data', label: 'QC Data',
value: 'qc', value: 'qc'
}, }
] ]
const InitialRoiParamList = new Array(4).fill([0, 0]) const InitialRoiParamList = new Array(4).fill([0, 0])
@ -175,16 +182,16 @@ export default {
SelfStationSpectrumModal, SelfStationSpectrumModal,
SelfStationPeakInfomation, SelfStationPeakInfomation,
SelfStationAutomaticAnalysisLogModal, SelfStationAutomaticAnalysisLogModal,
SelfStationBgLogViewer, SelfStationBgLogViewer
}, },
props: { props: {
sample: { sample: {
type: Object, type: Object
}, },
sampleList: { sampleList: {
type: Array, type: Array,
default: () => [], default: () => []
}, }
}, },
data() { data() {
this.SampleType = SampleType this.SampleType = SampleType
@ -200,8 +207,9 @@ export default {
ROILists: [], ROILists: [],
ROIAnalyzeLists: [], ROIAnalyzeLists: [],
roiParamList: cloneDeep(InitialRoiParamList), roiParamList: cloneDeep(InitialRoiParamList),
roiParamListState: cloneDeep(InitialRoiParamList),
resultDisplay: [], resultDisplay: [],
timerStamp: Date.now(), timerStamp: Date.now()
} }
}, },
watch: { watch: {
@ -229,21 +237,42 @@ export default {
this.$bus.$emit('resetROIRectState') this.$bus.$emit('resetROIRectState')
}, },
immediate: true, immediate: true,
deep: true, deep: true
}, }
}, },
created() { created() {
this.$bus.$on('selfRefresh', this.handleRefresh) this.$bus.$on('selfRefresh', this.handleRefresh)
this.$bus.$on('selfAccept', this.handleAccept) this.$bus.$on('selfAccept', this.handleAccept)
this.$bus.$on('ReAnalyses', this.updateByReprocessingData) this.$bus.$on('ReAnalyses', this.updateByReprocessingData)
this.$bus.$on('selfUpdateXeData', this.updateXeData)
}, },
beforeDestroy() { beforeDestroy() {
this.cancelLastRequest() this.cancelLastRequest()
this.$bus.$off('selfRefresh', this.handleRefresh) this.$bus.$off('selfRefresh', this.handleRefresh)
this.$bus.$off('selfAccept', this.handleAccept) this.$bus.$off('selfAccept', this.handleAccept)
this.$bus.$off('ReAnalyses', this.updateByReprocessingData) this.$bus.$off('ReAnalyses', this.updateByReprocessingData)
this.$bus.$off('selfUpdateXeData', this.updateXeData)
},
computed: {
isChanged() {
//
return this.roiParamListState.some((item, index) => {
return item[0] !== this.roiParamList[index][0] || item[1] !== this.roiParamList[index][1]
})
}
}, },
methods: { methods: {
updateXeData(XeData) {
this.resultDisplay = XeData
updateSampleData({ inputFileName: this.sample.inputFileName, key: 'XeData', data: XeData })
},
//
getEnergy(channel) {
const energy = this.betaEnergyData[channel]
return energy ? energy.toFixed(2) : 0
},
// db // db
getROIAnalyzeListsFromResult(sampleData) { getROIAnalyzeListsFromResult(sampleData) {
const arr = [] const arr = []
@ -275,7 +304,7 @@ export default {
const arr = message.split('\n') const arr = message.split('\n')
this.$warning({ this.$warning({
title: 'Warning', title: 'Warning',
content: () => arr.map((text) => <div>{text}</div>), content: () => arr.map(text => <div>{text}</div>)
}) })
} }
} catch (error) { } catch (error) {
@ -292,14 +321,14 @@ export default {
updateSampleData({ updateSampleData({
inputFileName, inputFileName,
key: 'ROIAnalyzeLists', key: 'ROIAnalyzeLists',
data: analyseList, data: analyseList
}) })
// XeData // XeData
updateSampleData({ updateSampleData({
inputFileName, inputFileName,
key: 'XeData', key: 'XeData',
data: result.XeData, data: result.XeData
}) })
this.resultDisplay = result.XeData this.resultDisplay = result.XeData
@ -312,18 +341,18 @@ export default {
updateSampleData({ updateSampleData({
inputFileName, inputFileName,
key: 'sample.betaEnergyData', key: 'sample.betaEnergyData',
data: betaEnergyData, data: betaEnergyData
}) })
updateSampleData({ updateSampleData({
inputFileName, inputFileName,
key: 'sample.gammaEnergyData', key: 'sample.gammaEnergyData',
data: gammaEnergyData, data: gammaEnergyData
}) })
updateSampleData({ updateSampleData({
inputFileName, inputFileName,
key: 'savedAnalysisResult', key: 'savedAnalysisResult',
data: true, data: true
}) })
}, },
@ -353,7 +382,7 @@ export default {
const params = this.roiParamList.map(([startChannel, endChannel], index) => ({ const params = this.roiParamList.map(([startChannel, endChannel], index) => ({
startChannel, startChannel,
endChannel, endChannel,
roiNum: index + 1, roiNum: index + 1
})) }))
const { inputFileName } = this.sample const { inputFileName } = this.sample
@ -376,7 +405,7 @@ export default {
updateSampleData({ updateSampleData({
inputFileName, inputFileName,
key: 'ROIAnalyzeLists', key: 'ROIAnalyzeLists',
data: cloneDeep(this.ROIAnalyzeLists), data: cloneDeep(this.ROIAnalyzeLists)
}) })
this.$refs.betaChartRef.setBoundaryList(cloneDeep(this.roiParamList)) this.$refs.betaChartRef.setBoundaryList(cloneDeep(this.roiParamList))
@ -388,19 +417,22 @@ export default {
updateSampleData({ updateSampleData({
inputFileName, inputFileName,
key: `sample.${realKey}`, key: `sample.${realKey}`,
data: this.roiParamList[index][ind], data: this.roiParamList[index][ind]
}) })
}) })
}) })
// XeData // XeData
this.resultDisplay = result.XeData this.resultDisplay = result.XeData
// RoiParamList
this.roiParamListState = cloneDeep(this.roiParamList)
} else { } else {
this.isLoading = false this.isLoading = false
const arr = message.split('\n') const arr = message.split('\n')
this.$warning({ this.$warning({
title: 'Warning', title: 'Warning',
content: () => arr.map((text) => <div>{text}</div>), content: () => arr.map(text => <div>{text}</div>)
}) })
} }
} catch (error) { } catch (error) {
@ -416,7 +448,7 @@ export default {
let params = { let params = {
sampleFileName: inputFileName, sampleFileName: inputFileName,
detFileName: detFileName, detFileName: detFileName,
qcFileName: qcFileName, qcFileName: qcFileName
} }
try { try {
this.isLoading = true this.isLoading = true
@ -427,7 +459,7 @@ export default {
addSampleData({ addSampleData({
inputFileName, inputFileName,
data: result, data: result,
from: 'file', from: 'file'
}) })
this.sampleDetail = result this.sampleDetail = result
this.changeChartByType('sample') this.changeChartByType('sample')
@ -458,7 +490,7 @@ export default {
{ {
dbName, dbName,
sampleId, sampleId,
analyst, analyst
}, },
cancelToken cancelToken
) )
@ -466,14 +498,14 @@ export default {
addSampleData({ addSampleData({
inputFileName, inputFileName,
data: result, data: result,
from: 'db', from: 'db'
}) })
const analyseList = this.getROIAnalyzeListsFromResult(result.sample) const analyseList = this.getROIAnalyzeListsFromResult(result.sample)
updateSampleData({ updateSampleData({
inputFileName, inputFileName,
key: 'ROIAnalyzeLists', key: 'ROIAnalyzeLists',
data: analyseList, data: analyseList
}) })
this.sampleDetail = result this.sampleDetail = result
@ -533,7 +565,7 @@ export default {
ROIThreeStart, ROIThreeStart,
ROIThreeStop, ROIThreeStop,
ROIFourStart, ROIFourStart,
ROIFourStop, ROIFourStop
} = currSampleDetail } = currSampleDetail
this.spectrumData = spectrumData this.spectrumData = spectrumData
@ -542,10 +574,11 @@ export default {
[ROIOneStart, ROIOneStop], [ROIOneStart, ROIOneStop],
[ROITwoStart, ROITwoStop], [ROITwoStart, ROITwoStop],
[ROIThreeStart, ROIThreeStop], [ROIThreeStart, ROIThreeStop],
[ROIFourStart, ROIFourStop], [ROIFourStart, ROIFourStop]
] ]
this.roiParamList = cloneDeep(boundaryList) this.roiParamList = cloneDeep(boundaryList)
this.roiParamListState = cloneDeep(boundaryList)
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.betaChartRef.setBoundaryList(boundaryList) this.$refs.betaChartRef.setBoundaryList(boundaryList)
this.$refs.betaChartRef.setData(histogramDataList, histogramDataDList) this.$refs.betaChartRef.setData(histogramDataList, histogramDataDList)
@ -562,13 +595,13 @@ export default {
}, },
createCancelToken() { createCancelToken() {
const cancelToken = new axios.CancelToken((c) => { const cancelToken = new axios.CancelToken(c => {
this._cancelToken = c this._cancelToken = c
}) })
return cancelToken return cancelToken
}, },
handleGetFlag(val, obj) { handleGetFlag(val, obj) {
this.resultDisplay.forEach((item) => { this.resultDisplay.forEach(item => {
if (item.nuclideName === obj.nuclideName) { if (item.nuclideName === obj.nuclideName) {
item.nidFlag = val ? 1 : 0 item.nidFlag = val ? 1 : 0
} }
@ -592,7 +625,7 @@ export default {
updateSampleData({ updateSampleData({
inputFileName, inputFileName,
key: 'ROIAnalyzeLists', key: 'ROIAnalyzeLists',
data: this.ROIAnalyzeLists, data: this.ROIAnalyzeLists
}) })
}, },
@ -606,7 +639,7 @@ export default {
shapeChannelData, shapeChannelData,
shapeEnergyData, shapeEnergyData,
barChart, barChart,
BaseCtrls, BaseCtrls
} = data } = data
this.$set(this.ROIAnalyzeLists, index, { this.$set(this.ROIAnalyzeLists, index, {
@ -617,14 +650,14 @@ export default {
shapeChannelData, shapeChannelData,
shapeEnergyData, shapeEnergyData,
barChart, barChart,
BaseCtrls, BaseCtrls
}) })
const { inputFileName } = this.sample const { inputFileName } = this.sample
updateSampleData({ updateSampleData({
inputFileName, inputFileName,
key: 'ROIAnalyzeLists', key: 'ROIAnalyzeLists',
data: this.ROIAnalyzeLists, data: this.ROIAnalyzeLists
}) })
}, },
@ -647,12 +680,17 @@ export default {
if (!this.ROIAnalyzeLists || !this.ROIAnalyzeLists.length) { if (!this.ROIAnalyzeLists || !this.ROIAnalyzeLists.length) {
throw new Error('Please Analyse Spectrum First') throw new Error('Please Analyse Spectrum First')
} }
if (this.isChanged) {
await this.confirm()
}
const { inputFileName: fileName } = this.sample const { inputFileName: fileName } = this.sample
const sampleData = getSampleData(fileName) const sampleData = getSampleData(fileName)
const { success, message, result } = await getAction('/selfStation/saveToDB', { const { success, message, result } = await getAction('/selfStation/saveToDB', {
fileName, fileName,
comment: sampleData.data.comment, comment: sampleData.data.comment
}) })
if (success) { if (success) {
Object.entries(result).forEach(([k, v]) => { Object.entries(result).forEach(([k, v]) => {
@ -660,7 +698,7 @@ export default {
updateSampleData({ updateSampleData({
inputFileName: fileName, inputFileName: fileName,
key: `${k}.spectrumData`, key: `${k}.spectrumData`,
data: v, data: v
}) })
}) })
@ -670,6 +708,21 @@ export default {
} }
}, },
confirm() {
return new Promise((resolve, reject) => {
this.$confirm({
title: 'Save Changes?',
content: "You have modified the channel addresses but haven't updated yet. Do you want to save directly?",
onOk: async () => {
resolve()
},
onCancel: () => {
reject('cancel')
}
})
})
},
// ARRRRR // ARRRRR
showArrRRRModal(type) { showArrRRRModal(type) {
this.$refs.ARR_RRRModalRef.show(type) this.$refs.ARR_RRRModalRef.show(type)
@ -689,8 +742,8 @@ export default {
showBgLogViewer() { showBgLogViewer() {
this.$refs.bgLogViewerRef.show() this.$refs.bgLogViewerRef.show()
}, }
}, }
} }
</script> </script>
@ -784,15 +837,31 @@ export default {
.ant-input-group { .ant-input-group {
display: flex; display: flex;
gap: 5px;
background-color: #04414d; background-color: #04414d;
border: solid 1px #0b8c82; border: solid 1px #0b8c82;
padding: 0 5px;
> div {
width: 110px;
display: flex;
gap: 5px;
align-items: center;
span {
color: #f00;
flex-shrink: 0;
max-width: 75px;
}
}
} }
&-input { &-input {
width: 80px; flex: 1;
text-align: center; text-align: center;
border: 0; border: 0;
background: transparent; background: transparent;
padding: 0;
} }
&-split { &-split {
@ -819,4 +888,8 @@ export default {
} }
// //
</style>
.is-changed {
color: #f00;
}
</style>

View File

@ -54,12 +54,15 @@
:selectedRowKeys.sync="selectedKeys" :selectedRowKeys.sync="selectedKeys"
rowKey="index" rowKey="index"
:canDeselect="false" :canDeselect="false"
:custom-row-class-name="rowClassName"
@rowClick="handleTableRowClick" @rowClick="handleTableRowClick"
> >
</custom-table> </custom-table>
<div class="operators"> <div class="operators">
<a-select v-model="currROIIndex" style="flex: 1" @change="setInfoByType"> <a-select v-model="currROIIndex" style="flex: 1" @change="setInfoByType">
<a-select-option v-for="(_, index) in 4" :value="index" :key="index">ROI{{ _ }}</a-select-option> <a-select-option v-for="(_, index) in nuclideNames" :value="index" :key="index">
ROI{{ index + 1 }}
</a-select-option>
</a-select> </a-select>
<a-button type="primary" @click="nuclideReviewModalVisible = true">Nuclide Review Window</a-button> <a-button type="primary" @click="nuclideReviewModalVisible = true">Nuclide Review Window</a-button>
<a-button type="primary" @click="handleAddPeakComment()">Add Peak Comment</a-button> <a-button type="primary" @click="handleAddPeakComment()">Add Peak Comment</a-button>
@ -127,6 +130,7 @@
</title-over-border> </title-over-border>
<div class="reset-btn-box"> <div class="reset-btn-box">
<a-button type="primary" @click="handleResetChart">Reset Chart</a-button> <a-button type="primary" @click="handleResetChart">Reset Chart</a-button>
<a-button type="primary" :loading="isApplying" @click="handleApply">Apply</a-button>
</div> </div>
<div class="identify-box"> <div class="identify-box">
<title-over-border title="Nuclide Identify"> <title-over-border title="Nuclide Identify">
@ -243,7 +247,7 @@ const initialOption = {
top: 40, top: 40,
left: 80, left: 80,
right: 30, right: 30,
bottom: 30, bottom: 30
}, },
title: { title: {
text: '', text: '',
@ -254,39 +258,39 @@ const initialOption = {
rich: { rich: {
a: { a: {
padding: [0, 20, 0, 0], padding: [0, 20, 0, 0],
fontSize: 16, fontSize: 16
}, }
}, }
}, }
}, },
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
axisPointer: { axisPointer: {
lineStyle: { lineStyle: {
color: '#3CAEBB', color: '#3CAEBB',
width: 1, width: 1
}, }
}, },
formatter: undefined, formatter: undefined,
className: 'figure-chart-option-tooltip', className: 'figure-chart-option-tooltip'
}, },
xAxis: { xAxis: {
axisLine: { axisLine: {
lineStyle: { lineStyle: {
color: '#ade6ee', color: '#ade6ee'
}, }
}, },
splitLine: { splitLine: {
show: false, show: false
}, },
axisLabel: { axisLabel: {
textStyle: { textStyle: {
color: '#ade6ee', color: '#ade6ee'
}, }
}, },
min: 1, min: 1,
max: 'dataMax', max: 'dataMax',
animation: false, animation: false
}, },
yAxis: { yAxis: {
type: 'log', type: 'log',
@ -295,31 +299,31 @@ const initialOption = {
nameGap: 40, nameGap: 40,
nameTextStyle: { nameTextStyle: {
color: '#8FD4F8', color: '#8FD4F8',
fontSize: 16, fontSize: 16
}, },
axisLine: { axisLine: {
show: true, show: true,
lineStyle: { lineStyle: {
color: '#ade6ee', color: '#ade6ee'
}, }
}, },
splitLine: { splitLine: {
show: true, show: true,
lineStyle: { lineStyle: {
color: 'rgba(173, 230, 238, .2)', color: 'rgba(173, 230, 238, .2)'
}, }
}, },
axisLabel: { axisLabel: {
textStyle: { textStyle: {
color: '#ade6ee', color: '#ade6ee'
}, }
}, },
min: 0.1, min: 0.1,
max: 'dataMax', max: 'dataMax',
animation: false, animation: false
}, },
series: [], series: [],
brush: {}, brush: {}
} }
const columns = [ const columns = [
@ -328,62 +332,62 @@ const columns = [
customRender: (_, __, index) => { customRender: (_, __, index) => {
return index + 1 return index + 1
}, },
width: 60, width: 60
}, },
{ {
title: 'Energy (keV)', title: 'Energy (keV)',
dataIndex: 'energy', dataIndex: 'energy',
width: 120, width: 120,
customRender: (text) => { customRender: text => {
return text.toFixed(3) return text.toFixed(3)
}, }
}, },
{ {
title: 'Centroid (C)', title: 'Centroid (C)',
dataIndex: 'peakCentroid', dataIndex: 'peakCentroid',
width: 120, width: 120,
customRender: (text) => { customRender: text => {
return text.toFixed(3) return text.toFixed(3)
}, }
}, },
{ {
title: 'FWHM (keV)', title: 'FWHM (keV)',
dataIndex: 'fwhm', dataIndex: 'fwhm',
width: 120, width: 120,
customRender: (text) => { customRender: text => {
return text.toFixed(3) return text.toFixed(3)
}, }
}, },
{ {
title: 'Area', title: 'Area',
dataIndex: 'area', dataIndex: 'area',
width: 120, width: 120,
customRender: (text) => { customRender: text => {
return text.toFixed(3) return text.toFixed(3)
}, }
}, },
{ {
title: 'Detectability', title: 'Detectability',
dataIndex: 'significance', dataIndex: 'significance',
width: 120, width: 120,
customRender: (text) => { customRender: text => {
return text == 'Infinity' ? 'inf' : text.toFixed(3) return text == 'Infinity' ? 'inf' : text.toFixed(3)
}, }
}, },
{ {
title: '#Cmnt', title: '#Cmnt',
dataIndex: 'comments', dataIndex: 'comments',
width: 120, width: 120
}, },
{ {
title: 'Nuclides', title: 'Nuclides',
dataIndex: 'nuclides', dataIndex: 'nuclides',
width: 120, width: 120,
ellipsis: true, ellipsis: true,
customRender: (text) => { customRender: text => {
return text && text.join(';') return text && text.join(';')
}, }
}, }
] ]
// //
@ -392,48 +396,48 @@ const thumbnailOption = {
top: 0, top: 0,
left: 0, left: 0,
right: 0, right: 0,
bottom: 0, bottom: 0
}, },
xAxis: { xAxis: {
type: 'category', type: 'category',
axisLine: { axisLine: {
lineStyle: { lineStyle: {
color: '#fff', color: '#fff'
}, }
}, },
splitLine: { splitLine: {
show: false, show: false
}, },
axisLabel: { axisLabel: {
show: false, show: false
}, },
axisTick: { axisTick: {
show: false, show: false
}, },
min: 1, min: 1,
max: 'dataMax', max: 'dataMax'
}, },
yAxis: { yAxis: {
type: 'value', type: 'value',
axisLine: { axisLine: {
show: false, show: false
}, },
splitLine: { splitLine: {
show: false, show: false
}, },
axisLabel: { axisLabel: {
show: false, show: false
}, },
max: 0, max: 0,
min: 0, min: 0
}, },
series: null, series: null
} }
const nuclideIdentifyModal = { const nuclideIdentifyModal = {
possibleNuclide: '', possibleNuclide: '',
tolerance: 0.5, tolerance: 0.5,
identifiedNuclide: '', identifiedNuclide: ''
} }
// //
@ -441,9 +445,12 @@ const Operators = {
ADD: 1, // ADD: 1, //
REMOVE: 2, // REMOVE: 2, //
MODIFY: 3, // MODIFY: 3, //
SLOPE_CHANGE: 4, // slope SLOPE_CHANGE: 4 // slope
} }
//
const nuclideNames = ['Xe131M', 'Xe131M', 'Xe133', 'Xe135']
export default { export default {
mixins: [SampleDataMixin], mixins: [SampleDataMixin],
components: { components: {
@ -454,13 +461,13 @@ export default {
NuclideReviewModal, NuclideReviewModal,
GeneralCommentModal, GeneralCommentModal,
EditSlopeModal, EditSlopeModal,
RectList, RectList
}, },
props: { props: {
colorConfig: { colorConfig: {
type: Object, type: Object,
default: () => ({}), default: () => ({})
}, }
}, },
data() { data() {
return { return {
@ -469,7 +476,7 @@ export default {
columns, columns,
searchParam: { searchParam: {
energy: '', energy: '',
tolerance: '', tolerance: ''
}, },
option: cloneDeep(initialOption), option: cloneDeep(initialOption),
opts: { notMerge: false }, opts: { notMerge: false },
@ -515,10 +522,13 @@ export default {
replotNeeded: false, replotNeeded: false,
currROIIndex: 0, currROIIndex: 0,
isApplying: false
} }
}, },
created() { created() {
this.option.tooltip.formatter = (params) => { this.nuclideNames = nuclideNames
this.option.tooltip.formatter = params => {
const channel = parseInt(params[0].value[0]) const channel = parseInt(params[0].value[0])
const energy = this.energy.pointlist ? this.energy.pointlist[channel - 1].x : 0 const energy = this.energy.pointlist ? this.energy.pointlist[channel - 1].x : 0
return `<div class="channel">Channel: ${channel}</div> return `<div class="channel">Channel: ${channel}</div>
@ -531,6 +541,13 @@ export default {
this.$bus.$off('selfAnalyzeSampleTypeChange', this.selfAnalyzeSampleTypeChange) this.$bus.$off('selfAnalyzeSampleTypeChange', this.selfAnalyzeSampleTypeChange)
}, },
methods: { methods: {
rowClassName({ record }) {
const nuclides = record.nuclides || []
return -1 !== nuclides.findIndex(item => item.toLowerCase() == nuclideNames[this.currROIIndex].toLowerCase())
? 'has-nuclide'
: ''
},
// SampleType // SampleType
selfAnalyzeSampleTypeChange(sampleType) { selfAnalyzeSampleTypeChange(sampleType) {
this.sampleType = sampleType this.sampleType = sampleType
@ -582,7 +599,7 @@ export default {
this.channelBaseLineChart = {} this.channelBaseLineChart = {}
this.channelCountChart = { this.channelCountChart = {
color: 'yellow', color: 'yellow',
pointlist: currROIItem, pointlist: currROIItem
} }
this.channelPeakChart = [] this.channelPeakChart = []
this.energy = [] this.energy = []
@ -599,7 +616,7 @@ export default {
baseline: [], baseline: [],
baseStack: [], baseStack: [],
replotUsed: false, replotUsed: false,
stepCounts: [], stepCounts: []
} }
this.list = [] this.list = []
@ -693,7 +710,7 @@ export default {
left = channel left = channel
} }
const peaksBetweenChannel = this.list.filter((peak) => { const peaksBetweenChannel = this.list.filter(peak => {
const centroidId = peak.peakCentroid const centroidId = peak.peakCentroid
return centroidId >= left && centroidId <= right return centroidId >= left && centroidId <= right
}) })
@ -753,7 +770,7 @@ export default {
*/ */
adjustArea() { adjustArea() {
const { const {
xAxis: { max, min }, xAxis: { max, min }
} = this.option } = this.option
// //
@ -775,7 +792,7 @@ export default {
if (find.x >= min && find.x <= max) { if (find.x >= min && find.x <= max) {
peaks.push({ peaks.push({
max: peakMaxY, max: peakMaxY,
min: Math.min(pointlist[0].y, pointlist[pointlist.length - 1].y), min: Math.min(pointlist[0].y, pointlist[pointlist.length - 1].y)
}) })
} }
} }
@ -784,7 +801,7 @@ export default {
const peaksMin = Math.min(...peaks.map(({ min }) => min)) const peaksMin = Math.min(...peaks.map(({ min }) => min))
const { const {
yAxis: { max: yAxisMax, min: yAxisMin }, yAxis: { max: yAxisMax, min: yAxisMin }
} = this.option } = this.option
if (peaksMax > yAxisMax) { if (peaksMax > yAxisMax) {
@ -842,7 +859,7 @@ export default {
sampleId, sampleId,
channel: Math.round(row.peakCentroid), channel: Math.round(row.peakCentroid),
fileName, fileName,
gammaROINum: this.currROIIndex + 1, gammaROINum: this.currROIIndex + 1
}) })
if (success) { if (success) {
const { possible } = result const { possible } = result
@ -867,7 +884,7 @@ export default {
sampleId, sampleId,
fileName, fileName,
...this.searchParam, ...this.searchParam,
gammaROINum: this.currROIIndex + 1, gammaROINum: this.currROIIndex + 1
}) })
if (success) { if (success) {
const { list } = result const { list } = result
@ -922,7 +939,7 @@ export default {
shadowEnergyChart, shadowEnergyChart,
shapeChannelData, shapeChannelData,
shapeEnergyData, shapeEnergyData,
table, table
} = result } = result
this.$bus.$emit( this.$bus.$emit(
@ -936,7 +953,7 @@ export default {
shapeEnergyData, shapeEnergyData,
peak: table, peak: table,
barChart: this.barChart, barChart: this.barChart,
BaseCtrls: cloneDeep(this.BaseCtrls), BaseCtrls: cloneDeep(this.BaseCtrls)
}, },
this.currROIIndex this.currROIIndex
) )
@ -986,8 +1003,8 @@ export default {
content: 'Are you sure to delete this peak?', content: 'Are you sure to delete this peak?',
cancelButtonProps: { cancelButtonProps: {
props: { props: {
type: 'warn', type: 'warn'
}, }
}, },
onOk: async () => { onOk: async () => {
// this.list.splice(findIndex, 1) // this.list.splice(findIndex, 1)
@ -1009,7 +1026,7 @@ export default {
const { success, result, message } = await getAction('/selfStation/deletePeak', { const { success, result, message } = await getAction('/selfStation/deletePeak', {
fileName, fileName,
curRow: this.curRow, curRow: this.curRow,
gammaROINum: this.currROIIndex + 1, gammaROINum: this.currROIIndex + 1
}) })
if (success) { if (success) {
const { const {
@ -1019,7 +1036,7 @@ export default {
shadowEnergyChart, shadowEnergyChart,
shapeChannelData, shapeChannelData,
shapeEnergyData, shapeEnergyData,
table, table
} = result } = result
this.$bus.$emit( this.$bus.$emit(
@ -1033,7 +1050,7 @@ export default {
shapeEnergyData, shapeEnergyData,
peak: table, peak: table,
barChart: this.barChart, barChart: this.barChart,
BaseCtrls: cloneDeep(this.BaseCtrls), BaseCtrls: cloneDeep(this.BaseCtrls)
}, },
this.currROIIndex this.currROIIndex
) )
@ -1069,7 +1086,7 @@ export default {
} catch (error) { } catch (error) {
console.error(error) console.error(error)
} }
}, }
}) })
}, },
@ -1136,8 +1153,8 @@ export default {
key: 'brush', key: 'brush',
brushOption: { brushOption: {
// brush brushType false // brush brushType false
brushType: 'rect', brushType: 'rect'
}, }
}) })
}, },
@ -1152,12 +1169,12 @@ export default {
// //
chart.dispatchAction({ chart.dispatchAction({
type: 'brush', type: 'brush',
areas: [], areas: []
}) })
// //
chart.dispatchAction({ chart.dispatchAction({
type: 'takeGlobalCursor', type: 'takeGlobalCursor'
}) })
}, },
@ -1168,8 +1185,8 @@ export default {
if (areas) { if (areas) {
const range = areas.range const range = areas.range
const [[minX, maxX], [minY, maxY]] = range const [[minX, maxX], [minY, maxY]] = range
const point1 = chart.convertFromPixel({ seriesIndex: 0 }, [minX, minY]).map((num) => parseInt(num.toFixed())) const point1 = chart.convertFromPixel({ seriesIndex: 0 }, [minX, minY]).map(num => parseInt(num.toFixed()))
const point2 = chart.convertFromPixel({ seriesIndex: 0 }, [maxX, maxY]).map((num) => parseInt(num.toFixed())) const point2 = chart.convertFromPixel({ seriesIndex: 0 }, [maxX, maxY]).map(num => parseInt(num.toFixed()))
const xAxisMax = chart.getModel().getComponent('xAxis').axis.scale._extent[1] const xAxisMax = chart.getModel().getComponent('xAxis').axis.scale._extent[1]
const yAxisMax = this.option.yAxis.max const yAxisMax = this.option.yAxis.max
let [x1, y2, x2, y1] = [...point1, ...point2] // let [x1, y2, x2, y1] = [...point1, ...point2] //
@ -1221,6 +1238,28 @@ export default {
} }
}, },
//
async handleApply() {
try {
this.isApplying = true
const { sampleId, inputFileName: fileName } = this.sampleData
const { success, message, result } = await getAction('/selfStation/recalculateActivity', {
fileName,
sampleId
})
if (success) {
const { XeData } = result
this.$bus.$emit('selfUpdateXeData', XeData)
} else {
this.$message.error(message || 'Apply failed!')
}
} catch (error) {
console.log(error)
} finally {
this.isApplying = false
}
},
// //
handleSwitchOperation() { handleSwitchOperation() {
// Base Line Control Point // Base Line Control Point
@ -1235,7 +1274,7 @@ export default {
this.baseCtrls_Copy.baseline.map((val, index) => [index + 1, val]), this.baseCtrls_Copy.baseline.map((val, index) => [index + 1, val]),
this.colorConfig.Color_Fitbase || '#fff', this.colorConfig.Color_Fitbase || '#fff',
{ {
zlevel: 21, zlevel: 21
} }
) )
this.option.series.push(baseLineEditSeries) this.option.series.push(baseLineEditSeries)
@ -1249,7 +1288,7 @@ export default {
this.btnGroupType = 1 this.btnGroupType = 1
this.opts.notMerge = true this.opts.notMerge = true
const baseLineEditSeries = findSeriesByName(this.option.series, 'BaseLine_Edit') const baseLineEditSeries = findSeriesByName(this.option.series, 'BaseLine_Edit')
const index = this.option.series.findIndex((item) => item == baseLineEditSeries) const index = this.option.series.findIndex(item => item == baseLineEditSeries)
this.option.series.splice(index, 1) this.option.series.splice(index, 1)
this.clearRect() this.clearRect()
@ -1295,7 +1334,7 @@ export default {
this.isModifying = false this.isModifying = false
this.pushOperationStack(Operators.MODIFY, { this.pushOperationStack(Operators.MODIFY, {
index, index,
prevYAxis, prevYAxis
}) })
}, },
@ -1319,7 +1358,7 @@ export default {
// Peaks // Peaks
redrawPeaks(peakList) { redrawPeaks(peakList) {
this.option.series = this.option.series.filter((item) => { this.option.series = this.option.series.filter(item => {
return !item.name.includes('Peak_') return !item.name.includes('Peak_')
}) })
this.option.series.push(...this.buildPeaks(peakList)) this.option.series.push(...this.buildPeaks(peakList))
@ -1395,7 +1434,7 @@ export default {
index: i, index: i,
removeXAxis, removeXAxis,
removeYAxis, removeYAxis,
removeYSlope, removeYSlope
}) })
}, },
@ -1431,7 +1470,7 @@ export default {
this.$refs.editSlopeModal.open({ this.$refs.editSlopeModal.open({
index: i, index: i,
value: yslope[i], value: yslope[i],
allowNaN: !(i == 0 || i == n - 1), allowNaN: !(i == 0 || i == n - 1)
}) })
}, },
@ -1445,7 +1484,7 @@ export default {
yslope[index] = slope yslope[index] = slope
this.pushOperationStack(Operators.SLOPE_CHANGE, { this.pushOperationStack(Operators.SLOPE_CHANGE, {
index, index,
slope: prevSlope, slope: prevSlope
}) })
this.redrawBaseLine() this.redrawBaseLine()
this.buildRect() this.buildRect()
@ -1469,7 +1508,7 @@ export default {
...this.baseCtrls_Copy, ...this.baseCtrls_Copy,
fileName, fileName,
replotNeeded: this.replotNeeded, replotNeeded: this.replotNeeded,
gammaROINum: this.currROIIndex + 1, gammaROINum: this.currROIIndex + 1
}) })
if (success) { if (success) {
const { chartData, peakSet, shapeData } = result const { chartData, peakSet, shapeData } = result
@ -1488,8 +1527,8 @@ export default {
color, color,
point: { point: {
x: xAxis, x: xAxis,
y: yctrl[index], y: yctrl[index]
}, }
} }
}) })
baseLineCP.data = this.buildCPPointData(baseCPPoints) baseLineCP.data = this.buildCPPointData(baseCPPoints)
@ -1522,8 +1561,8 @@ export default {
itemStyle: { itemStyle: {
color: 'transparent', color: 'transparent',
borderColor: color, borderColor: color,
borderWidth: size / 2, borderWidth: size / 2
}, }
} }
}) })
}, },
@ -1536,7 +1575,7 @@ export default {
const { success, result, message } = await postAction('/selfStation/acceptBaseLine', { const { success, result, message } = await postAction('/selfStation/acceptBaseLine', {
...this.baseCtrls_Copy, ...this.baseCtrls_Copy,
fileName, fileName,
gammaROINum: this.currROIIndex + 1, gammaROINum: this.currROIIndex + 1
}) })
if (success) { if (success) {
this.BaseCtrls = cloneDeep(this.baseCtrls_Copy) this.BaseCtrls = cloneDeep(this.baseCtrls_Copy)
@ -1550,7 +1589,7 @@ export default {
shadowEnergyChart, shadowEnergyChart,
shapeChannelData, shapeChannelData,
shapeData, shapeData,
shapeEnergyData, shapeEnergyData
} = result } = result
this.channelBaseLineChart = channelBaseLineChart this.channelBaseLineChart = channelBaseLineChart
@ -1572,7 +1611,7 @@ export default {
'selfAccept', 'selfAccept',
{ {
...result, ...result,
BaseCtrls: cloneDeep(this.baseCtrls_Copy), BaseCtrls: cloneDeep(this.baseCtrls_Copy)
}, },
this.currROIIndex this.currROIIndex
) )
@ -1626,7 +1665,7 @@ export default {
if (this.selectedTableItem._deleting) { if (this.selectedTableItem._deleting) {
return return
} }
const findIndex = nuclides.findIndex((nuclide) => nuclide == this.model.identifiedNuclide) const findIndex = nuclides.findIndex(nuclide => nuclide == this.model.identifiedNuclide)
if (-1 !== findIndex) { if (-1 !== findIndex) {
try { try {
this.$set(this.selectedTableItem, '_deleting', true) this.$set(this.selectedTableItem, '_deleting', true)
@ -1636,7 +1675,7 @@ export default {
nuclideName: this.model.identifiedNuclide, nuclideName: this.model.identifiedNuclide,
fileName, fileName,
list_identify: nuclides, list_identify: nuclides,
gammaROINum: this.currROIIndex + 1, gammaROINum: this.currROIIndex + 1
}) })
if (success) { if (success) {
const { identify, table } = result const { identify, table } = result
@ -1664,15 +1703,15 @@ export default {
silent: true, silent: true,
symbol: 'none', symbol: 'none',
label: { label: {
show: false, show: false
}, },
lineStyle: { lineStyle: {
color: 'red', color: 'red',
width: 1, width: 1
}, },
data: [{ xAxis: -1 }], data: [{ xAxis: -1 }]
}, },
zlevel: 10, zlevel: 10
} }
) )
}, },
@ -1697,7 +1736,7 @@ export default {
data: this.buildCPPointData(channelBaseCPChart), data: this.buildCPPointData(channelBaseCPChart),
silent: true, silent: true,
animation: false, animation: false,
zlevel: 20, zlevel: 20
} }
}, },
@ -1708,18 +1747,18 @@ export default {
type: 'bar', type: 'bar',
data: barChart.map(({ x, y }) => [x, y]), data: barChart.map(({ x, y }) => [x, y]),
itemStyle: { itemStyle: {
color: '#fff', color: '#fff'
}, },
lineStyle: { lineStyle: {
width: 1, width: 1
}, },
symbol: 'none', symbol: 'none',
symbolSize: 1, symbolSize: 1,
emphasis: { emphasis: {
disabled: true, disabled: true
}, },
animation: false, animation: false,
silent: true, silent: true
} }
}, },
@ -1731,7 +1770,7 @@ export default {
pushOperationStack(operator, operand) { pushOperationStack(operator, operand) {
this.operationStack.push({ this.operationStack.push({
operator, operator,
operand, operand
}) })
}, },
@ -1780,19 +1819,19 @@ export default {
handleFullScreenChange(isFullScreen) { handleFullScreenChange(isFullScreen) {
this.columns[7].width = isFullScreen ? 180 : 120 this.columns[7].width = isFullScreen ? 180 : 120
}, }
}, },
computed: { computed: {
curRow() { curRow() {
const [selectedKey] = this.selectedKeys const [selectedKey] = this.selectedKeys
const findIndex = this.list.findIndex((item) => item.index == selectedKey) const findIndex = this.list.findIndex(item => item.index == selectedKey)
return findIndex return findIndex
}, },
isOperationStackEmpty() { isOperationStackEmpty() {
return this.operationStack.length == 0 return this.operationStack.length == 0
}, }
}, }
} }
</script> </script>
@ -1894,6 +1933,8 @@ export default {
.reset-btn-box { .reset-btn-box {
margin-top: 20px; margin-top: 20px;
margin-bottom: 30px; margin-bottom: 30px;
display: flex;
gap: 10px;
} }
.identify-box { .identify-box {
@ -2055,4 +2096,8 @@ export default {
} }
} }
} }
.ant-table-tbody tr.has-nuclide {
color: yellow;
}
</style> </style>