WIP: 完成部分弹窗

This commit is contained in:
Xu Zhimeng 2023-07-11 09:10:34 +08:00
parent 194162804e
commit 09e77962d2
8 changed files with 817 additions and 55 deletions

View File

@ -0,0 +1,273 @@
<template>
<custom-modal v-model="visible" :width="1200" title="Interactive Analyse Tools" :okHanlder="handleOk">
<div class="interactive-analysis-tools">
<div class="interactive-analysis-tools-left">
<div class="chart">
<custom-chart :option="option" />
</div>
<div class="table">
<p class="title">
&lt; 6 Peaks with Anthro.Nuclides &gt;
</p>
<custom-table :list="list" :columns="columns"> </custom-table>
<div class="operators">
<a-button type="primary">Nuclide Review Window</a-button>
<a-button type="primary">Add Peak Comment</a-button>
<a-button type="primary">Add General Comment</a-button>
</div>
</div>
</div>
<div class="interactive-analysis-tools-right">
<title-over-boarder title="Peak">
<div class="peak-box">
<div class="peak-box-item">
<a-button type="primary">Insert</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary">Delete</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary">Fit</a-button>
</div>
<div class="peak-box-item symbol">
<a-button type="primary">&lt;</a-button>
<a-button type="primary">&gt;</a-button>
</div>
</div>
<div class="base-line">
<a-button type="primary">BaseLine</a-button>
</div>
</title-over-boarder>
<div class="reset-btn-box">
<a-button type="primary">Reset Chart</a-button>
</div>
<div class="identify-box">
<title-over-boarder title="Nuclide Identify">
<a-form-model class="tolerance">
<a-form-model-item label="Tolerance">
<a-input-number></a-input-number>
</a-form-model-item>
</a-form-model>
<div class="identify-item">
<div class="title">
Possible Nuclide
</div>
<div class="content"></div>
</div>
<div class="identify-item">
<div class="title">
Nuclide Identified
</div>
<div class="content"></div>
</div>
<div class="identify-operators">
<a-space>
<a-input></a-input>
<a-button type="primary">Add</a-button>
<a-button type="primary">Del</a-button>
</a-space>
</div>
</title-over-boarder>
</div>
</div>
</div>
</custom-modal>
</template>
<script>
import CustomChart from '@/components/CustomChart/index.vue'
import TitleOverBoarder from '../TitleOverBoarder.vue'
const initialOption = {
xAxis: {
min: 1,
max: 8192
},
yAxis: {
min: 1,
max: 994914
}
}
const columns = [
{
title: 'ID'
},
{
title: 'Energy (keV)'
},
{
title: 'Centroid (C)'
},
{
title: 'FWHM (keV)'
},
{
title: 'Area'
},
{
title: 'Detectability'
},
{
title: 'Cmnt'
},
{
title: 'Nuclides'
}
]
export default {
props: {
value: {
type: Boolean
}
},
components: {
CustomChart,
TitleOverBoarder
},
data() {
this.columns = columns
return {
option: initialOption,
list: []
}
},
methods: {
handleOk() {}
},
computed: {
visible: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
}
}
</script>
<style lang="less" scoped>
.interactive-analysis-tools {
display: flex;
&-left {
flex: 1;
margin-right: 20px;
.chart {
height: 275px;
}
.table {
.title {
color: #0cebc9;
font-size: 20px;
text-align: center;
margin-bottom: 10px;
}
.custom-table {
height: 421px;
}
.operators {
display: flex;
margin-top: 10px;
gap: 10px;
.ant-btn {
flex: 1;
}
}
}
}
&-right {
width: 25%;
.peak-box {
&-item {
margin-bottom: 10px;
}
.symbol {
display: flex;
.ant-btn {
flex: 1;
&:first-child {
margin-right: 10px;
}
}
}
}
.base-line {
margin-top: 80px;
}
.reset-btn-box {
margin-top: 20px;
margin-bottom: 30px;
}
.identify-box {
.tolerance {
::v-deep {
.ant-form-item {
margin-bottom: 10px;
&-control-wrapper {
flex: 1;
}
&-control {
width: 100%;
}
}
}
.ant-input-number {
width: 100%;
}
}
.identify-item {
.title {
background-color: #497e9d;
height: 30px;
line-height: 30px;
text-align: center;
font-size: 16px;
}
.content {
height: 80px;
background-color: #275466;
margin: 10px 0;
}
}
.identify-operators {
display: flex;
.ant-btn {
width: 50px;
padding-left: 5px;
padding-right: 5px;
}
}
}
}
.ant-btn {
width: 100%;
}
}
</style>

