From e38ed569f95e563585b2db890996e969b4a0715c Mon Sep 17 00:00:00 2001 From: xiaojinfei <378266566@qq.com> Date: Fri, 9 Jan 2026 11:34:55 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat:=E9=A2=84=E8=AD=A6=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=85=B3=E8=81=94=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/alert/warn/index.ts | 6 ++ src/views/warn/config/UpdateModal.vue | 90 ++++++++++++++++++++------- src/views/warn/config/warn.data.ts | 14 +++-- 3 files changed, 85 insertions(+), 25 deletions(-) diff --git a/src/api/alert/warn/index.ts b/src/api/alert/warn/index.ts index 376093b..6e74328 100644 --- a/src/api/alert/warn/index.ts +++ b/src/api/alert/warn/index.ts @@ -26,6 +26,12 @@ export function getWarnPageReal(params: WarnPageReqVO) { return defHttp.get({ url: '/alert/warn/page-real', params }) } +// 修改预警 +export function createWarn(data: WarnVO) { + return defHttp.post({ url: '/alert/warn/create', data }) +} + + // 修改预警 export function updateWarn(data: WarnVO) { return defHttp.put({ url: '/alert/warn/update', data }) diff --git a/src/views/warn/config/UpdateModal.vue b/src/views/warn/config/UpdateModal.vue index 8e12e3f..3403adf 100644 --- a/src/views/warn/config/UpdateModal.vue +++ b/src/views/warn/config/UpdateModal.vue @@ -5,7 +5,7 @@ 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' +import {getWarn, createWarn, updateWarn} from '@/api/alert/warn' import {getSearchFormSchema} from '@/views/run/instant/instant.data' import {Divider, Descriptions, DescriptionsItem} from 'ant-design-vue' import {getInstantPoint} from "@/api/alert/run/instant"; @@ -16,7 +16,7 @@ const emit = defineEmits(['success', 'register']) const {t} = useI18n() const {createMessage} = useMessage() const isUpdate = ref(true) - +const pointLoading = ref(true) // 新增的时候增加查询表单 const [registerQueryForm, { @@ -50,13 +50,43 @@ function getPointInfo(list, inputName) { } async function handleQuery() { - //先获取表单数据 - const queryValues = await validateQueryForm() - //查询各种点号信息 - const res = await getInstantPoint(queryValues.mpId) - //从结果中筛选inputName等于选中的inputName的项 - pointInfo.value = getPointInfo(res, queryValues?.inputName) + setProps({ + submitButtonOptions: { loading: true }, + }) + try { + //先获取表单数据 + const queryValues = await validateQueryForm() + pointLoading.value = true + //查询各种点号信息 + const res = await getInstantPoint(queryValues.mpId) + //从结果中筛选inputName等于选中的inputName的项 + pointInfo.value = getPointInfo(res, queryValues?.inputName) + // biasPointInfo:"XN.M00010001B" + // faultVariablePointInfo:"XN.M00010001F" + // id:1 + // inputInfo:"HN_01_1RRA010MT_AVALUE" + // inputName:"HN_01_1RRA010MT_AVALUE" + // outPointInfo:"XN.M00010001R" + // unit:"" + const {inputInfo, inputName, outPointInfo, ...rest} = pointInfo.value +//字段映射,后端字段和前端字段不一致,需要映射一下 + pointInfo.value = { + ...rest, + pointId: inputInfo, + pointName: inputName, + outputPoint: outPointInfo, + } + } + finally { + setProps({ + submitButtonOptions: { loading: false }, + }) + pointLoading.value = false + + } + } + const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => { resetFields() setModalProps({width: 800, useWrapper: true, minHeight: 180, confirmLoading: false}) @@ -74,19 +104,35 @@ const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) await handleQuery() } }) + async function handleSubmit() { try { const values = await validate() + // ⭐ 条件校验(重点) + if (values.inputName !== pointInfo.value.pointName) { + createMessage.error('请确保点号信息与查询结果一致,如果不一致请重新查询') + return + } setModalProps({confirmLoading: true}) if (unref(isUpdate)) { - await updateWarn(values) - closeModal() - emit('success') - createMessage.success(t('common.saveSuccessText')) - } - else{ -// 新增预警 - + await updateWarn(values) + closeModal() + emit('success') + createMessage.success(t('common.saveSuccessText')) + } else { + // 新增预警 + //先拿查询表单数据 + const queryValues = await validateQueryForm() + // 再拿输入的数据 + const values = await validate() + // 合并三个数据 + const mergedValues = {...queryValues, ...values, ...pointInfo.value} + //构造报警表达式 + mergedValues.equation = `[${mergedValues.biasPointInfo}]>UPLIMIT or [${mergedValues.biasPointInfo}] + - {{ pointInfo?.inputInfo }} - {{ pointInfo?.inputName }} - {{ pointInfo?.inputInfo + "-重构值" }} - {{ pointInfo?.outPointInfo }} - {{ pointInfo?.inputInfo + "-偏差值" }} + {{ pointInfo?.pointName }} + {{ pointInfo?.pointId }} + {{ pointInfo?.pointName + "-重构值" }} + {{ pointInfo?.outputPoint }} + {{ pointInfo?.pointName + "-偏差值" }} {{ pointInfo?.biasPointInfo }} + diff --git a/src/views/warn/config/warn.data.ts b/src/views/warn/config/warn.data.ts index ad6e2f1..3a364e9 100644 --- a/src/views/warn/config/warn.data.ts +++ b/src/views/warn/config/warn.data.ts @@ -149,6 +149,12 @@ export const updateWarnForm: FormSchema[] = [ component: 'Input', required: true, show: false, + dynamicRules: ({ values }) => { + // 假设:有 warnId = 编辑,没有 = 新增 + return values.warnId + ? [{ required: true, message: '编号不能为空' }] + : [] + }, }, { label: '残差上限', @@ -562,7 +568,7 @@ export const InstantForm: FormSchema[] = [ component: 'Select', defaultValue: mpList.value?.[0]?.mpId, colProps: { span:10}, - componentProps: () => ({ + componentProps: ({ formModel, formActionType }) => ({ placeholder: '模型实例', allowClear: false, options:mpList.value.map(instant => ({ @@ -574,14 +580,14 @@ export const InstantForm: FormSchema[] = [ const res = await getInstantPoint(mpId) console.log(res) pointList.value=res; - formModel.inputName = res.data?.[0]?.inputName + formModel.inputName = res[0]?.inputName formActionType.setFieldsValue({ - inputName: res.data?.[0]?.inputName, + inputName: res[0]?.inputName, }) } })}, { - label: '预警点号', + label: '预警点', field: 'inputName', component: 'Select', defaultValue: pointList.value?.[0]?.inputName, From 25c55571e72a060763b0c677292707c8ce15803c Mon Sep 17 00:00:00 2001 From: xiaojinfei <378266566@qq.com> Date: Fri, 9 Jan 2026 11:37:58 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feat:=E8=B6=8B=E5=8A=BF=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/exa/HistoryLine.vue | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/views/exa/HistoryLine.vue b/src/views/exa/HistoryLine.vue index 2a15960..b3ac196 100644 --- a/src/views/exa/HistoryLine.vue +++ b/src/views/exa/HistoryLine.vue @@ -60,8 +60,9 @@ watch( text: props.title, show: true, textStyle: { // 设置主标题的文字风格 - fontFamily: 'sans-serif', // 字体系列 - fontWeight: 350, + fontFamily: + '"PingFang SC","Microsoft YaHei","Helvetica Neue",Arial,sans-serif', + fontWeight: 600, color: 'black', // 字体颜色 fontSize: 16, // 文字大小 }, @@ -87,7 +88,7 @@ watch( // 网格 grid: { x: '2%', - y: '5%', + y: '10%', x2: '2%', y2: '10%', containLabel: false, From 73b43e3da6f49390334265092cd757d2ff591e9f Mon Sep 17 00:00:00 2001 From: xiaojinfei <378266566@qq.com> Date: Fri, 9 Jan 2026 11:44:14 +0800 Subject: [PATCH 3/4] =?UTF-8?q?fix:=E4=B8=8B=E6=8B=89=E6=A1=86=E9=80=9F?= =?UTF-8?q?=E5=BA=A6=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/run/calc/index.vue | 13 +- src/views/run/instant/index.vue | 37 ++-- src/views/run/instant/instant.data.ts | 241 ++++++++++++-------------- src/views/warn/alarm/index.vue | 34 ++-- src/views/warn/config/index.vue | 52 +++--- 5 files changed, 167 insertions(+), 210 deletions(-) diff --git a/src/views/run/calc/index.vue b/src/views/run/calc/index.vue index 9f06050..27ed7b9 100644 --- a/src/views/run/calc/index.vue +++ b/src/views/run/calc/index.vue @@ -30,9 +30,9 @@ const statusMap = { // 添加多选框相关状态 const selectedRowss = ref([]) -const searchSchema = ref(getSearchFormSchema(true)) // 不显示算法 +const searchSchema = getSearchFormSchema(true,true) // 显示算法,不设置默认值 -const [registerTable, {getForm, reload, getDataSource, updateTableDataRecord}] = useTable({ +const [registerTable, {setProps,getForm, reload, getDataSource, updateTableDataRecord}] = useTable({ title: '实例列表', api: getInstantPage, rowKey: 'mpId', @@ -40,13 +40,16 @@ const [registerTable, {getForm, reload, getDataSource, updateTableDataRecord}] = columns, formConfig: { labelWidth: 70, - schemas: searchSchema.value, + schemas: searchSchema, showResetButton: false, + submitButtonOptions:{ + preIcon: IconEnum.SEARCH, + }, actionColOptions: { - span: 2, + span: 3, style: { textAlign: 'left', - marginLeft: '10px', + marginLeft: '5px', } } }, diff --git a/src/views/run/instant/index.vue b/src/views/run/instant/index.vue index 97e1f43..5b2734d 100644 --- a/src/views/run/instant/index.vue +++ b/src/views/run/instant/index.vue @@ -24,7 +24,7 @@ const [registerHistoryModal, { openModal: openHistoryModal }] = useModal() const [registerCreateModal, { openModal: openCreateModal }] = useModal() const [registerUpdateModal, { openModal: openUpdateModal }] = useModal() -const searchSchema = ref(getSearchFormSchema(true,true)) // 不显示算法 +const searchSchema = getSearchFormSchema(true,true) // 显示算法,不设置默认值 const [registerTable, { setProps,getForm, reload, getDataSource, updateTableDataRecord }] = useTable({ title: '实例列表', @@ -44,7 +44,19 @@ const [registerTable, { setProps,getForm, reload, getDataSource, updateTableData } }, - formConfig: {}, + formConfig: { labelWidth: 70, + schemas: searchSchema, + showResetButton: false, + submitButtonOptions:{ + preIcon: IconEnum.SEARCH, + }, + actionColOptions: { + span: 3, + style: { + textAlign: 'left', + marginLeft: '5px', + } + } }, useSearchForm: true, showTableSetting: true, showIndexColumn: false, @@ -56,27 +68,6 @@ const [registerTable, { setProps,getForm, reload, getDataSource, updateTableData }, }) - -onMounted(async () => { - // 等待表单配置加载完成 - const searchSchema = await getSearchFormSchema(true,true,true,false,false,false) // 显示算法,不设置默认值 - setProps({ formConfig: { - labelWidth: 70, - schemas: searchSchema, - showResetButton: false, - submitButtonOptions:{ - preIcon: IconEnum.SEARCH, - }, - actionColOptions: { - span: 3, - style: { - textAlign: 'left', - marginLeft: '5px', - } - } }}) - // 加载表格数据 - reload() -}) function handleDetail(record) { console.log(record) router.push(`/run/instant/detail?mpId=${record.mpId}`) diff --git a/src/views/run/instant/instant.data.ts b/src/views/run/instant/instant.data.ts index dfd8c3e..c6e5b1c 100644 --- a/src/views/run/instant/instant.data.ts +++ b/src/views/run/instant/instant.data.ts @@ -94,113 +94,115 @@ export const columns: BasicColumn[] = [ ] +const optionList = await optionListApi() +const systemOptions = ref([]) -// /** -// * 获取搜索表单 schema -// * @param showAlgorithm 是否显示算法字段 -// */ -// export async function getSearchFormSchema(showAlgorithm = true,showAll=true): FormSchema[] { -// const optionList = await optionListApi() -// const systemOptions = ref([]) -// if(!showAll){ -// const param: systemSelectParams = { unitId: optionList.units[0].id, typeId: optionList.types[0].id } -// systemOptions.value = await subSystemListApi(param) -// } -// return [ -// { -// label: '机组', -// field: 'unit', -// component: 'Select', -// defaultValue: showAll ? null: optionList.units[0].id, -// colProps: { span: 4 }, -// componentProps: ({ formModel }) => ({ -// placeholder: '全部机组', -// style: { 'color': 'green', fontSize: '14px' }, -// options: optionList.units.map(unit => ({ value: unit.id, label: unit.name })), -// onChange: async (e: any) => { -// const param: systemSelectParams = { unitId: e, typeId: formModel.type } -// if (!param.typeId || !param.unitId) { -// systemOptions.value = [] -// return -// } -// systemOptions.value = await subSystemListApi(param) -// }, -// }), -// }, -// { -// label: '系统', -// field: 'type', -// component: 'Select', -// defaultValue: showAll ? null: optionList.types[0].id, -// colProps: { span: 4 }, -// componentProps: ({ formModel }) => ({ -// placeholder: '全部系统', -// options: optionList.types.map(type => ({ value: type.id, label: type.name })), -// onChange: async (e: any) => { -// const param: systemSelectParams = { unitId: formModel.unit, typeId: e } -// if (!param.typeId || !param.unitId) { -// systemOptions.value = [] -// return -// } -// systemOptions.value = await subSystemListApi(param) -// }, -// }), -// }, -// { -// label: '子系统', -// field: 'system', -// component: 'Select', -// defaultValue: showAll ? null: systemOptions[0].id, -// colProps: { span: 4 }, -// componentProps: () => ({ -// placeholder: '全部子系统', -// options: systemOptions.value.map(system => ({ value: system.id, label: system.name })), -// }), -// }, -// { -// label: '模型实例名称', -// field: 'mpName', -// component: 'Input', -// labelWidth: 120, -// defaultValue: '', -// colProps: { span: 5 }, -// }, -// { -// label: '算法', -// field: 'algorithmId', -// component: 'Select', -// labelWidth: 50, -// componentProps: { -// placeholder: '全部算法', -// options: [ -// { value: 1, label: '主成分分析(PCA)' }, -// { value: 2, label: '神经网络(ANN)' }, -// ], -// }, -// defaultValue: null, -// colProps: { span: 3 }, -// show: showAlgorithm, // 根据参数决定是否显示 -// }, -// { -// label: '状态1', -// field: 'running', -// component: 'Input', -// show: false, -// }, -// { -// label: '状态2', -// field: 'runningLog', -// component: 'Input', -// show: false, -// }, -// { -// label: '状态3', -// field: 'isUpdate', -// component: 'Input', -// show: false, -// }, -// ] -// } +//显示全部就不查询子系统 +const param: systemSelectParams = { unitId: optionList.units[0].id, typeId: optionList.types[0].id } + systemOptions.value = await subSystemListApi(param) + + +/** + * 获取搜索表单 schema + * @param showAlgorithm 是否显示算法字段 + */ +export function getSearchFormSchema(showAlgorithm = true,showAll=true): FormSchema[] { + if(showAll){systemOptions.value=[]} + return [ + { + label: '机组', + field: 'unit', + component: 'Select', + defaultValue: showAll ? null: optionList.units[0].id, + colProps: { span: 4 }, + componentProps: ({ formModel }) => ({ + placeholder: '全部机组', + style: { 'color': 'green', fontSize: '14px' }, + options: optionList.units.map(unit => ({ value: unit.id, label: unit.name })), + onChange: async (e: any) => { + const param: systemSelectParams = { unitId: e, typeId: formModel.type } + if (!param.typeId || !param.unitId) { + systemOptions.value = [] + return + } + systemOptions.value = await subSystemListApi(param) + }, + }), + }, + { + label: '系统', + field: 'type', + component: 'Select', + defaultValue: showAll ? null: optionList.types[0].id, + colProps: { span: 4 }, + componentProps: ({ formModel }) => ({ + placeholder: '全部系统', + options: optionList.types.map(type => ({ value: type.id, label: type.name })), + onChange: async (e: any) => { + const param: systemSelectParams = { unitId: formModel.unit, typeId: e } + if (!param.typeId || !param.unitId) { + systemOptions.value = [] + return + } + systemOptions.value = await subSystemListApi(param) + }, + }), + }, + { + label: '子系统', + field: 'system', + component: 'Select', + defaultValue: showAll ? null: systemOptions[0].id, + colProps: { span: 4 }, + componentProps: () => ({ + placeholder: '全部子系统', + options: systemOptions.value.map(system => ({ value: system.id, label: system.name })), + }), + }, + { + label: '模型实例名称', + field: 'mpName', + component: 'Input', + labelWidth: 120, + defaultValue: '', + colProps: { span: 5 }, + }, + { + label: '算法', + field: 'algorithmId', + component: 'Select', + labelWidth: 50, + componentProps: { + placeholder: '全部算法', + options: [ + { value: 1, label: '主成分分析(PCA)' }, + { value: 2, label: '神经网络(ANN)' }, + ], + }, + defaultValue: null, + colProps: { span: 3 }, + show: showAlgorithm, // 根据参数决定是否显示 + }, + { + label: '状态1', + field: 'running', + component: 'Input', + show: false, + }, + { + label: '状态2', + field: 'runningLog', + component: 'Input', + show: false, + }, + { + label: '状态3', + field: 'isUpdate', + component: 'Input', + show: false, + }, + ] +} /** * 获取搜索表单 schema(vben 标准版) */ @@ -211,7 +213,7 @@ export interface selectParams { systemId: number | null; } -export async function getSearchFormSchema( +export async function getSearchFormSchema1( showAlgorithm = true, showAll = true, showName=true, @@ -219,7 +221,6 @@ export async function getSearchFormSchema( haveMpId = true, haveWarn = true, ): Promise { - const optionList = await optionListApi() const mpList = ref([]) // 子系统 options 用普通变量维护(不是 ref) @@ -270,18 +271,6 @@ const mpList = ref([]) else{ formActionType.setFieldsValue({system: null}) } - // //拿到该机组、该系统、该子系统的模型实例 - // mpList.value = await getInstantList({ - // unit: unitId, - // type: formModel.type, - // system: formModel.system, - // }) - // if (mpList.value.length) { - // formActionType.setFieldsValue({mpId: mpList.value[0].mpId}) - // } - // else{ - // formActionType.setFieldsValue({mpId: null}) - // } }, }), }, @@ -313,18 +302,6 @@ const mpList = ref([]) else{ formActionType.setFieldsValue({system: null}) } - // //拿到该机组、该系统、该子系统的模型实例 - // mpList.value = await getInstantList({ - // unit: formModel.unit, - // type: typeId, - // system: formModel.system, - // }) - // if (mpList.value.length) { - // formActionType.setFieldsValue({mpId: mpList.value[0].mpId}) - // } - // else{ - // formActionType.setFieldsValue({mpId: null}) - // } }, }), }, diff --git a/src/views/warn/alarm/index.vue b/src/views/warn/alarm/index.vue index f41be42..ad5b027 100644 --- a/src/views/warn/alarm/index.vue +++ b/src/views/warn/alarm/index.vue @@ -25,6 +25,7 @@ const { createMessage } = useMessage() const { t } = useI18n() const [registerUpdateModal, { openModal: openUpdateModal }] = useModal() const [registerTrendModal, { openModal: openTrendModal }] = useModal() +const searchSchema = getSearchFormSchema(false, true) // 显示算法,不设置默认值 const [registerTable, { setProps,getForm,reload, getDataSource,setTableData,updateTableDataRecord }] = useTable({ title: '集中告警列表', @@ -34,7 +35,19 @@ const [registerTable, { setProps,getForm,reload, getDataSource,setTableData,upda columns, //这个要写,不然不生效 useSearchForm: true, - formConfig: {}, + formConfig: { labelWidth: 80, + schemas: searchSchema, + showResetButton: false, + submitButtonOptions:{ + preIcon: IconEnum.SEARCH, + }, + actionColOptions: { + span: 3, + style: { + textAlign: 'left', + marginLeft: '10px', + } + }}, showTableSetting: true, showIndexColumn: false, actionColumn: { @@ -45,25 +58,6 @@ const [registerTable, { setProps,getForm,reload, getDataSource,setTableData,upda } }) -onMounted(async () => { - // 等待表单配置加载完成 - const searchSchema = await getSearchFormSchema(false, true,true,false,false,false) // 显示算法,不设置默认值 -setProps({ formConfig: { - labelWidth: 80, - schemas: searchSchema, - showResetButton: false, - submitButtonOptions:{ - preIcon: IconEnum.SEARCH, - }, - actionColOptions: { - span: 3, - style: { - textAlign: 'left', - marginLeft: '10px', - } - } }}) - -}) function handleUpdate(record: Recordable) { openUpdateModal(true, { record, isUpdate: true }) } diff --git a/src/views/warn/config/index.vue b/src/views/warn/config/index.vue index eecf8cf..33ccb19 100644 --- a/src/views/warn/config/index.vue +++ b/src/views/warn/config/index.vue @@ -24,13 +24,34 @@ const { createMessage } = useMessage() const { t } = useI18n() const [registerUpdateModal, { openModal: openUpdateModal }] = useModal() +const [registerTrendModal, { openModal: openTrendModal }] = useModal() + +const searchSchema = getSearchFormSchema(false, true) // 显示算法,不设置默认值 + +const searchForm = computed(() => { + const schemas = [searchFormSchema] + schemas.push(...searchSchema) + return schemas +}) const [registerTable, { setProps,getForm, reload, getDataSource, updateTableDataRecord }] = useTable({ title: '预警测点列表', api: getWarnPage, rowKey: 'warnId', immediate: true, columns, - formConfig: {}, + formConfig: { labelWidth: 80, + schemas: searchForm.value, + showResetButton: false, + submitButtonOptions:{ + preIcon: IconEnum.SEARCH, + }, + actionColOptions: { + span: 4, + style: { + textAlign: 'left', + marginLeft: '5px', + } + }}, beforeFetch: (params) => ({ ...params, mpId: route.query.mpId ?? null, @@ -67,36 +88,7 @@ async function handleTrend(record: Recordable) { warnId.value=record.warnId; openTrendModal(true, { record }) } - -onMounted(async () => { - // 等待表单配置加载完成 - const searchSchema = await getSearchFormSchema(false, true,true,false,false,false) // 显示算法,不设置默认值 - const searchForm = computed(() => { - const schemas = [searchFormSchema] - schemas.push(...searchSchema) - return schemas - }) - console.log(searchForm.value) - // 重新设置表格属性 - setProps({ formConfig: { - labelWidth: 80, - schemas: searchForm.value, - showResetButton: false, - submitButtonOptions:{ - preIcon: IconEnum.SEARCH, - }, - actionColOptions: { - span: 4, - style: { - textAlign: 'left', - marginLeft: '5px', - } - } }}) - // 加载表格数据 - reload() -}) -