Browse Source

feat 运行中心-模型实例V2.0

pull/24/head^2
肖晋飞 1 month ago
parent
commit
7a077c261d
  1. 33
      src/api/alert/warn/index.ts
  2. 88
      src/views/run/instant/UpdateModal.vue
  3. 11
      src/views/run/instant/index.vue
  4. 40
      src/views/run/instant/instant.data.ts
  5. 125
      src/views/warn/index.vue
  6. 88
      src/views/warn/updateModal.vue
  7. 352
      src/views/warn/warn.data.ts

33
src/api/alert/warn/index.ts

@ -0,0 +1,33 @@
import { defHttp } from '@/utils/http/axios'
export interface WarnPageReqVO extends PageParam {
mpId?: string
}
export interface WarnVO {
id: number
warnStatus: number
}
export interface EXAHistoryReqVO {
itemName?: string
startTime?: string
endTime?: string
interval?: string
}
// 查询预警列表-分页
export function getWarnPage(params: WarnPageReqVO) {
return defHttp.get({ url: '/alert/warn/page', params })
}
// 修改预警
export function updateWarn(data: WarnVO) {
return defHttp.put({ url: '/alert/warn/update', data })
}
// 查询预警详情
export function getWarn(id: number) {
return defHttp.get({ url: `/alert/warn/get?id=${id}` })
}

88
src/views/run/instant/UpdateModal.vue

@ -0,0 +1,88 @@
<script lang="ts" setup>
import { ref, unref } from 'vue'
import { updateInstantForm } from './instant.data'
import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { BasicForm, useForm } from '@/components/Form'
import { BasicModal, useModalInner } from '@/components/Modal'
import { getInstant, updateInstant } from '@/api/alert/run/instant/index'
import { getModelVersionList } from '@/api/alert/run/model/index'
import { getCalcGroupList } from '@/api/alert/run/calcgroup/index'
defineOptions({ name: 'InstantUpdateModal' })
const emit = defineEmits(['success', 'register'])
const { t } = useI18n()
const { createMessage } = useMessage()
const isUpdate = ref(true)
const [registerForm, { updateSchema, setFieldsValue, resetFields, validate }] = useForm({
labelWidth: 120,
baseColProps: { span: 24 },
schemas: updateInstantForm,
showActionButtonGroup: false,
actionColOptions: { span: 23 },
})
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields()
// modal
isUpdate.value = !!data?.isUpdate
if (unref(isUpdate)) {
const res = await getInstant(data.record.id)
setFieldsValue({ ...res })
}
//
const versionData = await getModelVersionList({ modelId: data?.record.modelId })
const versionList = [] as any
// //
versionData.forEach((item) => {
versionList.push({ label: item.version, value: item.id })
})
const calcGroupData = await getCalcGroupList({ unitId: data?.record.unitId })
const calcGroupList = [] as any
// //
calcGroupData.forEach((item) => {
calcGroupList.push({ label: item.groupName, value: item.id })
})
//
updateSchema({
field: 'modelVersionId',
componentProps: {
options: versionList,
},
})
updateSchema({
field: 'calcGroup',
componentProps: {
options: calcGroupList,
},
})
setModalProps({ useWrapper: true, minHeight: 180, confirmLoading: false })
})
async function handleSubmit() {
try {
const values = await validate()
setModalProps({ confirmLoading: true })
if (unref(isUpdate))
await updateInstant(values)
closeModal()
emit('success')
createMessage.success(t('common.saveSuccessText'))
}
finally {
setModalProps({ confirmLoading: false })
}
}
</script>
<template>
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>

11
src/views/run/instant/index.vue

