修改初始条件分段时间段校验
This commit is contained in:
parent
8d2e7e1cee
commit
34d693e774
@ -58,3 +58,14 @@ export function exportAllExports(deviceType:any){
|
||||
responseType: 'arraybuffer'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//获取临界数据分页列表
|
||||
export function delAllCriticalData(queryParams:any){
|
||||
return request({
|
||||
url: '/critical-data/by-device-type' ,
|
||||
method: 'delete',
|
||||
params:queryParams
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ export default {
|
||||
<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 { searchCriticalDataPage,addCriticalData,updateCriticalData,deleteCriticalData,deleteBatchCriticalData,exportAllExports ,delAllCriticalData} from "@/api/business/database/criticalData";
|
||||
import { getDictItemById } from '@/api/dict';
|
||||
import { sizeSchemaAll } from "@/api/business/database/device";
|
||||
|
||||
@ -29,7 +29,8 @@ const url = import.meta.env.VITE_APP_BASE_API;
|
||||
const queryParams:any = ref({
|
||||
current: 1,
|
||||
size: 10,
|
||||
deviceType: ''
|
||||
deviceType: '',
|
||||
dictName: ''
|
||||
});
|
||||
//分页 总条数
|
||||
const total = ref()
|
||||
@ -82,6 +83,7 @@ function menuInit() {
|
||||
getDictItemById(params).then((result: any) => {
|
||||
menuData.value = result.data.records;
|
||||
queryParams.value.type = menuData.value[0].itemCode
|
||||
queryParams.value.dictName = menuData.value[0].dictName
|
||||
sourceTempData.value = sizeSchemaInfo.value[queryParams.value.type].fields
|
||||
gettableData();
|
||||
}).catch((err: any) => {
|
||||
@ -90,6 +92,7 @@ function menuInit() {
|
||||
|
||||
function handleMenu(row:any) {
|
||||
queryParams.value.type = row.itemCode
|
||||
queryParams.value.dictName = row.dictName
|
||||
sourceTempData.value = sizeSchemaInfo.value[queryParams.value.type].fields
|
||||
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) {
|
||||
const daterc = row;
|
||||
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="multipleSelection.length > 0 ? 'primary' : ''"
|
||||
: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>
|
||||
<el-table v-loading="loading" :data="tableData" style="width: 100%; height: calc(100vh - 260px);margin-bottom: 10px;" border
|
||||
|
||||
@ -38,8 +38,15 @@ const props = defineProps({ // 接收父组件传递的项目信息
|
||||
default: false
|
||||
},
|
||||
});
|
||||
const errorsStrs:any = ref([]) // 错误信息
|
||||
const isError = ref(false) // 是否有错误
|
||||
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
|
||||
}
|
||||
function initDeviceData(){
|
||||
@ -114,18 +121,23 @@ const menuList:any = ref([
|
||||
])
|
||||
const menuIndex = 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({
|
||||
segmentId: '分段-' + (menuList.value[menuIndex.value].segments.length + 1),
|
||||
start:null,
|
||||
end:null,
|
||||
timeline:[]
|
||||
})
|
||||
segmentationIndex.value = menuList.value[menuIndex.value].segments.length - 1
|
||||
|
||||
}
|
||||
function removeSegmentation(index:any){ // 删除分段
|
||||
|
||||
menuList.value[menuIndex.value].segments.splice(index, 1);
|
||||
segmentationIndex.value = 0
|
||||
segmentationIndex.value = menuList.value[menuIndex.value].segments.length - 1
|
||||
getTimelineList()
|
||||
}
|
||||
|
||||
@ -145,7 +157,10 @@ function menuClick(index:any){ // 点击菜单切换
|
||||
segmentationIndex.value = 0;
|
||||
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]
|
||||
menuList.value.push({
|
||||
label: '条件' + (Number(tempLabel) + 1),
|
||||
@ -255,7 +270,6 @@ function getTimelineList(){
|
||||
let item = menuList.value[menuIndex.value]
|
||||
item.segments.forEach((segment:any) => {
|
||||
segment.timeline.forEach((timeline:any) => {
|
||||
console.log(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>
|
||||
|
||||
<template>
|
||||
@ -409,7 +552,7 @@ function handleSuccess(file: any) {
|
||||
<span>{{ item.segmentId }}</span>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
<div class="segmentation-item-add" @click="addSegmentation" v-if="isEdit == true">
|
||||
@ -491,6 +634,21 @@ function handleSuccess(file: any) {
|
||||
</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>
|
||||
</template>
|
||||
|
||||
|
||||
@ -154,9 +154,11 @@ function confirmClick(formEl: any) {
|
||||
});
|
||||
}
|
||||
const conditionModel = ref()
|
||||
function submitClick(){
|
||||
|
||||
const tempData = conditionModel.value?.submitClick()
|
||||
async function submitClick(){
|
||||
const tempData = await conditionModel.value?.submitClick()
|
||||
if(tempData === true){
|
||||
return
|
||||
}
|
||||
let data:any = []
|
||||
tempData.forEach((item: any) => {
|
||||
data.push({
|
||||
|
||||
@ -358,8 +358,11 @@ const conditionModelRef = ref<any>() // 条件模型实例
|
||||
function handleScenarioClose(){
|
||||
isShowCondition.value = false;
|
||||
}
|
||||
function submitConditionClick(){
|
||||
const tempData = conditionModelRef.value?.submitClick()
|
||||
async function submitConditionClick(){
|
||||
const tempData = await conditionModelRef.value?.submitClick()
|
||||
if(tempData === true){
|
||||
return
|
||||
}
|
||||
let data:any = []
|
||||
tempData.forEach((item: any) => {
|
||||
data.push({
|
||||
|
||||
Loading…
Reference in New Issue
Block a user