AnalysisSystemForRadionucli.../src/views/spectrumAnalysis/components/Modals/KorsumModal.vue

571 lines
15 KiB
Vue

<template>
<custom-modal v-model="visible" title="Korsum" :width="1120" :footer="null">
<a-spin :spinning="isLoading">
<div class="korsum">
<!-- 输入开始 -->
<title-over-border title="Input">
<div class="korsum-input">
<!-- 公式部分 -->
<a-form-model
class="korsum-input-formula"
:labelCol="{
style: {
width: '110px',
},
}"
>
<a-form-model-item label="Total Effi = exp(">
<!-- 第一行 -->
<div>
<a-input-number v-model="totalEffi.totalEf1"></a-input-number>
<span class="operator">* Er + </span>
<a-input-number v-model="totalEffi.totalEf2"></a-input-number>
<span class="operator">+ </span>
</div>
<!-- 第二行 -->
<div>
<a-input-number v-model="totalEffi.totalEf3"></a-input-number>
<span class="operator">/ Er + </span>
<a-input-number v-model="totalEffi.totalEf4"></a-input-number>
<span class="operator">/ Er <sup>2</sup> + </span>
</div>
<!-- 第三行 -->
<div>
<a-input-number v-model="totalEffi.totalEf5"></a-input-number>
<span class="operator"> / Er <sup>3</sup> + </span>
<a-input-number v-model="totalEffi.totalEf6"></a-input-number>
<span class="operator">/ Er <sup>4</sup> ) </span>
</div>
</a-form-model-item>
<a-form-model-item label="Efficiency = exp(">
<!-- 第一行 -->
<div>
<a-input-number v-model="efficiency.effciency1"></a-input-number>
<span class="operator">* Er + </span>
<a-input-number v-model="efficiency.effciency2"></a-input-number>
<span class="operator">+ </span>
</div>
<!-- 第二行 -->
<div>
<a-input-number v-model="efficiency.effciency3"></a-input-number>
<span class="operator">/ Er + </span>
<a-input-number v-model="efficiency.effciency4"></a-input-number>
<span class="operator">/ Er <sup>2</sup> + </span>
</div>
<!-- 第三行 -->
<div>
<a-input-number v-model="efficiency.effciency5"></a-input-number>
<span class="operator"> / Er <sup>3</sup> + </span>
<a-input-number v-model="efficiency.effciency6"></a-input-number>
<span class="operator">/ Er <sup>4</sup> ) </span>
</div>
</a-form-model-item>
</a-form-model>
<!-- 公式结束 -->
<!-- 标题 -->
<a-button type="primary" class="korsum-input-title" @click="handleInput"> Input </a-button>
<!-- 标题结束 -->
<!-- 表格开始 -->
<a-table
class="korsum-input-table"
:class="list.length ? 'has-data' : ''"
:columns="columns"
:dataSource="list"
:scroll="{ y: 288 }"
:pagination="false"
>
<template slot="energy" slot-scope="text, record">
<a-input-number v-model="record.energy"></a-input-number>
</template>
<template slot="totalEffi" slot-scope="text, record">
<a-input-number v-model="record.totalEffi"></a-input-number>
</template>
<template slot="peakEffi" slot-scope="text, record">
<a-input-number v-model="record.peakEffi"></a-input-number>
</template>
<template slot="uncertain" slot-scope="text, record">
<a-input-number v-model="record.uncertain"></a-input-number>
</template>
</a-table>
<!-- 表格结束 -->
<!-- 按钮开始 -->
<div class="korsum-input-buttons">
<a-button type="primary" @click="handleAnalyze">Analyse</a-button>
<a-button type="primary" @click="handleExit">Exit</a-button>
</div>
<!-- 按钮结束 -->
</div>
</title-over-border>
<!-- 输入结束 -->
<!-- 输出开始 -->
<title-over-border title="Output">
<div class="korsum-output">
<div class="korsum-output-main">
<div class="korsum-output-list">
<div
class="korsum-output-list-item"
:class="selectedItem == item ? 'active' : ''"
v-for="(item, index) in outputList"
:key="index"
@click="handleOutputItemClick(item)"
>
{{ item }}
</div>
</div>
<a-table
class="korsum-output-table"
:columns="outputColumns"
:dataSource="outputTableList"
:class="outputTableList.length ? 'has-data' : ''"
:scroll="{ y: 584 }"
:pagination="false"
>
<template v-for="(col, i) in outputColumns" :slot="col.dataIndex" slot-scope="text, record, index">
<edit-cell
:text="parseFloat(Number(text).toPrecision(6))"
:key="i"
@change="onCellChange(index, col.dataIndex, $event)"
/>
</template>
</a-table>
</div>
<div class="korsum-output-operation">
<div class="left">
<a-input v-model="filterWord"></a-input>
</div>
<div class="right">
<a-button type="primary" @click="handleExport">Export to Excel</a-button>
</div>
</div>
</div>
</title-over-border>
<!-- 输出结束 -->
</div>
</a-spin>
</custom-modal>
</template>
<script>
import ModalMixin from '@/mixins/ModalMixin'
import TitleOverBorder from '../TitleOverBorder.vue'
import { getAction, postAction } from '@/api/manage'
import * as XLSX from 'xlsx'
import EditCell from './EditCell.vue'
const columns = [
{
title: 'Energy',
dataIndex: 'energy',
scopedSlots: {
customRender: 'energy',
},
},
{
title: 'Total Efficiency',
dataIndex: 'totalEffi',
scopedSlots: {
customRender: 'totalEffi',
},
},
{
title: 'Peak Efficiency',
dataIndex: 'peakEffi',
scopedSlots: {
customRender: 'peakEffi',
},
},
{
title: 'Uncertainty(%)',
dataIndex: 'uncertain',
scopedSlots: {
customRender: 'uncertain',
},
},
]
const outputColumns = [
{
title: 'Energy',
dataIndex: 'energy',
scopedSlots: { customRender: 'energy' },
// customRender: (text) => parseFloat(Number(text).toPrecision(6))
},
{
title: 'Correct Factor',
dataIndex: 'correctFactor',
scopedSlots: { customRender: 'correctFactor' },
// customRender: (text) => parseFloat(Number(text).toPrecision(6)),
},
{
title: 'Uncertainty(%)',
dataIndex: 'uncertainty',
scopedSlots: { customRender: 'uncertainty' },
// customRender: (text) => parseFloat(Number(text).toPrecision(6)),
},
]
export default {
components: { TitleOverBorder, EditCell },
mixins: [ModalMixin],
data() {
this.columns = columns
this.outputColumns = outputColumns
return {
isLoading: false,
totalEffi: {},
efficiency: {},
list: [],
nuclideList: [],
selectedItem: {}, // output中左侧选中的项
outputTableList: [], // output中表格列表数据
filterWord: '', // 筛选
fileName: '', // save excel name
analyseData: {}, // 分析结果
}
},
methods: {
async getInfo() {
try {
this.isLoading = true
const { success, result, message } = await getAction('/gamma/Korsum')
this.isLoading = false
if (success) {
const { Energy, Nuclide } = result
this.list = Energy
this.nuclideList = Nuclide
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
}
},
beforeModalOpen() {
this.totalEffi = {
totalEf1: -0.024326,
totalEf2: -1.857587,
totalEf3: 0.111096,
totalEf4: -0.003896,
totalEf5: -0.000345,
totalEf6: 0.000017,
}
this.efficiency = {
effciency1: -0.329812,
effciency2: -3.493192,
effciency3: 0.583265,
effciency4: -0.065884,
effciency5: 0.003255,
effciency6: -0.000059,
}
this.getInfo()
},
async handleInput() {
if (Object.entries(this.totalEffi).some(([_, v]) => !v) || Object.entries(this.efficiency).some(([_, v]) => !v)) {
this.$message.warn('Please input valid digits in all 12 edit boxes')
return
}
try {
const { success, result, message } = await postAction('/gamma/KorSumInput', {
...this.totalEffi,
...this.efficiency,
energys: this.list.map((item) => item.energy),
})
console.log(success)
if (success) {
this.list = result
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
}
},
// 分析
async handleAnalyze() {
console.log('%c [ 分析 ]-178', 'font-size:13px; background:pink; color:#bf2c9f;')
try {
this.isLoading = true
const { success, result, message } = await postAction('/gamma/KorSumAnalyse', this.list)
this.isLoading = false
if (success) {
this.analyseData = result
console.log(result)
} else {
this.$message.error(message)
}
} catch (error) {
this.isLoading = false
console.error(error)
}
},
// 退出
handleExit() {
this.visible = false
},
// output栏点击左侧列表
handleOutputItemClick(item) {
if (!this.analyseData) {
this.$message.error('Analyse Fail!')
return false
}
this.selectedItem = item
this.outputTableList = []
// 根据核素名获取结果集
let data = this.analyseData[this.selectedItem]
if (!data || data.energy.length < 1) {
this.$message.error('Analyse Fail!')
return false
}
let result = []
for (let i = 0; i < data.energy.length; i++) {
// 将数据进行填充并
let obj = {
energy: data.energy[i],
correctFactor: data.factor[i],
uncertainty: ((data.factor[i] - 1) / 10) * 100,
}
result.push(obj)
}
this.outputTableList = result
},
onCellChange(idx, label, value) {
console.log(this.outputTableList)
console.log(value)
const dataSource = [...this.outputTableList]
const target = dataSource.find((item, index) => index == idx)
if (target) {
target[label] = value
this.outputTableList = dataSource
}
console.log(this.outputTableList)
},
// 导出到excel
handleExport() {
console.log('%c [ 导出到excel ]-246', 'font-size:13px; background:pink; color:#bf2c9f;')
let _this = this
this.$confirm({
title: 'Please enter file name',
content: (h) => <a-input v-model={_this.fileName} />,
okText: 'Cancle',
cancelText: 'Save',
okButtonProps: { style: { backgroundColor: '#b98326', color: '#fff', borderColor: 'transparent' } },
cancelButtonProps: { style: { color: '#fff', backgroundColor: '#31aab0', borderColor: 'transparent' } },
onOk() {
console.log('Cancel')
},
onCancel() {
console.log(_this.fileName)
if (_this.fileName) {
// saveAs(blob, `${_this.fileName}`)
// 创建工作簿
const workbook = XLSX.utils.book_new()
// 创建工作表
const worksheet = XLSX.utils.json_to_sheet(_this.outputTableList)
// 将工作表添加到工作簿
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1')
// 导出Excel文件
XLSX.writeFile(workbook, _this.fileName + '.xlsx')
}
},
})
},
},
computed: {
outputList() {
return this.nuclideList.filter((item) => item.toLowerCase().includes(this.filterWord.toLowerCase()))
},
},
}
</script>
<style lang="less" scoped>
::v-deep {
.title-over-border-content {
height: 711px;
}
}
.korsum {
display: flex;
gap: 20px;
.title-over-border {
flex: 1;
}
&-input {
&-formula {
::v-deep {
.ant-form-item {
margin-bottom: 10px;
&-label {
::after {
content: ' ';
margin: 0 2px;
}
> label {
color: #fff;
}
}
}
}
.ant-input-number {
width: 120px;
}
.operator {
display: inline-block;
width: 46px;
margin: 0 5px;
}
}
&-title {
width: 100%;
margin-bottom: 10px;
}
&-table {
&.has-data {
::v-deep {
.ant-table-body {
height: 288px;
background-color: #06282a;
}
}
}
::v-deep {
.ant-table {
font-size: 14px;
}
.ant-table-placeholder {
height: 289px;
display: flex;
justify-content: center;
align-items: center;
}
}
.ant-input-number {
height: 26px;
::v-deep {
.ant-input-number-input {
height: 26px;
}
}
}
}
&-buttons {
margin-top: 10px;
display: flex;
gap: 20px;
.ant-btn {
flex: 1;
}
}
}
&-output {
height: 100%;
display: flex;
flex-direction: column;
&-main {
display: flex;
gap: 20px;
flex: 1;
}
&-list {
width: 120px;
height: 619px;
background: #275466;
padding: 5px;
overflow: auto;
&-item {
height: 32px;
line-height: 32px;
padding: 0 4px;
cursor: pointer;
&.active {
background-color: @primary-color;
}
}
}
&-table {
flex: 1;
&.has-data {
::v-deep {
.ant-table-body {
height: 584px;
background-color: #06282a;
}
}
}
::v-deep {
.ant-table {
font-size: 14px;
}
.ant-table-placeholder {
height: 585px;
display: flex;
justify-content: center;
align-items: center;
}
}
}
&-operation {
margin-top: 20px;
display: flex;
gap: 20px;
.left {
width: 120px;
}
.right {
flex: 1;
.ant-btn {
width: 100%;
}
}
}
}
}
</style>