View File

@ -0,0 +1,193 @@
<template>
<custom-modal
v-model="visible"
:width="900"
title="Analysis Settings"
class="analysis-settings"
:okHanlder="handleOk"
>
<!-- 第一行 -->
<div class="analysis-settings-item">
<title-over-boarder title="Peak Searching">
<a-form-model :colon="false" :labelCol="{ style: { width: '160px' } }">
<a-form-model-item label="ECutAnalysis_Low">
<div class="input-with-unit">
<a-input></a-input>
KeV
</div>
</a-form-model-item>
<a-form-model-item label="ECutAnalysis_High">
<div class="input-with-unit">
<a-input></a-input>
KeV
</div>
</a-form-model-item>
<a-form-model-item label="EnergyTolerance">
<div class="input-with-unit">
<a-input></a-input>
KeV
</div>
</a-form-model-item>
<a-form-model-item label="PSS_low">
<a-input></a-input>
</a-form-model-item>
</a-form-model>
</title-over-boarder>
<title-over-boarder title="Calibration Peak Searching">
<a-form-model :colon="false" :labelCol="{ style: { width: '170px' } }">
<a-form-model-item label="CalibrationPSS_low">
<a-input></a-input>
</a-form-model-item>
<a-form-model-item label="CalibrationPSS_high">
<a-input></a-input>
</a-form-model-item>
<a-form-model-item>
<a-checkbox>
Update Calibration
</a-checkbox>
</a-form-model-item>
<a-form-model-item>
<a-checkbox>
Keep Calibration Peak Search Peaks
</a-checkbox>
</a-form-model-item>
</a-form-model>
</title-over-boarder>
</div>
<!-- 第二行 -->
<div class="analysis-settings-item">
<title-over-boarder title="Baseline Param">
<a-form-model :colon="false" :labelCol="{ style: { width: '90px' } }">
<a-form-model-item label="k_back">
<a-input></a-input>
</a-form-model-item>
<a-form-model-item label="k_alpha">
<a-input></a-input>
</a-form-model-item>
<a-form-model-item label="k_beta">
<a-input></a-input>
</a-form-model-item>
</a-form-model>
</title-over-boarder>
<div>
<a-form-model :colon="false" :labelCol="{ style: { width: '150px' } }">
<title-over-boarder title="BaseImprove">
<a-form-model-item label="BaseImprovePSS">
<a-input></a-input>
</a-form-model-item>
</title-over-boarder>
<title-over-boarder title="LC Computing" style="margin-top: 20px">
<a-form-model-item label="RiskLevelK">
<a-input></a-input>
</a-form-model-item>
</title-over-boarder>
</a-form-model>
</div>
</div>
<!-- 第三行 -->
<div class="analysis-settings-item">
<title-over-boarder title="Activity Reference Time">
<custom-date-picker show-time v-model="formModel.activityReferenceTime"></custom-date-picker>
</title-over-boarder>
<title-over-boarder title="Concentration Reference Time">
<custom-date-picker show-time v-model="formModel.concentrationReferenceTime"></custom-date-picker>
</title-over-boarder>
</div>
</custom-modal>
</template>
<script>
import TitleOverBoarder from '../TitleOverBoarder.vue'
export default {
components: { TitleOverBoarder },
props: {
value: {
type: Boolean
}
},
data() {
return {
formModel: {
activityReferenceTime: undefined,
concentrationReferenceTime: undefined
}
}
},
methods: {
handleOk() {
console.log('%c [ handleOk ]-121', 'font-size:13px; background:pink; color:#bf2c9f;')
}
},
computed: {
visible: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
}
}
</script>
<style lang="less" scoped>
.analysis-settings {
&-item {
display: flex;
&:not(:first-child) {
margin-top: 20px;
}
> div {
flex: 1;
&:first-child {
margin-right: 20px;
}
}
.ant-form {
&-item {
margin-bottom: 0;
&:not(:last-child) {
margin-bottom: 10px;
}
::v-deep {
.ant-form-item {
&-label {
text-align: left;
label {
font-size: 16px;
}
}
&-control-wrapper {
flex: 1;
}
}
}
.ant-input {
height: 26px;
}
.input-with-unit {
display: flex;
align-items: center;
.ant-input {
margin-right: 10px;
}
}
}
}
}
}
</style>