@ -2,10 +2,11 @@
import { Badge, Switch } from 'ant-design-vue'
import { onMounted, ref } from 'vue'
import { color } from 'echarts'
import HistoryModal from '../../exa/config/HistoryModal.vue'
import { columns, searchFormSchema } from './instant.data'
import CreateModal from './CreateModal.vue'
import UpdateModal from './UpdateModal.vue'
import { BasicTable, TableAction, useTable } from '@/components/Table'
import { getInstantCount, getInstantPage, updateInstant } from '@/api/alert/run/instant'
import { getExaNow } from '@/api/alert/exa'
@ -21,6 +22,7 @@ const { t } = useI18n()
const [registerHistoryModal, { openModal: openHistoryModal }] = useModal()
const [registerCreateModal, { openModal: openCreateModal }] = useModal()
const [registerUpdateModal, { openModal: openUpdateModal }] = useModal()
const [registerTable, { getForm, reload, getDataSource, updateTableDataRecord }] = useTable({
title: '实例列表',
@ -67,7 +69,7 @@ function handleCreate() {
}
function handleEdit(record: Recordable) {
openModal(true, { record, isUpdate: true })
openUpdateModal(true, { record, isUpdate: true })
}
async function handleDelete(record: Recordable) {
await deleteRole(record.id)
@ -131,8 +133,8 @@ async function getNow() {
})
}
function handleWarnConfig() {
function handleWarnConfig(record: Recordable) {
router.push(`/run/warnConfig?id=${record.id}`)
}
</script>
@ -228,6 +230,7 @@ function handleWarnConfig() {
</BasicTable>
<HistoryModal :item-name="itemName" :legend-name="legendName" @register="registerHistoryModal" />
<CreateModal :item-name="itemName" :legend-name="legendName" @register="registerCreateModal" @success="reload" />
<UpdateModal @register="registerUpdateModal" @success="reload" />
</div>
</template>

40
src/views/run/instant/instant.data.ts

@ -342,7 +342,47 @@ export const createInstantForm: FormSchema[] = [
},
]
export const updateInstantForm: FormSchema[] = [
{
label: '编号',
field: 'id',
component: 'Input',
required: true,
show: false,
},
{
label: '实例名称',
field: 'mpName',
component: 'Input',
required: true,
componentProps: {
placeholder: '请输入实例名称',
},
rules: [{ required: true, message: '请输入实例名称' }],
},
{
label: '计算组',
field: 'calcGroup',
component: 'Select',
componentProps: {
options: [],
},
required: true,
},
{
label: '版本号',
field: 'modelVersionId',
component: 'Select',
componentProps: {
options: [],
},
required: true,
},
]
export const InstantBasicInfo: any[] = [
{

125
src/views/warn/index.vue

@ -0,0 +1,125 @@
<script lang="ts" setup>
import { Badge, Switch } from 'ant-design-vue'
import { onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'
import HistoryModal from '../../exa/config/HistoryModal.vue'
import { columns, searchFormSchema } from './warn.data'
import CreateModal from './CreateModal.vue'
import UpdateModal from './UpdateModal.vue'
import { BasicTable, TableAction, useTable } from '@/components/Table'
import { getWarnPage, updateWarn } from '@/api/alert/warn'
import { getExaNow } from '@/api/alert/exa'
import { useI18n } from '@/hooks/web/useI18n'
import { router } from '@/router'
import { useMessage } from '@/hooks/web/useMessage'
import { IconEnum } from '@/enums/appEnum'
import { useModal } from '@/components/Modal'
defineOptions({ name: 'Warn' })
const route = useRoute()
const { createMessage } = useMessage()
const { t } = useI18n()
const [registerUpdateModal, { openModal: openUpdateModal }] = useModal()
const [registerTable, { getForm, reload, getDataSource, updateTableDataRecord }] = useTable({
title: '预警测点列表',
api: getWarnPage,
rowKey: 'id',
immediate: true,
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
showResetButton: false,
showSubmitButton: false,
actionColOptions: {
span: 2,
},
},
beforeFetch: (params) => {
//
params.mpId = route.query.id
getForm().setFieldsValue(params)
return params
},
useSearchForm: !route.query.id,
showTableSetting: true,
showIndexColumn: false,
actionColumn: {
width: 120,
title: t('common.action'),
dataIndex: 'action',
fixed: 'right',
},
})
async function updateStatus(record) {
await updateWarn(record)
createMessage.success(t('common.saveSuccessText'))
console.log(record)
reload()
}
function handleWarnConfig(record: Recordable) {
openUpdateModal(true, { record, isUpdate: true })
}
onMounted(async () => {
})
</script>
<template>
<div>
<BasicTable @register="registerTable">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{ icon: IconEnum.WARN, label: t('action.warnConfig'), auth: 'run:instant:warnConfig', onClick: handleWarnConfig.bind(null, record) },
]"
/>
</template>
</template>
<template #warnStatus="{ record }">
<Switch
v-model:checked="record.warnStatus" :checked-value="1" :un-checked-value="0" checked-children="是"
un-checked-children="否" @change="updateStatus(record)"
/>
</template>
<template #shortMessageOnOff="{ record }">
<Switch
v-model:checked="record.shortMessageOnOff" :checked-value="1" :un-checked-value="0" checked-children="是"
un-checked-children="否" @change="updateStatus(record)"
/>
</template>
<template #gzpOnOff="{ record }">
<Switch
v-model:checked="record.gzpOnOff" :checked-value="1" :un-checked-value="0" checked-children="是"
un-checked-children="否" @change="updateStatus(record)"
/>
</template>
<template #copyToDiagOnOff="{ record }">
<Switch
v-model:checked="record.copyToDiagOnOff" :checked-value="1" :un-checked-value="0" checked-children="是"
un-checked-children="否" @change="updateStatus(record)"
/>
</template>
<template #timeDurationThreshold="{ record }">
{{ `${record.timeDurationThreshold}` }}
</template>
</BasicTable>
<UpdateModal @register="registerUpdateModal" @success="reload" />
</div>
</template>
<style lang="less" scoped>
</style>

88
src/views/warn/updateModal.vue

@ -0,0 +1,88 @@
<script lang="ts" setup>
import { ref, unref } from 'vue'
import { updateWarnForm } from './warn.data'
import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { BasicForm, useForm } from '@/components/Form'
import { BasicModal, useModalInner } from '@/components/Modal'
import { getWarn, updateWarn } from '@/api/alert/warn/index'
import { getModelVersionList } from '@/api/alert/run/model/index'
import { getCalcGroupList } from '@/api/alert/run/calcgroup/index'
defineOptions({ name: 'WarnUpdateModal' })
const emit = defineEmits(['success', 'register'])
const { t } = useI18n()
const { createMessage } = useMessage()
const isUpdate = ref(true)
const [registerForm, { updateSchema, setFieldsValue, resetFields, validate }] = useForm({
labelWidth: 120,
baseColProps: { span: 24 },
schemas: updateWarnForm,
showActionButtonGroup: false,
actionColOptions: { span: 23 },
})
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields()
setModalProps({ useWrapper: true, minHeight: 180, confirmLoading: false })
// modal
isUpdate.value = !!data?.isUpdate
if (unref(isUpdate)) {
const res = await getWarn(data.record.id)
setFieldsValue({ ...res })
}
// //
// const versionData = await getModelVersionList({ modelId: data?.record.modelId })
// const versionList = [] as any
// // //
// versionData.forEach((item) => {
// versionList.push({ label: item.version, value: item.id })
// })
// const calcGroupData = await getCalcGroupList({ unitId: data?.record.unitId })
// const calcGroupList = [] as any
// // //
// calcGroupData.forEach((item) => {
// calcGroupList.push({ label: item.groupName, value: item.id })
// })
// //
// updateSchema({
// field: 'modelVersionId',
// componentProps: {
// options: versionList,
// },
// })
// updateSchema({
// field: 'calcGroup',
// componentProps: {
// options: calcGroupList,
// },
// })
})
async function handleSubmit() {
try {
const values = await validate()
setModalProps({ confirmLoading: true })
if (unref(isUpdate))
await updateWarn(values)
closeModal()
emit('success')
createMessage.success(t('common.saveSuccessText'))
}
finally {
setModalProps({ confirmLoading: false })
}
}
</script>
<template>
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>

352
src/views/warn/warn.data.ts

@ -0,0 +1,352 @@
import type { BasicColumn, FormSchema } from '@/components/Table'
export const columns: BasicColumn[] = [
{
title: '编号',
dataIndex: 'id',
width: 80,
fixed: 'left',
},
{
title: '点号',
dataIndex: 'pointId',
width: 150,
fixed: 'left',
},
{
title: '描述',
dataIndex: 'pointName',
width: 200,
},
{
title: '单位',
dataIndex: 'unit',
width: 80,
},
{
title: '上限',
dataIndex: 'uplimit',
width: 80,
},
{
title: '下限',
dataIndex: 'lowlimit',
width: 80,
},
{
title: '实例名称',
dataIndex: 'mpName',
width: 250,
fixed: 'left',
},
{
title: '专业',
dataIndex: 'systemName',
width: 200,
},
{
title: '报警类型',
dataIndex: 'alarmModelRuleName',
width: 120,
},
{
title: '报警限制',
dataIndex: 'warnConstraintName',
width: 120,
},
{
title: '报警类型',
dataIndex: 'alarmModelRuleName',
width: 120,
},
{
title: '告警延时',
dataIndex: 'timeDurationThreshold',
width: 100,
slots: { customRender: 'timeDurationThreshold' },
},
{
title: '短信告警',
dataIndex: 'shortMessageOnOff',
width: 100,
slots: { customRender: 'shortMessageOnOff' },
},
{
title: '光字牌告警',
dataIndex: 'gzpOnOff',
width: 100,
slots: { customRender: 'gzpOnOff' },
},
{
title: '推送诊断',
dataIndex: 'copyToDiagOnOff',
width: 100,
slots: { customRender: 'copyToDiagOnOff' },
},
{
title: '已有实例数量',
dataIndex: 'number',
width: 100,
},
{
title: '参与报警',
dataIndex: 'warnStatus',
width: 100,
slots: { customRender: 'warnStatus' },
fixed: 'right',
},
// {
// title: '实时值',
// dataIndex: 'value',
// width: 90,
// className: 'value',
// slots: { customRender: 'value' },
// }
]
export const searchFormSchema: FormSchema[] = [
{
label: '模型实例id',
field: 'mpId',
component: 'Input',
defaultValue: '',
required: true,
show: false,
colProps: { span: 8 },
},
]
export const updateWarnForm: FormSchema[] = [
{
label: '编号',
field: 'id',
component: 'Input',
required: true,
show: false,
},
{
label: '残差上限',
field: 'uplimit',
component: 'Input',
required: true,
componentProps: {
placeholder: '请输入残差上限',
},
rules: [{ required: true, message: '请输入残差上限' }],
colProps: {
span: 12,
},
},
{
label: '残差下限',
field: 'lowlimit',
component: 'Input',
required: true,
componentProps: {
placeholder: '请输入残差下限',
},
rules: [{ required: true, message: '请输入残差下限' }],
colProps: {
span: 12,
},
},
{
label: '延时告警',
field: 'timeDurationThreshold',
component: 'Input',
required: true,
componentProps: {
placeholder: '请输入延时告警',
},
rules: [{ required: true, message: '请输入延时告警' }],
colProps: {
span: 12,
},
},
{
label: '告警等级',
field: 'alarmLevel',
component: 'Select',
componentProps: {
options: [],
},
required: true,
colProps: {
span: 12,
},
},
{
label: '光字牌名称',
field: 'gzpName',
component: 'Input',
required: true,
colProps: {
span: 12,
},
},
{
label: '光字牌状态',
field: 'gzpOnOff',
component: 'RadioGroup',
componentProps: {
// 数据源1:固定数据
options: [
{ label: '是', value: 1 },
{ label: '否', value: 0 },
],
},
required: true,
colProps: {
span: 12,
},
},
{
label: '短信推送',
field: 'shortMessageOnOff',
component: 'RadioGroup',
componentProps: {
options: [{ label: '是', value: 1 }, { label: '否', value: 0 }],
},
required: true,
colProps: {
span: 12,
},
},
{
label: '推送诊断',
field: 'copyToDiagOnOff',
component: 'RadioGroup',
componentProps: {
options: [{ label: '是', value: 1 }, { label: '否', value: 0 }],
},
required: true,
colProps: {
span: 12,
},
},
{
label: '告警限制名称',
field: 'warnConstraintName',
component: 'Input',
required: true,
colProps: {
span: 12,
},
},
{
label: '告警限制条件',
field: 'warnConstraint',
component: 'Input',
required: true,
colProps: {
span: 12,
},
},
]
export const InstantBasicInfo: any[] = [
{
label: '实例名称',
field: 'mpName',
},
{
label: '创建人',
field: 'creator',
},
{
label: '创建时间',
field: 'createTime',
},
{
label: '最近修改人',
field: 'updater',
},
{
label: '最近修改时间',
field: 'updateTime',
},
{
label: '算法',
field: 'algorithm_shortname',
},
// modelInfo中的字段
{
label: '训练采样间隔',
field: 'sampling',
},
{
label: '参数个数',
field: 'pointInfo',
},
{
label: '最小主元贡献率',
field: 'rate',
},
{
label: '主元个数',
field: 'principal',
},
{
label: '模型精度',
field: 'rate',
},
]
export const detailColumns: BasicColumn[] = [
{
title: '编号',
dataIndex: 'id',
width: 80,
fixed: 'left',
},
{
title: '测点编码',
dataIndex: 'inputInfo',
width: 150,
fixed: 'left',
},
{
title: '测点名称',
dataIndex: 'inputName',
width: 200,
fixed: 'left',
},
{
title: '单位',
dataIndex: 'unit',
width: 50,
fixed: 'left',
},
{
title: '重构值测点',
dataIndex: 'outPointInfo',
width: 200,
},
{
title: '偏差值测点',
dataIndex: 'biasPointInfo',
width: 200,
},
{
title: '错误状态测点',
dataIndex: 'faultVariablePointInfo',
width: 200,
},
]
Loading…
Cancel
Save