JavaProjectRepo/business-css/frontend/src/views/business/database/criticalData/index.vue
2026-05-19 15:32:39 +08:00

749 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script lang="ts">
export default {
name: "criticalData",
};
</script>
<script setup lang="ts">
import { onMounted, ref, nextTick } from "vue";
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
import { searchCriticalDataPage,addCriticalData,updateCriticalData,deleteCriticalData,deleteBatchCriticalData,exportAllExports} from "@/api/business/database/criticalData";
import { getDictItemById } from '@/api/dict';
import { sizeSchemaAll } from "@/api/business/database/device";
import Page from '@/components/Pagination/page.vue'
import { getToken } from '@/utils/auth'
//获取所有项目列表
const sizeSchemaInfo:any = ref({});
async function getSizeSchemaList(){
let result = await sizeSchemaAll({})
sizeSchemaInfo.value = result
}
const url = import.meta.env.VITE_APP_BASE_API;
// 搜索框
const queryParams:any = ref({
current: 1,
size: 10,
deviceType: ''
});
//分页 总条数
const total = ref()
//定义表格数据
const customAttrsData:any = ref([])
const tableData: any = ref([]);
const multipleSelection = ref([]);
// 表格加载
const loading = ref(false)
function gettableData() {
let params = {
name: input.value,
deviceType: queryParams.value.type,
pageNum: queryParams.value.current,
pageSize: queryParams.value.size,
};
loading.value = true;
searchCriticalDataPage(params).then((result:any) => {
tableData.value = result.records;
result.records.forEach((item:any) => {
item.size = JSON.parse(item.size)
})
total.value = result.total;
loading.value = false;
}).catch((err) => {
loading.value = false;
});
}
//表格多选事件
function handleSelectionChange(val: any) {
multipleSelection.value = val;
}
const menuData:any = ref([])
const sourceTempData:any = ref([])
// 查询字典项
function menuInit() {
let params = {
dictId: 'fe2c3418b8998f4e64d56ab46bfe0fed',
size:99,
current:1
}
getDictItemById(params).then((result: any) => {
menuData.value = result.data.records;
queryParams.value.type = menuData.value[0].itemCode
sourceTempData.value = sizeSchemaInfo.value[queryParams.value.type].fields
gettableData();
}).catch((err: any) => {
});
}
function handleMenu(row:any) {
queryParams.value.type = row.itemCode
sourceTempData.value = sizeSchemaInfo.value[queryParams.value.type].fields
gettableData()
}
const infoForm = ref();
//搜索内容及点击搜索按钮
const input = ref("");
//新建临界数据
const title = ref("");
const info: any = ref({
deviceType: null,
diameter: null,
height: null,
fissileConcentration: null,
isotopicAbundance: null,
keffValue: null,
size: {},
});
const validator1 = (rule: any, value: any, callback: any) => { // 校验数字是否大于0
if (value == null || value === '') {
callback();
return;
}
if (!/^\d+(\.\d+)?$/.test(value)) {
callback(new Error('请输入有效的数字或小数'));
} else if (parseFloat(value) <= 0) {
callback(new Error('数字必须大于 0'));
} else {
callback();
}
}
const validator2 = (rule: any, value: any, callback: any) => {
if (value == null || value === '') {
callback();
return;
}
if (!/^\d+(\.\d+)?$/.test(value)) {
callback(new Error('请输入有效的数字或小数'));
} else if (parseFloat(value) <= 0) {
callback(new Error('请输入小数'));
}else if (parseFloat(value) >= 1) {
callback(new Error('请输入小数'));
} else {
callback();
}
}
const rulesSize = ref({
uConcentration: [
{
validator: validator1,
trigger: 'blur'
}
],
uEnrichment: [
{
validator: validator2,
trigger: 'blur'
}
],
puConcentration: [
{
validator: validator1,
trigger: 'blur'
}
],
ePu238: [
{
validator: validator2,
trigger: 'blur'
}
],
ePu239: [
{
validator: validator2,
trigger: 'blur'
}
],
ePu240: [
{
validator: validator2,
trigger: 'blur'
}
],
ePu241: [
{
validator: validator2,
trigger: 'blur'
}
],
ePu242: [
{
validator: validator2,
trigger: 'blur'
}
],
keffValue: [
{
validator: validator2,
trigger: 'blur'
}
],
})
const rules = ref({...rulesSize.value});
const dialogVisible = ref(false);
function addClick() {
title.value = "新增临界数据";
info.value = {
deviceType: queryParams.value.type,
diameter: null,
height: null,
fissileConcentration: null,
isotopicAbundance: null,
keffValue: null,
size: {},
};
let rulesTemp:any = ref({})
sourceTempData.value.forEach((item:any) => {
info.value.size[item.key] = null
rulesTemp.value['size.' + item.key] = [{
validator: validator1,
trigger: 'blur'
}]
})
rules.value = {...rulesSize.value,...rulesTemp.value}
customAttrsData.value = []
dialogVisible.value = true;
}
//新建临界数据-确认按钮/修改按钮
function confirmClick(formEl: any) {
formEl.validate((valid: any) => {
if (valid) {
if (!info.value.criticalId) {
const params = {
...info.value,
size: JSON.stringify(info.value.size),
}
addCriticalData(params).then((res:any) => {
if(res === true){
gettableData();
dialogVisible.value = false;
}else{
ElMessage({
type: "error",
message: '新增失败',
});
}
});
} else if (info.value.criticalId) {
const params = {
...info.value,
size: JSON.stringify(info.value.size),
}
updateCriticalData(params).then((res:any) => {
if(res === true){
gettableData();
dialogVisible.value = false;
}else{
ElMessage({
type: "error",
message: '修改失败',
});
}
});
} else {
return false;
}
}
});
}
//新建角色-取消按钮
function handleClose() {
dialogVisible.value = false;
if (infoForm.value != null) infoForm.value.resetFields();
}
//修改临界数据
function editClick(row: any) {
title.value = "修改临界数据";
info.value = JSON.parse(JSON.stringify(row));
sourceTempData.value = sizeSchemaInfo.value[queryParams.value.type].fields
if(row.size == null || "object" != typeof row.size){
info.value.size = {}
sourceTempData.value.forEach((item:any) => {
info.value.size[item.key] = null
})
}
dialogVisible.value = true;
}
//删除临界数据
function delAloneClick(row: any) {
ElMessageBox.confirm("确定删除此临界数据吗?", "删除提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
let params = {
id: row.criticalId,
};
deleteCriticalData(params).then(() => {
gettableData();
ElMessage({
type: "success",
message: "删除成功",
});
});
})
}
// 多选删除?
function delClick() {
ElMessageBox.confirm("确定删除已选择临界数据吗?", "删除提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
let id = [] as any[];
multipleSelection.value.forEach((item: any) => {
id.push(item.criticalId)
})
let params = {
ids: id,
};
deleteBatchCriticalData(params.ids).then(() => {
gettableData();
ElMessage({
message: "删除成功",
type: "success",
});
});
});
}
function dateFormat(row: any) {
const daterc = row;
if (daterc != null) {
var date = new Date(daterc);
var year = date.getFullYear();
var month =
date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
// 拼接
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
}
}
function handlePreview(){
// loadingtext.value = "正在导入数据,请耐心等待!"
loading.value = true
}
const upload:any = ref(null)
function handlesSuccess(file: any) {
if(file !== false){
ElMessage({
message: "导入成功!",
type: "success",
});
}else{
ElMessage({
message: "导入失败!",
type: "error",
});
}
gettableData()
upload.value.clearFiles()
}
function handleError(file: any){
loading.value = false
ElMessage({
message: "导入失败!",
type: "error",
});
upload.value.clearFiles()
}
// 处理数字输入的过滤
function handleNumberInput(field: string) {
// 过滤输入,只允许数字和小数点
info.value[field] = info.value[field].replace(/[^\d.]/g, '');
// 确保只有一个小数点
const parts = info.value[field].split('.');
if (parts.length > 2) {
info.value[field] = parts[0] + '.' + parts.slice(1).join('');
}
}
onMounted(() => {
getSizeSchemaList()
menuInit()
});
function exportExportsClick(){
exportAllExports(queryParams.value.type).then((response:any) => {
downloadFile(response, '临界数据数据' , 'xlsx')
});
}
function downloadFile(obj :any, name :any, suffix :any) {
const url = window.URL.createObjectURL(new Blob([obj]))
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
const fileName = name.trim() + '.' + suffix
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
</script>
<template>
<div class="criticalData-box">
<div class="conductproject-bg-leftBox">
<div v-for="(item,index) in menuData"
:key="index" :class="{'menu-list-active': item.itemCode == queryParams.type }" class="menu-list"
@click="handleMenu(item)">
{{ item.dictName }}
</div>
</div>
<div class="conductproject-bg-box">
<div
style="display: flex;display: -webkit-flex; justify-content: space-between; -webkit-justify-content: space-between;margin-bottom: 10px">
<div style="display: flex;display: -webkit-flex;">
<!-- <el-input v-model="input" placeholder="请输入临界数据名称" @keyup.enter="gettableData" style="width: 200px" clearable />
<el-button type="primary" style="margin-left: 10px" @click="gettableData">搜索</el-button> -->
</div>
<div style="display: flex;display: -webkit-flex;">
<el-button type="primary" @click="addClick" v-hasPerm="['criticalData:add']">
新增</el-button>
<el-upload
ref="upload"
accept=".xlsx,.xls"
class="upload-demo"
:data="{ deviceType: queryParams.type }"
:action=" url + '/critical-data/v2/import' "
:headers="{ token: getToken() }"
:show-file-list="false"
:before-upload="handlePreview"
:on-success="handlesSuccess"
:on-error="handleError">
<el-button type="primary" style="margin: 0 10px;" v-hasPerm="['criticalData:import']">导入</el-button>
</el-upload>
<el-button type="primary" @click="exportExportsClick">导出</el-button>
<el-button :type="multipleSelection.length > 0 ? 'primary' : ''"
:disabled="multipleSelection.length <= 0" @click="delClick" v-hasPerm="['criticalData:del']">删除</el-button>
</div>
</div>
<el-table v-loading="loading" :data="tableData" style="width: 100%; height: calc(100vh - 260px);margin-bottom: 10px;" border
@selection-change="handleSelectionChange"
:header-cell-style="{ background: 'rgb(250 250 250)', color: '#383838', height: '50px' }">
<el-table-column type="selection" width="50" align="center"></el-table-column>
<el-table-column type="index" label="序号" width="70" align="center"></el-table-column>
<el-table-column v-for="(item,index) in sourceTempData" :label="item.label" min-width="100">
<template #default="scope">
{{ scope.row.size[item.key] }}
</template>
</el-table-column>
<el-table-column prop="uConcentration" label="铀浓度g/L" min-width="130"></el-table-column>
<el-table-column prop="uEnrichment" label="铀富集度" min-width="100"></el-table-column>
<el-table-column prop="puConcentration" label="钚浓度g/L" min-width="130"></el-table-column>
<el-table-column prop="ePu238" label="PU-238占比" min-width="120"></el-table-column>
<el-table-column prop="ePu239" label="PU-239占比" min-width="120"></el-table-column>
<el-table-column prop="ePu240" label="PU-240占比" min-width="120"></el-table-column>
<el-table-column prop="ePu241" label="PU-241占比" min-width="120"></el-table-column>
<el-table-column prop="ePu242" label="PU-242占比" min-width="120"></el-table-column>
<el-table-column prop="keffValue" label="对应Keff值" min-width="100"></el-table-column>
<el-table-column prop="modifier" label="创建人" width="120"></el-table-column>
<el-table-column prop="createdAt" label="创建时间" width="200">
<template #default="scope">
{{ dateFormat(scope.row.createdAt) }}
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" width="80" align="center">
<template #default="scope">
<span
style="display: flex;display: -webkit-flex; justify-content: space-around;-webkit-justify-content: space-around; ">
<img src="@/assets/table/edit.png" alt="" title="修改"
@click="editClick(scope.row)" style="cursor: pointer; " v-hasPerm="['criticalData:update']">
<img src="@/assets/table/del.png" alt="" title="删除"
@click="delAloneClick(scope.row)" style="cursor: pointer; " v-hasPerm="['criticalData:del']">
</span>
</template>
</el-table-column>
</el-table>
<Page :total="total" v-model:size="queryParams.size" v-model:current="queryParams.current" @pagination="gettableData()" ></Page>
</div>
<el-dialog v-model="dialogVisible" :close-on-click-modal="false"
:modal="false" draggable :before-close="handleClose" :title="title"
append-to-body width="677px" height="530px">
<el-form ref="infoForm" :model="info" :rules="rules" label-width="100px" style="height: calc(100vh - 160px);overflow: auto;">
<el-form-item :label="item.label" style="width: 100%;" v-for="item in sourceTempData" :prop="'size.' + item.key">
<el-input-number
placeholder="请输入长度"
v-model="info.size[item.key]"
:min="0"
align="left"
:controls="false"
style="width: 100%"
>
<template #suffix>{{item.unit}}</template>
</el-input-number>
</el-form-item>
<el-form-item label="铀浓度g/L" style="width: 100%;" prop="uConcentration">
<el-input-number
placeholder="请输入长度"
v-model="info.uConcentration"
:min="0"
align="left"
:controls="false"
style="width: 100%"
>
</el-input-number>
</el-form-item>
<el-form-item label="铀富集度" style="width: 100%;" prop="uEnrichment">
<el-input-number
placeholder="请输入长度"
v-model="info.uEnrichment"
:min="0"
align="left"
:controls="false"
style="width: 100%"
>
</el-input-number>
</el-form-item>
<el-form-item label="钚浓度" style="width: 100%;" prop="puConcentration">
<el-input-number
placeholder="请输入长度"
v-model="info.puConcentration"
:min="0"
align="left"
:controls="false"
style="width: 100%"
>
</el-input-number>
</el-form-item>
<el-form-item label="PU-238占比" style="width: 100%;" prop="ePu238">
<el-input-number
placeholder="请输入长度"
v-model="info.ePu238"
:min="0"
align="left"
:controls="false"
style="width: 100%"
>
</el-input-number>
</el-form-item>
<el-form-item label="PU-239占比" style="width: 100%;" prop="ePu239">
<el-input-number
placeholder="请输入长度"
v-model="info.ePu239"
:min="0"
align="left"
:controls="false"
style="width: 100%"
>
</el-input-number>
</el-form-item>
<el-form-item label="PU-240占比" style="width: 100%;" prop="ePu240">
<el-input-number
placeholder="请输入长度"
v-model="info.ePu240"
:min="0"
align="left"
:controls="false"
style="width: 100%"
>
</el-input-number>
</el-form-item>
<el-form-item label="PU-241占比" style="width: 100%;" prop="ePu241">
<el-input-number
placeholder="请输入长度"
v-model="info.ePu241"
:min="0"
align="left"
:controls="false"
style="width: 100%"
>
</el-input-number>
</el-form-item>
<el-form-item label="PU-242占比" style="width: 100%;" prop="ePu242">
<el-input-number
placeholder="请输入长度"
v-model="info.ePu242"
:min="0"
align="left"
:controls="false"
style="width: 100%"
>
</el-input-number>
</el-form-item>
<!-- <el-form-item label="同位素丰度" style="width: 100%;">
<el-input v-model="info.isotopicAbundance" style="width: 100%" placeholder="请输入同位素丰度"
@input="handleNumberInput('isotopicAbundance')">
</el-input>
</el-form-item> -->
<el-form-item label="对应Kef值" style="width: 100%;" prop="keffValue">
<el-input v-model="info.keffValue" style="width: 100%" placeholder="请输入对应Kef值"
@input="handleNumberInput('keffValue')">
<!-- <template #append>m³/s</template> -->
</el-input>
</el-form-item>
<span class="dialog-footer"
style="display: flex;display: -webkit-flex; justify-content: flex-end;-webkit-justify-content: flex-end;">
<el-button @click="handleClose">取 消</el-button>
<el-button type="primary" @click="confirmClick(infoForm)"> </el-button>
</span>
</el-form>
</el-dialog>
</div>
</template>
<style scoped>
.criticalData-box {
padding-right: 10px;
display: flex;
justify-content: space-between;
}
.dialog-footer {
display: block;
margin-top: 20px;
}
.conductproject-bg-leftBox{
width: 240px;
height: calc(100vh - 130px);
overflow: auto;
padding: 20px 0px;
background-color: rgba(255, 255, 255, 1);
border: none;
border-radius: 3px;
box-sizing: border-box;
}
.menu-list{
width: 220px;
height: 40px;
line-height: 40px;
box-sizing: border-box;
padding-left: 30px;
font-family: 'Arial Normal', 'Arial', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 14px;
letter-spacing: normal;
color: #333333;
margin-left: 10px;
cursor: pointer;
}
.menu-list:hover{
background-color: #f9f9f9;
}
.menu-list-active{
background-color: #eaf1ff !important;
color: rgb(38, 111, 255) ;
}
.conductproject-bg-box {
padding: 20px;
width: calc(100% - 255px);
height: calc(100vh - 130px);
overflow: auto;
background-color: rgba(255, 255, 255, 1);
border: none;
border-radius: 3px;
box-sizing: border-box;
}
.menu-title{
width: 100%;
height: 50px;
line-height: 50px;
border-bottom: 1px solid rgba(242, 242, 242, 1);
font-family: 'Arial Negreta', 'Arial Normal', 'Arial', sans-serif;
font-weight: 700;
font-style: normal;
font-size: 15px;
color: #363636;
padding-left: 20px;
}
</style>
<style>
.el-dialog {
padding: 0 !important;
border-radius: 10px !important;
border: 1px solid #363636 !important;
}
.el-dialog .el-dialog__header{
display: flex;
display: -webkit-flex;
justify-content: flex-start;-webkit-justify-content: flex-start;
align-items: center;-webkit-align-items: center;
padding: 10px 20px;
background-color: #f1f3f8 !important;
font-family: 'Arial Negreta', 'Arial Normal', 'Arial', sans-serif;
font-weight: 700;
font-style: normal;
font-size: 16px;
color: #1B1B1B;
text-align: left;
border-radius: 10px 10px 0 0;
height: 50px;
}
.el-dialog .el-dialog__close{
font-size: 22px;
color: rgb(80, 80, 80);
}
.el-dialog .el-dialog__headerbtn{
display: flex;
align-items: center;
}
.el-dialog .el-dialog__body{
padding: 20px 40px !important;
}
.el-dialog .el-input{
--el-input-inner-height: 38px
}
.criticalData-box .el-button{
height: 36px;
}
.el-dialog .el-button{
height: 40px;
}
.el-input-group__append {
background-color: transparent !important;
border: none !important;
}
</style>