|
|
@ -9,6 +9,7 @@ import { |
|
|
|
Button, |
|
|
|
Card, |
|
|
|
Checkbox, |
|
|
|
Col, |
|
|
|
Descriptions, |
|
|
|
Divider, |
|
|
|
Form, |
|
|
@ -17,9 +18,11 @@ import { |
|
|
|
InputNumber, |
|
|
|
Modal, |
|
|
|
RangePicker, |
|
|
|
Row, |
|
|
|
Spin, |
|
|
|
Steps, |
|
|
|
Tabs, |
|
|
|
Transfer, |
|
|
|
} from 'ant-design-vue' |
|
|
|
import VueECharts from 'vue-echarts' |
|
|
|
import { pointTableSchema, sampleInfoTableSchema } from './data' |
|
|
@ -34,6 +37,7 @@ import { |
|
|
|
import { getExaHistorys } from '@/api/alert/exa/index' |
|
|
|
import { useECharts } from '@/hooks/web/useECharts' |
|
|
|
import { useMessage } from '@/hooks/web/useMessage' |
|
|
|
import { pointListApi } from '@/api/alert/model/select' |
|
|
|
|
|
|
|
export default defineComponent({ |
|
|
|
components: { |
|
|
@ -57,6 +61,9 @@ export default defineComponent({ |
|
|
|
AInputNumber: InputNumber, |
|
|
|
AButton: Button, |
|
|
|
ASpin: Spin, |
|
|
|
ATransfer: Transfer, |
|
|
|
ARow: Row, |
|
|
|
ACol: Col, |
|
|
|
}, |
|
|
|
setup() { |
|
|
|
const { createMessage } = useMessage() |
|
|
@ -65,16 +72,18 @@ export default defineComponent({ |
|
|
|
const model = ref(null) |
|
|
|
const brushActivated = ref<Set<number>>(new Set()) |
|
|
|
const spinning = ref(false) |
|
|
|
let trainTimeCopy = '' |
|
|
|
const fetchModelInfo = async () => { |
|
|
|
const modelInfo = await modelInfoApi(id) |
|
|
|
model.value = modelInfo |
|
|
|
trainTimeCopy = JSON.stringify(model.value.trainTime) |
|
|
|
getHistory() |
|
|
|
} |
|
|
|
|
|
|
|
const pointData = computed(() => model.value?.pointInfo || []) |
|
|
|
const [pointTable] = useTable({ |
|
|
|
columns: pointTableSchema, |
|
|
|
pagination: false, |
|
|
|
pagination: true, |
|
|
|
dataSource: pointData, |
|
|
|
scroll: { y: 300 }, |
|
|
|
}) |
|
|
@ -82,7 +91,6 @@ export default defineComponent({ |
|
|
|
const trainTime = computed(() => model.value?.trainTime || []) |
|
|
|
const [trainTimeTable] = useTable({ |
|
|
|
columns: sampleInfoTableSchema, |
|
|
|
pagination: false, |
|
|
|
dataSource: trainTime, |
|
|
|
scroll: { y: 300 }, |
|
|
|
}) |
|
|
@ -92,8 +100,8 @@ export default defineComponent({ |
|
|
|
const currentDate: Dayjs = dayjs() |
|
|
|
const lastMonthDate: Dayjs = currentDate.subtract(1, 'day') |
|
|
|
const rangeValue: RangeValue = [ |
|
|
|
dayjs('2025-2-24 00:00:00'), |
|
|
|
dayjs('2025-2-24 23:59:59'), |
|
|
|
lastMonthDate, |
|
|
|
currentDate, |
|
|
|
] |
|
|
|
const historyTime = ref<RangeValue>(rangeValue) |
|
|
|
const historyList = ref<any[]>([]) |
|
|
@ -115,7 +123,6 @@ export default defineComponent({ |
|
|
|
.join(','), |
|
|
|
interval: model.value.sampling, |
|
|
|
} |
|
|
|
console.log(params) |
|
|
|
const history = await getExaHistorys(params) |
|
|
|
historyList.value = history.map((item, index) => { |
|
|
|
const point = model.value?.pointInfo[index] |
|
|
@ -164,14 +171,13 @@ export default defineComponent({ |
|
|
|
name: `${index + 1}.${point?.description}(${point?.pointId})`, |
|
|
|
} |
|
|
|
}) |
|
|
|
console.log(historyList.value) |
|
|
|
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()) |
|
|
|
return Array.from({ length: count }, (_, i) => t1.add(i * intervalMs, 'millisecond').valueOf()) |
|
|
|
} |
|
|
|
|
|
|
|
function getOption(item: any) { |
|
|
@ -216,7 +222,6 @@ export default defineComponent({ |
|
|
|
}, |
|
|
|
], |
|
|
|
} |
|
|
|
console.log('option', option) |
|
|
|
return option |
|
|
|
} |
|
|
|
|
|
|
@ -286,7 +291,9 @@ export default defineComponent({ |
|
|
|
coordRange: area.coordRange, |
|
|
|
})) |
|
|
|
const trainTime = areas.map((area) => { |
|
|
|
const [st, et] = area.coordRange |
|
|
|
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'), |
|
|
@ -297,7 +304,11 @@ export default defineComponent({ |
|
|
|
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({ |
|
|
@ -504,6 +515,86 @@ export default defineComponent({ |
|
|
|
closeEditMode() |
|
|
|
} |
|
|
|
|
|
|
|
const openEditModelModal = ref(false) |
|
|
|
const editModelForm = ref({ |
|
|
|
sampling: 0, |
|
|
|
rate: 0, |
|
|
|
selectedKeys: [], |
|
|
|
}) |
|
|
|
|
|
|
|
// 穿梭框数据源示例 |
|
|
|
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, |
|
|
|
}))) |
|
|
|
console.log('Transfer data:', transferData.value) |
|
|
|
} |
|
|
|
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 |
|
|
|
} |
|
|
|
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] = key.split('|') |
|
|
|
return { |
|
|
|
description, |
|
|
|
pointId, |
|
|
|
unit, |
|
|
|
Lower, |
|
|
|
Upper, |
|
|
|
dead: true, |
|
|
|
limit: false, |
|
|
|
} |
|
|
|
}) |
|
|
|
clearModel() |
|
|
|
openEditModelModal.value = false |
|
|
|
} |
|
|
|
function handleEditModelCancel() { |
|
|
|
openEditModelModal.value = false |
|
|
|
} |
|
|
|
|
|
|
|
return { |
|
|
|
pointTable, |
|
|
|
model, |
|
|
@ -531,6 +622,13 @@ export default defineComponent({ |
|
|
|
mode, |
|
|
|
spinning, |
|
|
|
clearModel, |
|
|
|
openEditModelModal, |
|
|
|
editModelForm, |
|
|
|
transferData, |
|
|
|
handleTransferSearch, |
|
|
|
openEditModel, |
|
|
|
handleEditModelOk, |
|
|
|
handleEditModelCancel, |
|
|
|
} |
|
|
|
}, |
|
|
|
}) |
|
|
@ -540,12 +638,6 @@ export default defineComponent({ |
|
|
|
<PageWrapper content-background> |
|
|
|
<div> |
|
|
|
<a-card title="模型信息" :bordered="false"> |
|
|
|
<template #extra> |
|
|
|
<a-button> 下装 </a-button> |
|
|
|
<a-button type="primary" style="margin-left: 6px"> |
|
|
|
修改模型 |
|
|
|
</a-button> |
|
|
|
</template> |
|
|
|
<a-descriptions size="small" :column="4" bordered> |
|
|
|
<a-descriptions-item label="模型名称"> |
|
|
|
{{ model?.name }} |
|
|
@ -669,6 +761,15 @@ export default defineComponent({ |
|
|
|
> |
|
|
|
清除训练结果 |
|
|
|
</a-button> |
|
|
|
<a-button type="primary" style="margin-left: 6px" @click="openEditModel"> |
|
|
|
修改模型 |
|
|
|
</a-button> |
|
|
|
<a-button |
|
|
|
danger |
|
|
|
style="margin-left: 10px" |
|
|
|
> |
|
|
|
下装 |
|
|
|
</a-button> |
|
|
|
</div> |
|
|
|
<a-divider /> |
|
|
|
<a-spin :spinning="spinning" size="large"> |
|
|
@ -764,6 +865,58 @@ export default defineComponent({ |
|
|
|
</a-form-item> |
|
|
|
</a-form> |
|
|
|
</a-modal> |
|
|
|
<a-modal |
|
|
|
v-model:open="openEditModelModal" |
|
|
|
title="编辑模型" |
|
|
|
width="1200px" |
|
|
|
@ok="handleEditModelOk" |
|
|
|
@cancel="handleEditModelCancel" |
|
|
|
> |
|
|
|
<a-form |
|
|
|
:model="editModelForm" |
|
|
|
:label-col="{ span: 7 }" |
|
|
|
:wrapper-col="{ span: 15 }" |
|
|
|
> |
|
|
|
<a-row :gutter="16"> |
|
|
|
<a-col :span="12"> |
|
|
|
<a-form-item label="训练采样间隔" required> |
|
|
|
<a-input-number |
|
|
|
v-model:value="editModelForm.sampling" |
|
|
|
placeholder="请输入训练采样间隔" |
|
|
|
style="width: 100%" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
</a-col> |
|
|
|
<a-col :span="12"> |
|
|
|
<a-form-item label="最小主元贡献率" required> |
|
|
|
<a-input-number |
|
|
|
v-model:value="editModelForm.rate" |
|
|
|
placeholder="请输入最小主元贡献率" |
|
|
|
style="width: 100%" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
</a-col> |
|
|
|
</a-row> |
|
|
|
<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', |
|
|
|
}" |
|
|
|
@search="handleTransferSearch" |
|
|
|
/> |
|
|
|
</div> |
|
|
|
</a-form> |
|
|
|
</a-modal> |
|
|
|
</PageWrapper> |
|
|
|
</template> |
|
|
|
|
|
|
|