修改初始条件分段时间段校验

This commit is contained in:
limengnan 2026-07-09 17:16:29 +08:00
parent 8d2e7e1cee
commit 34d693e774
5 changed files with 223 additions and 13 deletions

View File

@ -58,3 +58,14 @@ export function exportAllExports(deviceType:any){
responseType: 'arraybuffer' responseType: 'arraybuffer'
}); });
} }
//获取临界数据分页列表
export function delAllCriticalData(queryParams:any){
return request({
url: '/critical-data/by-device-type' ,
method: 'delete',
params:queryParams
});
}

View File

@ -7,7 +7,7 @@ export default {
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref, nextTick } from "vue"; import { onMounted, ref, nextTick } from "vue";
import { ElForm, ElMessage, ElMessageBox } from "element-plus"; import { ElForm, ElMessage, ElMessageBox } from "element-plus";
import { searchCriticalDataPage,addCriticalData,updateCriticalData,deleteCriticalData,deleteBatchCriticalData,exportAllExports} from "@/api/business/database/criticalData"; import { searchCriticalDataPage,addCriticalData,updateCriticalData,deleteCriticalData,deleteBatchCriticalData,exportAllExports ,delAllCriticalData} from "@/api/business/database/criticalData";
import { getDictItemById } from '@/api/dict'; import { getDictItemById } from '@/api/dict';
import { sizeSchemaAll } from "@/api/business/database/device"; import { sizeSchemaAll } from "@/api/business/database/device";
@ -29,7 +29,8 @@ const url = import.meta.env.VITE_APP_BASE_API;
const queryParams:any = ref({ const queryParams:any = ref({
current: 1, current: 1,
size: 10, size: 10,
deviceType: '' deviceType: '',
dictName: ''
}); });
// //
const total = ref() const total = ref()
@ -82,6 +83,7 @@ function menuInit() {
getDictItemById(params).then((result: any) => { getDictItemById(params).then((result: any) => {
menuData.value = result.data.records; menuData.value = result.data.records;
queryParams.value.type = menuData.value[0].itemCode queryParams.value.type = menuData.value[0].itemCode
queryParams.value.dictName = menuData.value[0].dictName
sourceTempData.value = sizeSchemaInfo.value[queryParams.value.type].fields sourceTempData.value = sizeSchemaInfo.value[queryParams.value.type].fields
gettableData(); gettableData();
}).catch((err: any) => { }).catch((err: any) => {
@ -90,6 +92,7 @@ function menuInit() {
function handleMenu(row:any) { function handleMenu(row:any) {
queryParams.value.type = row.itemCode queryParams.value.type = row.itemCode
queryParams.value.dictName = row.dictName
sourceTempData.value = sizeSchemaInfo.value[queryParams.value.type].fields sourceTempData.value = sizeSchemaInfo.value[queryParams.value.type].fields
gettableData() gettableData()
} }
@ -372,6 +375,34 @@ function delClick() {
}); });
}); });
} }
function delAllClick(){
ElMessageBox.confirm("确定全部删除所有【" + queryParams.value.dictName + "】的临界数据吗?", "删除提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
let id = [] as any[];
multipleSelection.value.forEach((item: any) => {
id.push(item.criticalId)
})
let params = {
deviceType: queryParams.value.type,
confirm: true
};
loading.value = true
delAllCriticalData(params).then(() => {
loading.value = false
gettableData();
ElMessage({
message: "删除成功",
type: "success",
});
}).catch(() => {
loading.value = false
})
});
}
function dateFormat(row: any) { function dateFormat(row: any) {
const daterc = row; const daterc = row;
if (daterc != null) { if (daterc != null) {
@ -492,6 +523,11 @@ function downloadFile(obj :any, name :any, suffix :any) {
<el-button type="primary" @click="exportExportsClick">导出</el-button> <el-button type="primary" @click="exportExportsClick">导出</el-button>
<el-button :type="multipleSelection.length > 0 ? 'primary' : ''" <el-button :type="multipleSelection.length > 0 ? 'primary' : ''"
:disabled="multipleSelection.length <= 0" @click="delClick" v-hasPerm="['criticalData:del']">删除</el-button> :disabled="multipleSelection.length <= 0" @click="delClick" v-hasPerm="['criticalData:del']">删除</el-button>
<el-button type="primary"
@click="delAllClick" v-hasPerm="['criticalData:del']">全部删除</el-button>
</div> </div>
</div> </div>
<el-table v-loading="loading" :data="tableData" style="width: 100%; height: calc(100vh - 260px);margin-bottom: 10px;" border <el-table v-loading="loading" :data="tableData" style="width: 100%; height: calc(100vh - 260px);margin-bottom: 10px;" border

View File

@ -38,8 +38,15 @@ const props = defineProps({ // 接收父组件传递的项目信息
default: false default: false
}, },
}); });
const errorsStrs:any = ref([]) //
const isError = ref(false) //
const isEdit = ref(props.isEdit) const isEdit = ref(props.isEdit)
function submitClick() { async function submitClick() {
const result = await validateSegments(menuList.value[menuIndex.value].segments);
console.log(result)
if(result === true){
return true
}
return menuList.value return menuList.value
} }
function initDeviceData(){ function initDeviceData(){
@ -114,18 +121,23 @@ const menuList:any = ref([
]) ])
const menuIndex = ref(0) // const menuIndex = ref(0) //
const segmentationIndex:any = ref(0) // const segmentationIndex:any = ref(0) //
function addSegmentation() { // async function addSegmentation() { //
if(await validateSegments(menuList.value[menuIndex.value].segments)){
return true
}
menuList.value[menuIndex.value].segments.push({ menuList.value[menuIndex.value].segments.push({
segmentId: '分段-' + (menuList.value[menuIndex.value].segments.length + 1), segmentId: '分段-' + (menuList.value[menuIndex.value].segments.length + 1),
start:null, start:null,
end:null, end:null,
timeline:[] timeline:[]
}) })
segmentationIndex.value = menuList.value[menuIndex.value].segments.length - 1
} }
function removeSegmentation(index:any){ // function removeSegmentation(index:any){ //
menuList.value[menuIndex.value].segments.splice(index, 1); menuList.value[menuIndex.value].segments.splice(index, 1);
segmentationIndex.value = 0 segmentationIndex.value = menuList.value[menuIndex.value].segments.length - 1
getTimelineList() getTimelineList()
} }
@ -145,7 +157,10 @@ function menuClick(index:any){ // 点击菜单切换
segmentationIndex.value = 0; segmentationIndex.value = 0;
getTimelineList() getTimelineList()
} }
function addMenu(){ // async function addMenu(){ //
if(await validateSegments(menuList.value[menuIndex.value].segments)){
return true
}
let tempLabel = menuList.value[menuList.value.length - 1].label.split('条件')[1] let tempLabel = menuList.value[menuList.value.length - 1].label.split('条件')[1]
menuList.value.push({ menuList.value.push({
label: '条件' + (Number(tempLabel) + 1), label: '条件' + (Number(tempLabel) + 1),
@ -255,7 +270,6 @@ function getTimelineList(){
let item = menuList.value[menuIndex.value] let item = menuList.value[menuIndex.value]
item.segments.forEach((segment:any) => { item.segments.forEach((segment:any) => {
segment.timeline.forEach((timeline:any) => { segment.timeline.forEach((timeline:any) => {
console.log(timeline)
timelineList.value.push(timeline) timelineList.value.push(timeline)
}) })
}) })
@ -363,6 +377,135 @@ function handleSuccess(file: any) {
} }
const errortitle:any = ref('') //
const validateSegments:any = async (segments:any) => {
errortitle.value = menuList.value[menuIndex.value].label
let errors:any = [];
let errorsData = []
//
segments.forEach((segment:any, index:any) => {
const timeline = segment.timeline;
const tValues = timeline.map((item:any) => item.t);
// === 1. t ===
for (let i = 1; i < timeline.length; i++) {
if (timeline[i].t <= timeline[i - 1].t) {
errors.push({
type: '内部递增',
segmentId: segment.segmentId,
index: index,
message: `${segment.segmentId}内部时间有误: ` +
`${i}行=${timeline[i-1].t}, 第${i+1}行=${timeline[i].t}`
});
}
}
// === 2. t ===
const duplicateMap = new Map();
//
tValues.forEach((t:any, idx:any) => {
if (!duplicateMap.has(t)) {
duplicateMap.set(t, [idx]);
} else {
duplicateMap.get(t).push(idx);
}
});
// > 1
const duplicates = Array.from(duplicateMap.entries())
.filter(([t, indices]) => indices.length > 1);
if (duplicates.length > 0) {
//
const duplicateDetails = duplicates.map(([t, indices]) => {
const rowNumbers = indices.map((idx:any) => idx + 1).join('、');
return `${t} 在第 ${rowNumbers} 行重复`;
});
errors.push({
type: '重复值',
segmentId: segment.segmentId,
index: index,
message: `${segment.segmentId} 存在重复的 时间: ${duplicateDetails.join('')}`,
duplicateData: duplicates.map(([t, indices]) => ({
value: t,
rows: indices.map((idx:any) => idx + 1)
}))
});
}
});
if (errors.length > 0) {
console.log('❌ 校验失败,发现以下问题:\n');
errors.forEach((err:any, idx:any) => {
// console.error(` ${err.message}`);
errorsData.push(err.message)
});
console.log(`\n共发现 ${errors.length} 个问题`);
errorsStrs.value = errors
isError.value = true
// return true;
}
// === 3. t t ===
for (let i = 1; i < segments.length; i++) {
const prevMaxT = Math.max(...segments[i - 1].timeline.map((item:any) => item.t));
const currentTValues = segments[i].timeline.map((item:any) => item.t);
const minCurrentT = Math.min(...currentTValues);
if (minCurrentT <= prevMaxT) {
//
const invalidValues = currentTValues.filter((t:any) => t <= prevMaxT);
errors.push({
type: '分段间对比',
segmentId: segments[i].segmentId,
prevSegmentId: segments[i - 1].segmentId,
index: i,
message: `${segments[i].segmentId}的时间` +
`[${invalidValues.join(', ')}] 不大于 ${segments[i-1].segmentId} 的最大值 ${prevMaxT}`
});
}
}
// === ===
// if (errors.length > 0) {
// console.error(' \n');
// errors.forEach((err, idx) => {
// console.error(` ${idx + 1}. [${err.type}] ${err.message}`);
// });
// console.error(`\n ${errors.length} `);
// }
if(errors.length == 0){
return false;
}else{
return true;
}
}
const segments2 = [
{
segmentId: '分段-1',
start: null,
end: null,
timeline: [{t: 1, value: 10}, {t: 3, value: 10}, {t: 5, value: 10}]
},
{
segmentId: '分段-2',
start: null,
end: null,
timeline: [{t: 6, value: 10}, {t: 5, value: 10}, {t: 4, value: 10}]
},
{
segmentId: '分段-3',
start: null,
end: null,
timeline: [{t: 9, value: 10}, {t: 11, value: 10}, {t: 13, value: 10}]
}
];
// validateSegments(segments2);
function handleClose(done: any) {
isError.value = false
}
</script> </script>
<template> <template>
@ -409,7 +552,7 @@ function handleSuccess(file: any) {
<span>{{ item.segmentId }}</span> <span>{{ item.segmentId }}</span>
<svg v-if="isEdit == true && menuList[menuIndex].segments.length >1 && menuList[menuIndex].segments.length - 1 == index" <svg v-if="isEdit == true && menuList[menuIndex].segments.length >1 && menuList[menuIndex].segments.length - 1 == index"
@click.top="removeSegmentation(index)" @click.stop="removeSegmentation(index)"
t="1766969938271" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4998" width="14" height="14"><path d="M571.01312 523.776l311.3472-311.35232c15.7184-15.71328 15.7184-41.6256 0-57.344l-1.69472-1.69984c-15.7184-15.71328-41.6256-15.71328-57.34912 0l-311.3472 311.77728-311.35232-311.77728c-15.7184-15.71328-41.63072-15.71328-57.344 0l-1.69984 1.69984a40.0128 40.0128 0 0 0 0 57.344L452.92544 523.776l-311.35232 311.35744c-15.71328 15.71328-15.71328 41.63072 0 57.33888l1.69984 1.69984c15.71328 15.7184 41.6256 15.7184 57.344 0l311.35232-311.35232 311.3472 311.35232c15.72352 15.7184 41.63072 15.7184 57.34912 0l1.69472-1.69984c15.7184-15.70816 15.7184-41.6256 0-57.33888l-311.3472-311.35744z" p-id="4999" fill="currentColor"></path></svg> t="1766969938271" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4998" width="14" height="14"><path d="M571.01312 523.776l311.3472-311.35232c15.7184-15.71328 15.7184-41.6256 0-57.344l-1.69472-1.69984c-15.7184-15.71328-41.6256-15.71328-57.34912 0l-311.3472 311.77728-311.35232-311.77728c-15.7184-15.71328-41.63072-15.71328-57.344 0l-1.69984 1.69984a40.0128 40.0128 0 0 0 0 57.344L452.92544 523.776l-311.35232 311.35744c-15.71328 15.71328-15.71328 41.63072 0 57.33888l1.69984 1.69984c15.71328 15.7184 41.6256 15.7184 57.344 0l311.35232-311.35232 311.3472 311.35232c15.72352 15.7184 41.63072 15.7184 57.34912 0l1.69472-1.69984c15.7184-15.70816 15.7184-41.6256 0-57.33888l-311.3472-311.35744z" p-id="4999" fill="currentColor"></path></svg>
</div> </div>
<div class="segmentation-item-add" @click="addSegmentation" v-if="isEdit == true"> <div class="segmentation-item-add" @click="addSegmentation" v-if="isEdit == true">
@ -491,6 +634,21 @@ function handleSuccess(file: any) {
</div> </div>
</div> </div>
</div> </div>
<el-dialog
v-model="isError"
:title="errortitle + '--分段的时间错误提示'"
width="500"
:before-close="handleClose"
>
<el-table :data="errorsStrs" style="width: 100%;height: calc(100vh - 300px);overflow: auto;" >
<el-table-column type="index" label="序号" width="60" align="center"></el-table-column>
<el-table-column prop="message" label="错误信息" ></el-table-column>
</el-table>
</el-dialog>
</div> </div>
</template> </template>

View File

@ -154,9 +154,11 @@ function confirmClick(formEl: any) {
}); });
} }
const conditionModel = ref() const conditionModel = ref()
function submitClick(){ async function submitClick(){
const tempData = await conditionModel.value?.submitClick()
const tempData = conditionModel.value?.submitClick() if(tempData === true){
return
}
let data:any = [] let data:any = []
tempData.forEach((item: any) => { tempData.forEach((item: any) => {
data.push({ data.push({

View File

@ -358,8 +358,11 @@ const conditionModelRef = ref<any>() // 条件模型实例
function handleScenarioClose(){ function handleScenarioClose(){
isShowCondition.value = false; isShowCondition.value = false;
} }
function submitConditionClick(){ async function submitConditionClick(){
const tempData = conditionModelRef.value?.submitClick() const tempData = await conditionModelRef.value?.submitClick()
if(tempData === true){
return
}
let data:any = [] let data:any = []
tempData.forEach((item: any) => { tempData.forEach((item: any) => {
data.push({ data.push({