View File

@ -129,7 +129,7 @@ export default {
loadData(arg) {
const params = this.getQueryParams() //
const { startDate, endDate, menuTypes } = params
if (!menuTypes || !menuTypes.length) {
if (!menuTypes) {
this.$message.warn('Please Select SampleType First')
return
}
@ -144,8 +144,6 @@ export default {
return
}
params.menuTypes = menuTypes.join(',')
// 1
if (arg === 1) {
this.ipagination.current = 1
@ -199,13 +197,13 @@ export default {
//
async getStationAndDetectorList(value) {
if (!value || !value.length) {
if (!value) {
return
}
try {
const { success, result, message } = await getAction('/spectrumAnalysis/getDBSearchList', {
menuTypes: value.join(',')
menuTypes: value
})
if (success) {
this.stationList = result.stationCode.map(item => ({ label: item, value: item }))
@ -243,8 +241,11 @@ export default {
type: 'custom-select',
name: 'menuTypes',
props: {
mode: 'multiple',
options: [
{
label: 'All',
value: 'G,B'
},
{
label: 'Gamma',
value: 'G'
@ -254,11 +255,10 @@ export default {
value: 'B'
}
],
maxTagCount: 1,
maxTagPlaceholder: '...'
allowClear: true
},
style: {
width: '23%'
width: '18%'
},
on: {
change: event => {
@ -277,7 +277,7 @@ export default {
allowClear: true
},
style: {
width: '16%'
width: '19%'
}
},
{
@ -291,7 +291,7 @@ export default {
allowClear: true
},
style: {
width: '16%'
width: '19%'
}
},
{
@ -316,7 +316,7 @@ export default {
allowClear: true
},
style: {
width: '15%'
width: '14%'
}
},
{
@ -353,7 +353,7 @@ export default {
allowClear: true
},
style: {
width: '15%'
width: '14%'
}
},
{
@ -374,7 +374,8 @@ export default {
allowClear: true
},
style: {
width: '15%'
width: '16%',
paddingRight: 0
}
},
{
@ -385,7 +386,7 @@ export default {
allowClear: true
},
style: {
width: '20%'
width: '264px'
}
},
{
@ -400,7 +401,8 @@ export default {
]
},
style: {
width: '315px'
width: '305px',
paddingRight: 0
}
},
{

View File

@ -0,0 +1,81 @@
<template>
<custom-modal v-model="visible" title="Save Setting" :width="380" :okHandler="handleOk">
<div class="save-setting">
<div class="save-setting-all">
<a-checkbox v-model="saveAll">
Save All
</a-checkbox>
</div>
<div>
<title-over-boarder title="Format">
<a-radio-group v-model="saveFormat" class="format-radio-group">
<a-radio value="txt">Save as Txt</a-radio>
<a-radio value="excel">Save as Excel</a-radio>
</a-radio-group>
</title-over-boarder>
</div>
</div>
</custom-modal>
</template>
<script>
import { downloadFile } from '../../../../api/manage'
import TitleOverBoarder from '../TitleOverBoarder.vue'
export default {
components: { TitleOverBoarder },
props: {
value: {
type: Boolean
}
},
data() {
return {
saveAll: false,
saveFormat: 'txt'
}
},
methods: {
reset() {
this.saveAll = false
this.saveFormat = 'txt'
},
handleOk() {
console.log('%c [ save ]-22', 'font-size:13px; background:pink; color:#bf2c9f;')
downloadFile('', 'result.' + this.saveFormat, {})
}
},
computed: {
visible: {
set(val) {
this.$emit('input', val)
},
get() {
if (this.value) {
this.reset()
}
return this.value
}
}
}
}
</script>
<style lang="less" scoped>
.save-setting {
display: flex;
align-items: center;
&-all {
width: 65%;
text-align: center;
}
.format-radio-group {
.ant-radio-wrapper:first-child {
margin-bottom: 10px;
}
}
}
</style>

View File

@ -0,0 +1,64 @@
<template>
<a-menu mode="vertical" :style="{ width }" class="multi-level-menu">
<template v-for="(item, index) in children">
<a-menu-item :key="index" v-bind="item.attrs" @click="handleMenuClick(item)">
{{ item.title }}
<div v-if="item.children" :key="index">
<a-menu class="multi-level-menu-sub-menu">
<a-menu-item v-for="child in item.children" :key="child.key" @click="handleSubMenuClick(item, child)">
{{ child.title }}
</a-menu-item>
</a-menu>
</div>
</a-menu-item>
</template>
</a-menu>
</template>
<script>
export default {
props: {
children: {
type: Array,
default: () => []
},
width: {
type: String,
default: 'auto'
}
},
methods: {
handleMenuClick(item) {
if (!item.children) {
this.$emit('menuClick', item)
}
},
handleSubMenuClick(item, child) {
this.$emit('submenuClick', { item, child })
}
}
}
</script>
<style lang="less">
.multi-level-menu {
.ant-menu-item {
overflow: visible;
.multi-level-menu-sub-menu {
position: absolute;
top: 0;
right: 0;
transform: translateX(100%);
display: none;
background: #03353f;
}
&-active {
.multi-level-menu-sub-menu {
display: block;
}
}
}
}
</style>

View File

@ -135,6 +135,10 @@ export default {
}
::v-deep {
.ant-table {
border: none;
}
.ant-table-thead > tr th {
color: #00e9fe;
font-family: MicrosoftYaHei;

View File

@ -0,0 +1,39 @@
<template>
<div class="title-over-border">
<div class="title-over-border-title">{{ title }}</div>
<div class="title-over-border-content">
<slot />
</div>
</div>
</template>
<script>
export default {
props: {
title: {
type: String
}
}
}
</script>
<style lang="less" scoped>
@color: rgba(12, 235, 201, 0.6);
.title-over-border {
border: 1px solid @color;
position: relative;
&-title {
color: @color;
background-color: #022024;
position: absolute;
top: -11px;
left: 10px;
padding: 0 10px;
}
&-content {
padding: 20px;
}
}
</style>

View File

@ -86,6 +86,18 @@
<!-- Nuclide Activity and MDC 弹窗开始 -->
<nuclide-activity-and-mdc-modal v-model="nuclideActivityAndMDCModalVisible" />
<!-- Nuclide Activity and MDC 弹窗结束 -->
<!-- Save Setting 弹窗开始 -->
<save-setting-modal v-model="saveSettingModalVisible" />
<!-- Save Setting 弹窗结束 -->
<!-- 分析-设置弹窗开始 -->
<analyze-setting-modal v-model="analyzeConfigureModalVisible" />
<!-- 分析-设置弹窗结束 -->
<!-- 分析工具弹窗开始 -->
<analyze-interactive-tool-modal v-model="analyzeInteractiveToolModalVisible" />
<!-- 分析工具弹窗结束 -->
</div>
</template>
<script>
@ -103,6 +115,10 @@ import LoadFromDbModal from './components/Modals/LoadFromDBModal.vue'
import LoadFromFileModal from './components/Modals/LoadFromFileModal.vue'
import PeakInfomation from './components/PeakInfomation.vue'
import NuclideActivityAndMdcModal from './components/Modals/NuclideActivityAndMDCModal.vue'
import MultiLevelMenu from './components/MultiLevelMenu.vue'
import SaveSettingModal from './components/Modals/SaveSettingModal.vue'
import AnalyzeSettingModal from './components/Modals/AnalyzeSettingModal.vue'
import AnalyzeInteractiveToolModal from './components/Modals/AnalyzeInteractiveToolModal.vue'
//
const ANALYZE_TYPE = {
@ -124,7 +140,11 @@ export default {
LoadFromDbModal,
LoadFromFileModal,
PeakInfomation,
NuclideActivityAndMdcModal
NuclideActivityAndMdcModal,
MultiLevelMenu,
SaveSettingModal,
AnalyzeSettingModal,
AnalyzeInteractiveToolModal
},
data() {
this.ANALYZE_TYPE = ANALYZE_TYPE
@ -139,12 +159,18 @@ export default {
{ id: 2, name: 'AUX02 003-20151223 1855 S FULL 40183.7.PHD' }
],
loadFromDbModalVisible: false,
loadFromFileModalVisible: false,
loadFromDbModalVisible: false, //
loadFromFileModalVisible: false, //
peakInfomationModalVisible: false,
nuclideActivityAndMDCModalVisible: false
nuclideActivityAndMDCModalVisible: false,
saveSettingModalVisible: false, //
analyzeConfigureModalVisible: false, //
analyzeInteractiveToolModalVisible: true //
}
},
methods: {
@ -163,29 +189,44 @@ export default {
this.spectraList = []
},
//
saveResultsToFile() {
console.log('%c [ saveResultsToFile ]-152', 'font-size:13px; background:pink; color:#bf2c9f;')
//
handleSaveResultsToFile() {
this.saveSettingModalVisible = true
},
//
saveResultsToDB() {
console.log('%c [ saveResultsToDB ]-157', 'font-size:13px; background:pink; color:#bf2c9f;')
/**
* 保存结果到数据库
* @param { 'all' | 'current' } type
*/
handleSaveResultsToDB(type) {
console.log('%c [ saveResultsToDB ]-157', 'font-size:13px; background:pink; color:#bf2c9f;', type)
},
// IMS2.0PHD
savePHDToFile() {
console.log('%c [ savePHDToFile ]-162', 'font-size:13px; background:pink; color:#bf2c9f;')
/**
* 将谱列表中所有谱数据均以IMS2.0格式保存为PHD文件
* 服务端生成文件前端下载
* @param { 'all' | 'current' } type
*/
handleSavePHDToFile(type) {
console.log('%c [ savePHDToFile ]-162', 'font-size:13px; background:pink; color:#bf2c9f;', type)
},
// β-γ
handleAnalyzeCurrSample() {
console.log('%c [ handleAnalyzeCurrSample ]-152', 'font-size:13px; background:pink; color:#bf2c9f;')
//
handleShowConfigureModal() {
this.analyzeConfigureModalVisible = true
},
//
handleAnalyzeAllSample() {
console.log('%c [ handleAnalyzeAllSample ]-156', 'font-size:13px; background:pink; color:#bf2c9f;')
handleProcessing() {
console.log('%c [ handleProcessing ]-156', 'font-size:13px; background:pink; color:#bf2c9f;')
},
handleReprocessAll() {
console.log('%c [ handleReprocessAll ]-216', 'font-size:13px; background:pink; color:#bf2c9f;')
},
//
handleShowInteractiveTool() {
this.analyzeInteractiveToolModalVisible = true
},
//
@ -321,24 +362,53 @@ export default {
title: 'SAVE',
children: [
{
type: 'a-menu',
children: [
{
type: 'a-menu-item',
title: 'Save Results to File',
handler: this.saveResultsToFile
type: 'MultiLevelMenu',
attrs: {
children: [
{
title: 'Save Results to File'
},
{
title: 'Save Results to DB',
children: [
{
title: 'Save Current',
key: 'current'
},
{
title: 'Save All',
key: 'all'
}
]
},
{
title: 'Save PHD to File',
children: [
{
title: 'Save Current',
key: 'current'
},
{
title: 'Save All',
key: 'all'
}
]
}
],
width: '170px'
},
on: {
menuClick: () => {
this.handleSaveResultsToFile()
},
{
type: 'a-menu-item',
title: 'Save Results to DB',
handler: this.saveResultsToDB
},
{
type: 'a-menu-item',
title: 'Save PHD to File',
handler: this.savePHDToFile
submenuClick: ({ item, child }) => {
if (item.title == 'Save Results to DB') {
this.handleSaveResultsToDB(child.key)
} else if (item.title == 'Save PHD to File') {
this.handleSavePHDToFile(child.key)
}
}
]
}
}
]
},
@ -350,13 +420,23 @@ export default {
children: [
{
type: 'a-menu-item',
title: 'Analyze Current Sample',
handler: this.handleAnalyzeCurrSample
title: 'Configure',
handler: this.handleShowConfigureModal
},
{
type: 'a-menu-item',
title: 'Analyze All Sample',
handler: this.handleAnalyzeAllSample
title: 'Processing',
handler: this.handleProcessing
},
{
type: 'a-menu-item',
title: 'Reprocess All',
handler: this.handleReprocessAll
},
{
type: 'a-menu-item',
title: 'Interactive Tool',
handler: this.handleShowInteractiveTool
}
]
}
@ -606,6 +686,30 @@ export default {
position: relative;
border-right: 0;
&-submenu {
&-active {
background-color: #055565 !important;
}
&-title {
height: 30px !important;
line-height: 30px !important;
color: #fff;
margin: 0;
&:active {
background-color: #055565 !important;
}
.ant-menu-submenu-arrow {
&::before,
&::after {
background: #fff !important;
}
}
}
}
&-item {
color: #fff;
font-family: Arial;
@ -614,6 +718,8 @@ export default {
padding: 4px 14px;
height: 30px;
line-height: 22px;
margin: 0 !important;
&:hover {
background-color: #055565 !important;
}