Browse Source

fix: resolve merge conflicts and clean up code formatting in index.vue

pull/79/head
CJL6015 1 month ago
parent
commit
d1630dc16a
  1. 529
      src/views/model/train/index.vue

529
src/views/model/train/index.vue

@ -1,10 +1,10 @@
<script lang="ts">
import type { ComponentPublicInstance } from 'vue'
import type { Dayjs } from 'dayjs'
import { debounce } from 'lodash-es'
import dayjs from 'dayjs'
import { computed, defineComponent, onMounted, ref, toRaw, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import type { ComponentPublicInstance } from "vue";
import type { Dayjs } from "dayjs";
import { debounce } from "lodash-es";
import dayjs from "dayjs";
import { computed, defineComponent, onMounted, ref, toRaw, watch } from "vue";
import { useRoute } from "vue-router";
import {
Button,
Card,
@ -25,11 +25,12 @@ import {
Steps,
Table,
Tabs,
} from 'ant-design-vue'
import VueECharts from 'vue-echarts'
import { pointTableSchema, sampleInfoTableSchema } from './data'
import { BasicTable, useTable } from '@/components/Table'
import { PageWrapper } from '@/components/Page'
Transfer,
} from "ant-design-vue";
import VueECharts from "vue-echarts";
import { pointTableSchema, sampleInfoTableSchema } from "./data";
import { BasicTable, useTable } from "@/components/Table";
import { PageWrapper } from "@/components/Page";
import {
bottomModelApi,
createDraftVersionApi,
@ -151,14 +152,14 @@ export default defineComponent({
pagination: true,
dataSource: pointData,
scroll: { y: 300 },
})
});
const trainTime = computed(() => model.value?.trainTime || [])
const trainTime = computed(() => model.value?.trainTime || []);
const [trainTimeTable] = useTable({
columns: sampleInfoTableSchema,
dataSource: trainTime,
scroll: { y: 300 },
})
});
const updatePrincipalFromTrainTime = (trainTimeList: any[]) => {
if (!Array.isArray(trainTimeList) || !model.value)
@ -189,34 +190,33 @@ export default defineComponent({
const echartsRefs = ref<any[]>([])
async function getHistory() {
if (!historyTime.value)
return
spinning.value = true
if (!historyTime.value) return;
spinning.value = true;
if (model.value.para) {
await getTestData()
}
else {
const params = {
startTime: historyTime.value[0].format('YYYY-MM-DD HH:mm:ss'),
endTime: historyTime.value[1].format('YYYY-MM-DD HH:mm:ss'),
startTime: historyTime.value[0].format("YYYY-MM-DD HH:mm:ss"),
endTime: historyTime.value[1].format("YYYY-MM-DD HH:mm:ss"),
itemName: model.value?.pointInfo
.map(item => item.pointId)
.join(','),
.map((item) => item.pointId)
.join(","),
interval: model.value.sampling,
}
const history = await getExaHistorys(params)
};
const history = await getExaHistorys(params);
historyList.value = history.map((item, index) => {
const point = model.value?.pointInfo[index]
const point = model.value?.pointInfo[index];
return {
data: [item],
name: `${index + 1}.${point?.description}(${point?.pointId})`,
}
})
echartsRefs.value = Array.from({ length: historyList.value.length })
brushActivated.value = new Set()
};
});
echartsRefs.value = Array.from({ length: historyList.value.length });
brushActivated.value = new Set();
}
spinning.value = false
spinning.value = false;
}
async function getTestData(range?: RangeValue) {
@ -247,7 +247,7 @@ export default defineComponent({
model.value.sampling * 1000,
)
historyList.value = sampleData.map((item, index) => {
const point = model.value?.pointInfo[index]
const point = model.value?.pointInfo[index];
return {
data: [
(Array.isArray(item) ? item : []).map((t, i) => {
@ -258,15 +258,17 @@ export default defineComponent({
}),
],
name: `${index + 1}.${point?.description}(${point?.pointId})`,
}
})
brushActivated.value = new Set()
};
});
brushActivated.value = new Set();
}
function generateTimeList(time: RangeValue, intervalMs: number) {
const [t1, t2] = time
const count = Math.floor(t2.diff(t1, 'millisecond') / intervalMs) + 1
return Array.from({ length: count }, (_, i) => t1.add(i * intervalMs, 'millisecond').valueOf())
const [t1, t2] = time;
const count = Math.floor(t2.diff(t1, "millisecond") / intervalMs) + 1;
return Array.from({ length: count }, (_, i) =>
t1.add(i * intervalMs, "millisecond").valueOf()
);
}
function normalizeTrainTime(modelInfo: any) {
@ -290,37 +292,37 @@ export default defineComponent({
}
function getOption(item: any) {
const name = ['测量值', '模型值', '']
const color = ['blue', '#ff6f00', 'red']
const yIndex = [0, 0, 1]
const name = ["测量值", "模型值", ""];
const color = ["blue", "#ff6f00", "red"];
const yIndex = [0, 0, 1];
const option = {
xAxis: {
type: 'time',
type: "time",
axisLabel: {
formatter(value) {
const date = new Date(value)
return date.toLocaleString()
const date = new Date(value);
return date.toLocaleString();
},
},
},
yAxis: [{ type: 'value' }, { type: 'value', max: 10, show: false }],
yAxis: [{ type: "value" }, { type: "value", max: 10, show: false }],
series: item.data.map((item, index) => {
return {
data: item,
type: 'line',
type: "line",
smooth: true,
symbol: 'none',
symbol: "none",
name: name[index],
color: color[index],
yAxisIndex: yIndex[index],
}
};
}),
legend: {},
dataZoom: [{}],
brush: {
toolbox: ['lineX'],
toolbox: ["lineX"],
xAxisIndex: 0,
brushType: 'lineX',
brushType: "lineX",
},
grid: [
{
@ -330,54 +332,49 @@ export default defineComponent({
top: 30,
},
],
}
return option
};
return option;
}
function setChartRef(
el: Element | ComponentPublicInstance | null,
index: number,
index: number
) {
let dom: HTMLElement | null = null
let dom: HTMLElement | null = null;
if (el) {
if ('$el' in el && (el as any).$el instanceof HTMLElement)
dom = (el as any).$el
else if (el instanceof HTMLElement)
dom = el
if ("$el" in el && (el as any).$el instanceof HTMLElement)
dom = (el as any).$el;
else if (el instanceof HTMLElement) dom = el;
}
if (dom)
useECharts(ref(dom as HTMLDivElement))
if (dom) useECharts(ref(dom as HTMLDivElement));
}
function setEchartsRef(el: any, index: number) {
if (el)
echartsRefs.value[index] = el
if (el) echartsRefs.value[index] = el;
}
const isInitBrush = ref(true)
const isInitBrush = ref(true);
function onChartFinished(index: number) {
if (brushActivated.value.has(index))
return
const chart = echartsRefs.value[index]
if (!chart)
return
if (brushActivated.value.has(index)) return;
const chart = echartsRefs.value[index];
if (!chart) return;
chart.dispatchAction({
type: 'takeGlobalCursor',
key: 'brush',
type: "takeGlobalCursor",
key: "brush",
brushOption: {
brushType: 'lineX',
brushMode: 'multiple',
brushType: "lineX",
brushMode: "multiple",
},
})
const areas = (model.value?.trainTime || []).map(row => ({
brushType: 'lineX',
});
const areas = (model.value?.trainTime || []).map((row) => ({
brushType: "lineX",
xAxisIndex: 0,
coordRange: [
dayjs(row.st).format('YYYY-MM-DD HH:mm:ss'),
dayjs(row.et).format('YYYY-MM-DD HH:mm:ss'),
dayjs(row.st).format("YYYY-MM-DD HH:mm:ss"),
dayjs(row.et).format("YYYY-MM-DD HH:mm:ss"),
],
}))
}));
chart.dispatchAction({
type: 'brush',
type: "brush",
areas,
})
isInitBrush.value = true
@ -385,148 +382,131 @@ export default defineComponent({
}
onMounted(async () => {
await fetchModelInfo()
})
await fetchModelInfo();
});
const onBrushSelected = debounce((params) => {
if (isInitBrush.value) {
isInitBrush.value = false
return
isInitBrush.value = false;
return;
}
if (!isInitBrush.value && model.value?.version != 'v-test')
return
const selected = params.batch[0].selected
if (!isInitBrush.value && model?.Cur_Version != "v-test") {
return;
}
const selected = params.batch[0].selected;
if (selected.length > 0) {
const areas = mergeAreas(params.batch[0].areas).map(area => ({
const areas = mergeAreas(params.batch[0].areas).map((area) => ({
brushType: area.brushType,
xAxisIndex: 0,
coordRange: area.coordRange,
}))
}));
const trainTime = areas.map((area) => {
const [stRaw, etRaw] = area.coordRange
const st = typeof stRaw === 'string' ? dayjs(stRaw).valueOf() : stRaw
const et = typeof etRaw === 'string' ? dayjs(etRaw).valueOf() : etRaw
console.log('Selected area:', { st, et }, area)
const [stRaw, etRaw] = area.coordRange;
const st = typeof stRaw === "string" ? dayjs(stRaw).valueOf() : stRaw;
const et = typeof etRaw === "string" ? dayjs(etRaw).valueOf() : etRaw;
console.log("Selected area:", { st, et }, area);
return {
st: dayjs(st).format('YYYY-MM-DD HH:mm:ss'),
et: dayjs(et).format('YYYY-MM-DD HH:mm:ss'),
st: dayjs(st).format("YYYY-MM-DD HH:mm:ss"),
et: dayjs(et).format("YYYY-MM-DD HH:mm:ss"),
duration: Math.round((et - st) / 1000),
number: '', //
filter: '', //
mode: '', //
}
})
console.log('Selected train time:', trainTime)
if (trainTimeCopy === JSON.stringify(trainTime))
return
model.value.trainTime = trainTime
trainTimeCopy = JSON.stringify(trainTime)
number: "", //
filter: "", //
mode: "", //
};
});
console.log("Selected train time:", trainTime);
if (trainTimeCopy === JSON.stringify(trainTime)) return;
model.value.trainTime = trainTime;
trainTimeCopy = JSON.stringify(trainTime);
echartsRefs.value.forEach((chart, index) => {
if (chart) {
chart.dispatchAction({
type: 'brush',
type: "brush",
areas,
})
isInitBrush.value = true
});
isInitBrush.value = true;
}
})
updateModelInfoDebounced()
});
updateModelInfoDebounced();
}
}, 300)
}, 300);
function mergeAreas(areas: any[]) {
if (!areas.length)
return []
if (!areas.length) return [];
// brushType xAxisIndex
const sorted = [...areas].sort(
(a, b) => a.coordRange[0] - b.coordRange[0],
)
const merged: any[] = []
(a, b) => a.coordRange[0] - b.coordRange[0]
);
const merged: any[] = [];
for (const area of sorted) {
if (
merged.length
&& merged[merged.length - 1].brushType === area.brushType
&& merged[merged.length - 1].xAxisIndex === area.xAxisIndex
&& merged[merged.length - 1].coordRange[1] >= area.coordRange[0]
merged.length &&
merged[merged.length - 1].brushType === area.brushType &&
merged[merged.length - 1].xAxisIndex === area.xAxisIndex &&
merged[merged.length - 1].coordRange[1] >= area.coordRange[0]
) {
//
merged[merged.length - 1].coordRange[1] = Math.max(
merged[merged.length - 1].coordRange[1],
area.coordRange[1],
)
}
else {
area.coordRange[1]
);
} else {
//
merged.push({
brushType: area.brushType,
xAxisIndex: area.xAxisIndex,
coordRange: [...area.coordRange],
})
});
}
}
return merged
return merged;
}
//
const updateModelInfoDebounced = debounce(() => {
const val = toRaw(model.value)
if (val && val.id)
updateModelInfo(val)
}, 500)
const val = toRaw(model.value);
if (val && val.id) updateModelInfo(val);
}, 500);
function handleDeleteTrainTime(index: number) {
if (!canEditModel.value) {
createMessage.warning('非草稿版本不可修改训练时间')
return
}
if (!model.value?.trainTime)
return
if (!model.value?.trainTime) return;
//
model.value.trainTime = [
...model.value.trainTime.slice(0, index),
...model.value.trainTime.slice(index + 1),
]
];
// brush
const areas = (model.value.trainTime || []).map(row => ({
brushType: 'lineX',
const areas = (model.value.trainTime || []).map((row) => ({
brushType: "lineX",
xAxisIndex: 0,
coordRange: [dayjs(row.st).valueOf(), dayjs(row.et).valueOf()],
}))
}));
echartsRefs.value.forEach((chart) => {
if (chart) {
chart.dispatchAction({
type: 'brush',
type: "brush",
areas,
})
isInitBrush.value = true
});
isInitBrush.value = true;
}
})
updateModelInfoDebounced()
});
updateModelInfoDebounced();
}
async function clearModel() {
if (!canEditModel.value) {
createMessage.warning('非草稿版本不可清除训练结果')
return
}
model.value.para = null
updateModelInfoDebounced()
await getHistory()
model.value.para = null;
updateModelInfoDebounced();
await getHistory();
}
async function trainModel() {
if (!canEditModel.value) {
createMessage.warning('非草稿版本不可训练模型')
return
}
const modelInfo = model.value
const modelInfo = model.value;
if (!modelInfo || !modelInfo.id) {
console.error('模型信息不完整,无法训练')
return
console.error("模型信息不完整,无法训练");
return;
}
const pointInfo = modelInfo.pointInfo || []
const pointInfo = modelInfo.pointInfo || [];
if (pointInfo.length === 0) {
console.error('模型参数点信息为空,无法训练')
return
console.error("模型参数点信息为空,无法训练");
return;
}
const params = {
conditon: modelInfo.alarmmodelset?.alarmcondition || '1=1',
@ -534,27 +514,27 @@ export default defineComponent({
percent: modelInfo.rate,
},
Train_Data: {
points: pointInfo.map(item => item.pointId).join(','),
dead: pointInfo.map(item => (item.dead ? '1' : '0')).join(','),
limit: pointInfo.map(item => (item.limit ? '1' : '0')).join(','),
points: pointInfo.map((item) => item.pointId).join(","),
dead: pointInfo.map((item) => (item.dead ? "1" : "0")).join(","),
limit: pointInfo.map((item) => (item.limit ? "1" : "0")).join(","),
uplow: pointInfo
.map(
item =>
(item) =>
`${item.Upper ? item.Upper : null},${
item.Lower ? item.Lower : null
}`,
}`
)
.join(';'),
.join(";"),
interval: modelInfo.sampling * 1000,
time: modelInfo.trainTime
.map(item => `${item.st},${item.et}`)
.join(';'),
.map((item) => `${item.st},${item.et}`)
.join(";"),
},
type: 'PCA',
type: "PCA",
smote_config: [],
smote: true,
}
spinning.value = true
};
spinning.value = true;
try {
const response = await trainModelApi(params)
model.value.para = response
@ -640,19 +620,19 @@ export default defineComponent({
createMessage.error('模型训练失败')
}
spinning.value = false
spinning.value = false;
}
const editForm = ref({
index: -1,
Upper: '',
Lower: '',
lowerBound: '',
upperBound: '',
Upper: "",
Lower: "",
lowerBound: "",
upperBound: "",
dead: true,
limit: false,
})
const openEditPointModal = ref<boolean>(false)
let pointEditRecord = null
});
const openEditPointModal = ref<boolean>(false);
let pointEditRecord = null;
function editPoint() {
//
model.value.pointInfo[editForm.value.index] = {
@ -663,15 +643,15 @@ export default defineComponent({
upperBound: editForm.value.upperBound,
dead: editForm.value.dead,
limit: editForm.value.limit,
}
updateModelInfoDebounced()
pointEditRecord.Upper = editForm.value.Upper
pointEditRecord.Lower = editForm.value.Lower
pointEditRecord.lowerBound = editForm.value.lowerBound
pointEditRecord.upperBound = editForm.value.upperBound
pointEditRecord.dead = editForm.value.dead
pointEditRecord.limit = editForm.value.limit
openEditPointModal.value = false
};
updateModelInfoDebounced();
pointEditRecord.Upper = editForm.value.Upper;
pointEditRecord.Lower = editForm.value.Lower;
pointEditRecord.lowerBound = editForm.value.lowerBound;
pointEditRecord.upperBound = editForm.value.upperBound;
pointEditRecord.dead = editForm.value.dead;
pointEditRecord.limit = editForm.value.limit;
openEditPointModal.value = false;
}
function openPointModal(index, record) {
@ -680,29 +660,22 @@ export default defineComponent({
return
}
// index
const pageIndex = index
const pageIndex = index;
// index
const globalIndex = model.value.pointInfo.findIndex(
item => item.pointId === record.pointId,
)
openEditPointModal.value = true
pointEditRecord = record
const normalizeBool = (val: any) => {
if (val === true || val === '是' || val === 1 || val === '1')
return true
if (val === false || val === '否' || val === 0 || val === '0')
return false
return !!val
}
(item) => item.pointId === record.pointId
);
openEditPointModal.value = true;
pointEditRecord = record;
editForm.value = {
index: globalIndex,
Upper: record?.Upper ?? '',
Lower: record?.Lower ?? '',
lowerBound: record?.lowerBound ?? '',
upperBound: record?.upperBound ?? '',
dead: normalizeBool(record?.dead),
limit: normalizeBool(record?.limit),
}
Upper: record?.Upper ?? "",
Lower: record?.Lower ?? "",
lowerBound: record?.lowerBound ?? "",
upperBound: record?.upperBound ?? "",
dead: !!record?.dead,
limit: !!record?.limit,
};
}
const mode = ref({
@ -713,58 +686,92 @@ export default defineComponent({
const normalizeVersion = (val?: string | null) => (val ? String(val).trim().toLowerCase() : '')
function openEditMode() {
if (!canEditModel.value) {
createMessage.warning('非草稿版本不可修改模式')
return
}
openEditModeModal.value = true
openEditModeModal.value = true;
mode.value = {
alarmcondition: model.value?.alarmmodelset?.alarmcondition || '1=1',
alarmname: model.value?.alarmmodelset?.alarmname || '全工况运行',
}
}
function closeEditMode() {
openEditModeModal.value = false
openEditModeModal.value = false;
}
function handleEditMode() {
//
model.value.alarmmodelset = mode.value
updateModelInfoDebounced()
closeEditMode()
model.value.alarmmodelset = mode.value;
updateModelInfoDebounced();
closeEditMode();
}
const openEditModelModal = ref(false)
const openEditModelModal = ref(false);
const editModelForm = ref({
sampling: 0,
rate: 0,
selectedKeys: [],
})
});
function openEditModel() {
if (!canEditModel.value) {
createMessage.warning('非草稿版本不可修改模型')
return
}
editModelForm.value.sampling = model.value?.sampling || 0
editModelForm.value.rate = model.value?.rate || 0
editModelForm.value.selectedKeys = (model.value?.pointInfo || []).map(item => buildPointKeyFromInfo({
description: item.description ?? item.Description,
pointId: item.pointId ?? item.PointId,
unit: item.unit ?? item.Unit,
Lower: item.Lower ?? item.lower,
Upper: item.Upper ?? item.upper,
// 穿
const transferData = ref([]); // 穿
//
async function fetchAllPoints(keyword = "") {
// keyword
// const res = await fetchPointsApi({ keyword })
//
const data = await pointListApi({ keyword });
console.log("Fetched points:", data);
transferData.value = transferData.value
.filter((item) => editModelForm.value.selectedKeys.includes(item.key))
.concat(
data.map((item) => ({
key: item.id,
title: item.name,
}))
openEditModelModal.value = true
);
console.log("Transfer data:", transferData.value);
}
function handleEditModelOk() {
if (!canEditModel.value) {
createMessage.warning('非草稿版本不可修改模型')
return
onMounted(() => {
fetchAllPoints();
});
function handleTransferSearch(dir, value) {
if (dir === "left") {
//
fetchAllPoints(value);
} else {
//
transferData.value = (model.value?.pointInfo || [])
.filter(
(item) =>
editModelForm.value.selectedKeys.includes(
`${item.description}|${item.pointId}|${item.unit}|${item.Lower}|${item.Upper}`
) && `${item.description || ""}(${item.pointId})`.includes(value)
)
.map((item) => ({
key: `${item.description}|${item.pointId}|${item.unit}|${item.Lower}|${item.Upper}`,
title: `${item.description || ""} (${item.pointId})`,
}));
}
}
function openEditModel() {
editModelForm.value.sampling = model.value?.sampling || 0;
editModelForm.value.rate = model.value?.rate || 0;
editModelForm.value.selectedKeys = (model.value?.pointInfo || []).map(
(item) =>
`${item.description}|${item.pointId}|${item.unit}|${item.Lower}|${item.Upper}`
);
transferData.value = (model.value?.pointInfo || []).map((item) => ({
key: `${item.description}|${item.pointId}|${item.unit}|${item.Lower}|${item.Upper}`,
title: `${item.description || ""} (${item.pointId})`,
}));
console.log("transferData:", transferData.value);
openEditModelModal.value = true;
}
model.value.sampling = editModelForm.value.sampling
model.value.rate = editModelForm.value.rate
function handleEditModelOk() {
model.value.sampling = editModelForm.value.sampling;
model.value.rate = editModelForm.value.rate;
model.value.pointInfo = editModelForm.value.selectedKeys.map((key) => {
const { description, pointId, unit, Lower, Upper } = parsePointKey(key)
const [description, pointId, unit, Lower, Upper] = key.split("|");
return {
description,
pointId,
@ -773,13 +780,13 @@ export default defineComponent({
Upper,
dead: true,
limit: false,
}
})
clearModel()
openEditModelModal.value = false
};
});
clearModel();
openEditModelModal.value = false;
}
function handleEditModelCancel() {
openEditModelModal.value = false
openEditModelModal.value = false;
}
const reportModalVisible = ref(false)
@ -1056,7 +1063,7 @@ export default defineComponent({
canEditModel,
}
},
})
});
</script>
<template>
@ -1145,7 +1152,7 @@ export default defineComponent({
(
model?.trainTime.reduce(
(total, item) => total + item.duration,
0,
0
) / 3600
).toFixed(2) || "暂无"
}}
@ -1337,12 +1344,8 @@ export default defineComponent({
/>
</a-form-item>
<a-form-item label="清洗方式" style="margin-top: 16px">
<a-checkbox v-model:checked="editForm.dead">
死区清洗
</a-checkbox>
<a-checkbox v-model:checked="editForm.limit">
限值清洗
</a-checkbox>
<a-checkbox v-model:checked="editForm.dead"> 死区清洗 </a-checkbox>
<a-checkbox v-model:checked="editForm.limit"> 限值清洗 </a-checkbox>
</a-form-item>
</a-form>
</a-modal>
@ -1403,10 +1406,24 @@ export default defineComponent({
</a-form-item>
</a-col>
</a-row>
<div style="display: flex; justify-content: center; margin-top: 24px;margin-bottom: 10px;">
<PointTransfer
v-model:selected-keys="editModelForm.selectedKeys"
:prefill-points="model?.pointInfo || []"
<div
style="
display: flex;
justify-content: center;
margin-top: 24px;
margin-bottom: 10px;
"
>
<a-transfer
v-model:target-keys="editModelForm.selectedKeys"
:data-source="transferData"
:render="(item) => item.title"
:row-key="(item) => item.key"
:pagination="false"
:show-search="true"
:filter="true"
search-placeholder="搜索测点"
:titles="['可选测点', '已选测点']"
:list-style="{
width: '500px',
height: '450px',

Loading…
Cancel
Save