修改初始条件分段时间段校验
This commit is contained in:
parent
8d2e7e1cee
commit
34d693e774
@ -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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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>
|
||||||
|
|
||||||
|
|||||||
@ -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({
|
||||||
|
|||||||
@ -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({
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user