Browse Source

Merge branch 'dev-xjf' of http://120.26.116.243:3000/root/alert-front into cjl-dev

pull/24/head
Jiale 6 months ago
parent
commit
39f224c943
  1. 2
      .env
  2. 10
      src/api/alert/run/calcgroup/index.ts
  3. 87
      src/api/alert/run/instant/index.ts
  4. 19
      src/api/alert/run/model/index.ts
  5. 33
      src/api/alert/warn/index.ts
  6. 3
      src/enums/appEnum.ts
  7. 9
      src/hooks/web/useECharts.ts
  8. 6
      src/locales/lang/en/action.json
  9. 5
      src/locales/lang/zh-CN/action.json
  10. 2
      src/utils/http/axios/index.ts
  11. 114
      src/views/exa/EXAHistoryLine.vue
  12. 189
      src/views/exa/HistoryLine.vue
  13. 28
      src/views/exa/config/HistoryModal.vue
  14. 9
      src/views/exa/config/index.vue
  15. 73
      src/views/exa/history/PointModal.vue
  16. 260
      src/views/exa/history/index copy.vue
  17. 5
      src/views/exa/history/index.vue
  18. 211
      src/views/run/instant/CreateModal.vue
  19. 88
      src/views/run/instant/UpdateModal.vue
  20. 195
      src/views/run/instant/detail.vue
  21. 260
      src/views/run/instant/index.vue
  22. 479
      src/views/run/instant/instant.data.ts
  23. 66
      src/views/run/model/ModelTable.vue
  24. 110
      src/views/run/model/PointTable.vue
  25. 55
      src/views/run/model/model.data.ts
  26. 34
      src/views/run/model/point.data.ts
  27. 4
      src/views/system/role/index.vue
  28. 125
      src/views/warn/index.vue
  29. 88
      src/views/warn/updateModal.vue
  30. 352
      src/views/warn/warn.data.ts

2
.env

@ -14,7 +14,7 @@ VITE_GLOB_APP_TENANT_ENABLE = false
VITE_GLOB_APP_CAPTCHA_ENABLE = true
# 文档地址的开关
VITE_APP_DOCALERT_ENABLE=true
VITE_APP_DOCALERT_ENABLE=false
# 百度统计
VITE_APP_BAIDU_CODE = eb21166668bf766b9d059a6fd1c10777

10
src/api/alert/run/calcgroup/index.ts

@ -0,0 +1,10 @@
import { defHttp } from '@/utils/http/axios'
export interface CalcGroupPageReqVO extends PageParam {
unitId?: number
}
// 查询计算组列表-不分页
export function getCalcGroupList(params: CalcGroupPageReqVO) {
return defHttp.get({ url: '/alert/calcgroup/list', params })
}

87
src/api/alert/run/instant/index.ts

@ -0,0 +1,87 @@
import qs from 'qs'
import { defHttp } from '@/utils/http/axios'
export interface InstantPageReqVO extends PageParam {
mpName?: string
}
export interface InstantVO {
id: number
status: number
modelId: number
pointInfo: Array<any>
mpName: string
intervalTime: number
visible: number
hisSto: number
calcGroup: number
modelVersionId: number
}
export interface EXAHistoryReqVO {
itemName?: string
startTime?: Date
endTime?: Date
interval?: string
}
export interface InstantChartReqVO extends EXAHistoryReqVO {
id?: number
}
export interface EXANowReqVO {
itemName?: string
}
export interface EXAPoint {
AssetCode?: string
ItemName?: string
GroupName?: string
ItemType?: number
Descriptor?: string
EngUnits?: string
Source?: string
AutoSave?: number
UpperBound?: number
LowerBound?: number
UpperLimit?: number
LowerLimit?: number
UpperUpperLimit?: number
LowerLowerLimit?: number
Comment?: string
Note?: string
}
// 查询模型实例列表
export function getInstantPage(params: InstantPageReqVO) {
return defHttp.get({ url: '/alert/instant/page', params })
}
// 查询模型实例详情
export function getInstant(id: number) {
return defHttp.get({ url: `/alert/instant/get?id=${id}` })
}
// 新增模型实例
export function createInstant(data: InstantVO) {
return defHttp.post({ url: '/alert/instant/create', data })
}
// 修改模型实例
export function updateInstant(data: InstantVO) {
return defHttp.put({ url: '/alert/instant/update', data })
}
// 获取模型实例数量
export function getInstantCount() {
return defHttp.get({ url: '/alert/instant/count' })
}
// 查询模型实例测点列表
export function getInstantPoint(id: number) {
return defHttp.get({ url: `/alert/instant/getPoint?id=${id}` })
}
// 查询模型实例测点曲线
export function getInstantChart(data: InstantChartReqVO) {
return defHttp.post({ url: `/alert/instant/getChart`, data })
}

19
src/api/alert/run/model/index.ts

@ -0,0 +1,19 @@
import { defHttp } from '@/utils/http/axios'
export interface ModelPageReqVO extends PageParam {
modelName?: string
}
export interface ModelVersionPageReqVO extends PageParam {
modelId?: number
}
// 查询模型实例列表
export function getModelPage(params: ModelPageReqVO) {
return defHttp.get({ url: '/alert/model/page', params })
}
// 查询模型版本列表-不分页
export function getModelVersionList(params: ModelVersionPageReqVO) {
return defHttp.get({ url: '/alert/model/version/list', params })
}

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}` })
}

3
src/enums/appEnum.ts

@ -71,4 +71,7 @@ export enum IconEnum {
SETTING = 'ant-design:setting-outlined',
SEND = 'ant-design:send-outlined',
ADDS = 'ant-design:plus-circle-outlined',
CHANGE = 'ant-design:one-to-one-outlined',
WARN = 'ant-design:warning-outlined',
}

9
src/hooks/web/useECharts.ts

@ -8,13 +8,14 @@ import echarts from '@/utils/lib/echarts'
import { useRootSetting } from '@/hooks/setting/useRootSetting'
import { useMenuSetting } from '@/hooks/setting/useMenuSetting'
export function useECharts(elRef: Ref<HTMLDivElement>, theme: 'light' | 'dark' | 'default' = 'default') {
export function useECharts(elRef: Ref<HTMLDivElement>, theme: 'light' | 'dark' | 'default' = 'default', isAsync) {
const { getDarkMode: getSysDarkMode } = useRootSetting()
const { getCollapsed } = useMenuSetting()
const getDarkMode = computed(() => {
return theme === 'default' ? getSysDarkMode.value : theme
})
let chartInstance: echarts.ECharts | null = null
let resizeFn: Fn = resize
const cacheOptions = ref({}) as Ref<EChartsOption>
@ -38,6 +39,11 @@ export function useECharts(elRef: Ref<HTMLDivElement>, theme: 'light' | 'dark' |
return
chartInstance = echarts.init(el, t)
// 是否做同步
if (isAsync === true)
chartInstance.group = 'async'
const { removeEvent } = useEventListener({
el: window,
name: 'resize',
@ -120,6 +126,7 @@ export function useECharts(elRef: Ref<HTMLDivElement>, theme: 'light' | 'dark' |
}
return {
chartInstance,
setOptions,
resize,
echarts,

6
src/locales/lang/en/action.json

@ -11,5 +11,9 @@
"test": "Test",
"view": "View",
"clearAllandClose": "ClearAllAndClose",
"createBatch": "CreateBatch"
"createBatch": "CreateBatch",
"createInstant": "CreateInstant",
"pointConfig": "PointConfig",
"warnConfig": "WarnConfig"
}

5
src/locales/lang/zh-CN/action.json

@ -12,5 +12,8 @@
"test": "测试",
"view": "查看",
"clearAllandClose": "清空并关闭",
"createBatch": "批量导入"
"createBatch": "批量导入",
"createInstant": "新增实例",
"pointConfig": "测点配置",
"warnConfig": "预警配置"
}

2
src/utils/http/axios/index.ts

@ -277,7 +277,7 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) {
// authentication schemes,e.g: Bearer
// authenticationScheme: 'Bearer',
authenticationScheme: 'Bearer',
timeout: 20 * 1000,
timeout: 60 * 1000,
// 基础接口地址
// baseURL: globSetting.apiUrl,

114
src/views/exa/EXAHistoryLine.vue

@ -1,114 +0,0 @@
<script lang="ts" setup>
import type { Ref } from 'vue'
import { onMounted, ref, watch } from 'vue'
import type { YAXisOption } from 'echarts/types/dist/shared'
import { useECharts } from '@/hooks/web/useECharts'
import { propTypes } from '@/utils/propTypes'
const props = defineProps({
height: {
type: String,
default: propTypes.string.def('500px'),
},
name: {
type: Array<string>,
default: [],
},
data: {
type: Array<Array<number>>,
default: () => [[]],
},
width: propTypes.string.def('100%'),
// height: propTypes.string.def('70vh'),
})
const chartRef = ref<HTMLDivElement | null>(null)
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
onMounted(() => {
})
// const yAxis = reactive<yAxisForm>({
// type: 'value',
// scale: true, //
// })
watch(
() => props.data,
() => {
console.log(props.data)
const yAxis = ref<YAXisOption[]>([])
const series = ref<any[]>([])
for (let i = 0; i < props.data.length; i++) {
yAxis.value.push({
type: 'value',
show: false,
scale: true, //
})
series.value.push({
name: props.name[i],
type: 'line',
smooth: true,
itemStyle: {
normal: {
lineStyle: {
width: 3, // 0.1线
},
},
},
showSymbol: false,
data: props.data[i],
yAxisIndex: i,
})
}
setOptions({
tooltip: {
trigger: 'axis',
position(pt) {
return [pt[0], '10%']
},
},
title: {
left: 'center',
text: 'Large Ara Chart',
show: false,
},
toolbox: {
feature: {
dataZoom: {
yAxisIndex: 'none',
},
restore: {},
saveAsImage: {},
},
},
xAxis: {
type: 'time',
// boundaryGap: false,
},
yAxis: yAxis.value,
legend: {
},
dataZoom: [
{
type: 'inside',
start: 0,
end: 100,
},
{
start: 0,
end: 100,
},
],
series: series.value,
})
},
{ immediate: true },
)
</script>
<template>
<div ref="chartRef" :style="{ width, height }" />
</template>

189
src/views/exa/HistoryLine.vue

@ -0,0 +1,189 @@
<script lang="ts" setup>
import type { Ref } from 'vue'
import { onMounted, ref, watch } from 'vue'
import type { YAXisOption } from 'echarts/types/dist/shared'
import moment from 'moment'
import { useECharts } from '@/hooks/web/useECharts'
import { propTypes } from '@/utils/propTypes'
const props = defineProps({
isAsync: {
type: Boolean,
default: false,
},
height: {
type: String,
default: propTypes.string.def('500px'),
},
title: {
type: String,
default: '',
},
name: {
type: Array<string>,
default: [],
},
data: {
type: Array<Array<number>>,
default: () => [[]],
},
width: propTypes.string.def('100%'),
// height: propTypes.string.def('70vh'),
})
const chartRef = ref<HTMLDivElement | null>(null)
const { setOptions, setGroup, chartInstance } = useECharts(chartRef as Ref<HTMLDivElement>, 'default', props.isAsync)
onMounted(() => {
})
// const yAxis = reactive<yAxisForm>({
// type: 'value',
// scale: true, //
// })
watch(
() => props.data,
() => {
console.log(props.data)
const yAxis = ref<YAXisOption[]>([])
const series = ref<any[]>([])
const title = ref<any>({})
for (let i = 0; i < props.data.length; i++) {
title.value = {
left: 'left',
text: props.title,
show: true,
textStyle: { //
fontFamily: 'sans-serif', //
fontWeight: 350,
color: 'black', //
fontSize: 16, //
},
}
yAxis.value.push({
type: 'value',
show: false,
scale: true, //
})
series.value.push({
name: props.name[i],
type: 'line',
smooth: true,
showSymbol: false,
data: props.data[i],
yAxisIndex: i,
})
}
// const aa = getInstance()
setOptions({
//
grid: {
x: '2%',
y: '5%',
x2: '2%',
y2: '30%',
containLabel: false,
// width: {totalWidth} - x - x2,
// height: {totalHeight} - y - y2,
backgroundColor: 'rgba(0,0,0,0)',
borderWidth: 1,
borderColor: '#ccc',
},
tooltip: {
trigger: 'axis',
position(pt) {
return [pt[0], '10%']
},
},
title: title.value,
toolbox: {
feature: {
dataZoom: {
yAxisIndex: 'none',
},
restore: { show: false },
saveAsImage: {},
/* 自定义事件,注意:自定义事件必须以my开头 */
myTool2: {
show: true,
title: '下载csv文件', /* 鼠标停留时的提示文字 */
// icon: 'image://../0IMG/tool.png', /* ,image:// */
icon: 'path://M18 20.288L21.288 17l-.688-.688l-2.1 2.1v-4.887h-1v4.887l-2.1-2.1l-.688.688zM14.5 23.5v-1h7v1zm-10-4v-17H13L18.5 8v3.14h-1V8.5h-5v-5h-7v15h6.615v1zm1-1v-15z',
/* 点击时触发的事件 */
onclick() {
setTimeout(() => {
// 使CSV
const csv = convertToCSV(props.data)
console.log(props.data)
//
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = 'data.csv'
link.click()
function convertToCSV(data) {
let csv = ''
//
const name = props.name.join(',')
csv += `时间,${name}\n`
// CSV
for (let i = 0; i < props.data[0].length; i++) {
let data = ''
for (let j = 0; j < props.data.length; j++)
data += `,${props.data[j][i][1]}`
csv += `${moment(props.data[0][i][0]).format('YYYY-MM-DD HH:mm:ss')}${data}\n`
// props.data[i].map((item, index) => {
// csv += 'x' + ',' + 'y' + '\n'
// })
}
return csv
}
}, 10)
},
},
},
},
xAxis: {
type: 'time',
axisTick: {
length: 6,
lineStyle: {
type: 'dashed',
// ...
},
},
// boundaryGap: false,
},
yAxis: yAxis.value,
legend: {
},
dataZoom: [
{
type: 'slider',
start: 0,
end: 100,
},
//
//
// {
// start: 0,
// end: 100,
// },
],
series: series.value,
})
},
{ immediate: true },
)
</script>
<template>
<div ref="chartRef" :style="{ width, height }" />
</template>

28
src/views/exa/config/HistoryModal.vue

@ -4,16 +4,27 @@ import moment from 'moment'
import { Card } from 'ant-design-vue'
import { formHistory } from '../exa.data'
import EXAHistoryLine from '../EXAHistoryLine.vue'
import HistoryLine from '../HistoryLine.vue'
import { BasicModal, useModalInner } from '@/components/Modal'
import { BasicForm, useForm } from '@/components/Form'
import { getExaHistorys } from '@/api/alert/exa'
const props = defineProps({
itemName: {
type: String,
default: '',
},
legendName: {
type: Array<string>,
default: () => [],
},
})
const loading = ref(true)
const itemName = ref('')
// const itemName = ref('')
const [registerForm, { getFieldsValue }] = useForm({
labelWidth: 100,
@ -29,14 +40,14 @@ const [registerForm, { getFieldsValue }] = useForm({
actionColOptions: { span: 2 },
})
const historyData = ref()
const legendName = ref<any[]>([])
// const legendName = ref<any[]>([])
const [registerHistoryModal, { setModalProps }] = useModalInner(async (data) => {
console.log(543)
setModalProps({ confirmLoading: false, showCancelBtn: false, showOkBtn: false })
itemName.value = data.record.itemName
legendName.value = []
legendName.value.push(`${data.record.descriptor}-${data.record.itemName}`)
// props.itemName = data.record.itemName
// legendName.value = []
// legendName.value.push(`${data.record.descriptor}-${data.record.itemName}`)
handleSubmitR()
// 线
// setFieldsValue({ time: [moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')] })
@ -59,7 +70,8 @@ async function handleSubmitR() {
const exaHistoryReqVO = {
startTime: serachFormData.startTime,
endTime: serachFormData.endTime,
itemName: itemName.value,
itemName: props.itemName,
interval: 100,
}
historyData.value = await getExaHistorys(exaHistoryReqVO)
@ -71,7 +83,7 @@ async function handleSubmitR() {
<BasicModal v-bind="$attrs" title="历史曲线" width="80%" @register="registerHistoryModal">
<BasicForm @register="registerForm" @submit="handleSubmitR" />
<Card :loading="loading">
<EXAHistoryLine :data="historyData" :name="legendName" height="500px" />
<HistoryLine :data="historyData" :name="legendName" height="500px" />
</Card>
</BasicModal>
</template>

9
src/views/exa/config/index.vue

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { onMounted, onUnmounted } from 'vue'
import { onMounted, onUnmounted, ref } from 'vue'
import { columns, searchFormSchema } from '../exa.data'
import EXAModal from './EXAModal.vue'
import CreateBatchModal from './CreateBatchModal.vue'
@ -79,7 +79,12 @@ function handleCreate() {
function handleCreateBatch() {
openCreateBatchModal(true, {})
}
const itemName = ref<string>()
const legendName = ref<string[]>()
function handleHistory(record: Recordable) {
itemName.value = record.itemName
legendName.value = []
legendName.value.push(`${record.descriptor}-${record.itemName}`)
openHistoryModal(true, { record })
}
async function handleExport() {
@ -142,7 +147,7 @@ async function handleDelete(record: Recordable) {
</BasicTable>
<EXAModal @register="registerModal" @success="reload" />
<CreateBatchModal @register="registerCreateBatchModal" @success="reload" />
<HistoryModal @register="registerHistoryModal" />
<HistoryModal :item-name="itemName" :legend-name="legendName" @register="registerHistoryModal" />
</div>
</template>

73
src/views/exa/history/PointModal.vue

@ -1,5 +1,6 @@
<script lang="ts" setup>
import { computed, reactive, ref, watch } from 'vue'
import { message } from 'ant-design-vue'
import { columns, searchFormSchema } from '../exa.data'
import type { TableActionType } from '@/components/Table'
import { BasicTable, TableAction, useTable } from '@/components/Table'
@ -9,6 +10,8 @@ import { IconEnum } from '@/enums/appEnum'
import { BasicModal, useModalInner } from '@/components/Modal'
const props = defineProps({
source: { type: String, default: '' },
rowSelectType: { type: String, default: 'checkbox' },
selectedData: { type: Array<Recordable>, default: [] },
selectedRowKeys: { type: Array<number>, default: [] },
})
@ -65,7 +68,7 @@ const [registerTable] = useTable({
const rowSelection = computed(() => {
return {
preserveSelectedRowKeys: true, // 2.
type: 'checkbox',
type: props.rowSelectType,
selectedRowKeys: state.selectedRowKeys,
onChange: onSelectChange,
@ -80,42 +83,6 @@ watch(
selectedData.value = props.selectedData
},
)
// onBeforeMount(() => {
// console.log(props.selectedRowKeys)
// console.log(props.selectedData)
// state.selectedRowKeys = props.selectedRowKeys
// selectedData.value = props.selectedData
// console.log(state.selectedRowKeys)
// console.log(selectedData.value)
// emit('success')
// })
// const historyData = ref()
// const legendName = ref<any[]>([])
// async function getHistoryChart() {
// const pointCodeList = selectedData.value.map(item => (item.itemName))
// loading.value = true
// if (pointCodeList.length !== 0) {
// const pointCode = selectedData.value.map(item => (item.itemName)).join(',')
// const pointDesc: any[] = selectedData.value.map(item => (item.descriptor))
// const exaHistoryReqVO = {
// startTime: searchForm.publishTime[0],
// endTime: searchForm.publishTime[1],
// itemName: pointCode,
// }
// historyData.value = await getExaHistorys(exaHistoryReqVO)
// legendName.value = pointDesc
// }
// else {
// message.info('')
// }
// loading.value = false
// }
const [registerSelectedTable] = useTable({
title: '已选中测点列表',
showTableSetting: false,
@ -170,12 +137,23 @@ function onSelectChange(selectedRowKeys, selectedRows) {
}
function handleOk() {
console.log('onOk:')
localStorage.setItem('pointInfo', JSON.stringify(state.selectedRowKeys))
localStorage.setItem('pointInfoList', JSON.stringify(selectedData.value))
closeModal()
emit('success')
console.log(props.source)
if (props.source === 'run') {
console.log('来自运行中心-模型实例-更换测点')
if (selectedData.value.length !== 0) {
emit('success', selectedData.value)
closeModal()
}
else { message.error('请选择替换的测点,若不进行替换,请点击取消返回') }
}
else {
console.log('onOk:')
localStorage.setItem('pointInfo', JSON.stringify(state.selectedRowKeys))
localStorage.setItem('pointInfoList', JSON.stringify(selectedData.value))
closeModal()
emit('success')
}
}
async function handleDelete(record: Recordable) {
const newArr = state.selectedRowKeys.filter((value) => {
@ -197,10 +175,15 @@ function handleClearAndClose() {
closeModal()
emit('success')
}
function onCanel() {
state.selectedRowKeys = []
selectedData.value = []
}
</script>
<template>
<BasicModal v-bind="$attrs" title="测点配置" width="1000px" @register="registerPointModal" @ok="handleOk">
<BasicModal v-bind="$attrs" title="测点配置" width="1000px" @cancel="onCanel" @register="registerPointModal" @ok="handleOk">
<BasicTable
ref="tableRef" :can-resize="false" title="RefTable示例" title-help-message="使用Ref调用表格内方法"
:row-selection="rowSelection" size="small" @register="registerTable"
@ -227,7 +210,7 @@ function handleClearAndClose() {
/>
</template>
</template>
<template #toolbar>
<template v-if="props.source !== 'run'" #toolbar>
<a-button v-auth="['system:role:create']" type="primary" :pre-icon="IconEnum.DELETE" @click="handleClearAndClose">
{{ t('action.clearAllandClose') }}
</a-button>

260
src/views/exa/history/index copy.vue

@ -1,260 +0,0 @@
<script lang="ts" setup>
import { computed, onMounted, reactive, ref } from 'vue'
import type { Dayjs } from 'dayjs'
import moment from 'moment'
import { Button, Card, Form, FormItem, Modal, RangePicker, Space, message } from 'ant-design-vue'
import { columns, searchFormSchema } from '../exa.data'
import EXAHistoryLine from '../EXAHistoryLine.vue'
import type { TableActionType } from '@/components/Table'
import { BasicTable, TableAction, useTable } from '@/components/Table'
import { getEXAPage, getExaHistorys } from '@/api/alert/exa'
import { useI18n } from '@/hooks/web/useI18n'
import { IconEnum } from '@/enums/appEnum'
const { t } = useI18n()
interface FormState {
publishTime: any[]
}
const searchForm = reactive<FormState>({
publishTime: [],
})
const loading = ref(true)
function onRangeChange(value: [Dayjs, Dayjs], dateString: [string, string]) {
console.log('Selected Time: ', value)
console.log('Formatted Selected Time: ', dateString)
}
function onRangeOk(value: [Dayjs, Dayjs]) {
console.log('onOk: ', value)
console.log(searchForm.publishTime)
searchForm.publishTime = value
}
const open = ref<boolean>(false)
const selectedData = ref<Recordable[]>([])
interface RowKeys {
selectedRowKeys: number[]
}
const state = reactive<RowKeys>({
selectedRowKeys: [],
})
const tableRef = ref<Nullable<TableActionType>>(null)
const tableRef1 = ref<Nullable<TableActionType>>(null)
const [registerTable] = useTable({
title: '测点列表',
api: getEXAPage,
immediate: false,
showTableSetting: false,
tableSetting: {
//
redo: false,
//
size: false,
//
setting: false,
//
fullScreen: false,
},
columns,
formConfig: {
labelWidth: 150,
schemas: searchFormSchema,
showResetButton: false,
actionColOptions: {
span: 2,
},
},
rowKey: 'serialNumber',
useSearchForm: true,
showIndexColumn: false,
})
// computed
const rowSelection = computed(() => {
return {
preserveSelectedRowKeys: true, // 2.
type: 'checkbox',
selectedRowKeys: state.selectedRowKeys,
onChange: onSelectChange,
}
})
// defaultChecked: record.serialNumber === 93,
onMounted(() => {
state.selectedRowKeys = localStorage.getItem('pointInfo') ? JSON.parse(localStorage.getItem('pointInfo') || '') : []
selectedData.value = localStorage.getItem('pointInfoList') ? JSON.parse(localStorage.getItem('pointInfoList') || '') : []
searchForm.publishTime = [moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')]
getHistoryChart()
})
const historyData = ref()
const legendName = ref<any[]>([])
async function getHistoryChart() {
const pointCodeList = selectedData.value.map(item => (item.itemName))
loading.value = true
if (pointCodeList.length !== 0) {
const pointCode = selectedData.value.map(item => (item.itemName)).join(',')
const pointDesc: any[] = selectedData.value.map(item => (item.descriptor))
const exaHistoryReqVO = {
startTime: searchForm.publishTime[0],
endTime: searchForm.publishTime[1],
itemName: pointCode,
}
historyData.value = await getExaHistorys(exaHistoryReqVO)
legendName.value = pointDesc
}
else {
message.info('暂无测点')
}
loading.value = false
}
const [registerSelectedTable] = useTable({
title: '已选中测点列表',
showTableSetting: false,
tableSetting: {
//
redo: false,
//
size: false,
//
setting: false,
//
fullScreen: false,
},
columns,
formConfig: {
labelWidth: 150,
schemas: searchFormSchema,
showResetButton: false,
actionColOptions: {
span: 2,
},
},
rowKey: 'serialNumber',
useSearchForm: false,
showIndexColumn: false,
actionColumn: {
width: 140,
title: t('common.action'),
dataIndex: 'action',
fixed: 'right',
},
})
function openModal() {
open.value = true
console.log(24)
console.log(selectedData.value)
}
function onSelectChange(selectedRowKeys, selectedRows) {
console.log(selectedRowKeys, selectedRows)
state.selectedRowKeys = selectedRowKeys
let selectionRows: any[] = []
console.log('3', selectedData.value)
selectionRows = selectedData.value.concat(selectedRows)
console.log('2', selectionRows)
selectionRows = selectionRows.filter(item => selectedRowKeys.includes(item.serialNumber))
console.log('1', selectionRows)
//
const map = new Map()
for (const item of selectionRows) {
if (!map.has(item.serialNumber))
map.set(item.serialNumber, item)
};
selectedData.value = [...map.values()]
}
function handleOk() {
console.log('onOk:')
localStorage.setItem('pointInfo', JSON.stringify(state.selectedRowKeys))
localStorage.setItem('pointInfoList', JSON.stringify(selectedData.value))
open.value = false
getHistoryChart()
}
async function handleDelete(record: Recordable) {
const newArr = state.selectedRowKeys.filter((value) => {
return value !== record.serialNumber
})
state.selectedRowKeys = newArr
localStorage.setItem('pointInfo', JSON.stringify(state.selectedRowKeys))
const newArrObj = selectedData.value.filter((value) => {
return value.serialNumber !== record.serialNumber
})
selectedData.value = newArrObj
}
</script>
<template>
<div>
<Card>
<Form layout="inline" :model="searchForm">
<FormItem label="时间范围">
<RangePicker
:model="searchForm.publishTime"
:show-time="{ format: 'HH:mm:ss' }"
:placeholder="['开始时间', '结束时间']" :default-value="[moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')]"
value-format="YYYY-MM-DD HH:mm:ss"
@change="onRangeChange"
@ok="onRangeOk"
/>
</FormItem>
<FormItem>
<Space wrap>
<Button type="primary" @click="getHistoryChart">
查看趋势
</Button>
<Button @click="openModal()">
测点配置
</Button>
</Space>
</FormItem>
</Form>
</Card>
<Card style="margin:5px" :loading="loading">
<EXAHistoryLine :data="historyData" :name="legendName" height="70vh" />
</Card>
<Modal v-model:open="open" :destroy-on-close="false" width="1000px" title="测点配置" @ok="handleOk">
<BasicTable
ref="tableRef" :can-resize="false" title="RefTable示例" title-help-message="使用Ref调用表格内方法"
:row-selection="rowSelection" size="small" @register="registerTable"
/>
<BasicTable
ref="tableRef1" :pagination="false" size="small" :data-source="selectedData" :can-resize="false"
title="已选中测点" title-help-message="使用Ref调用表格内方法" @register="registerSelectedTable"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[{
icon: IconEnum.DELETE,
danger: true,
label: t('action.delete'),
auth: 'system:role:delete',
popConfirm: {
title: t('common.delMessage'),
placement: 'left',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</template>
</BasicTable>
</Modal>
</div>
</template>

5
src/views/exa/history/index.vue

@ -3,7 +3,7 @@ import { onMounted, reactive, ref } from 'vue'
import type { Dayjs } from 'dayjs'
import moment from 'moment'
import { Button, Card, Form, FormItem, RangePicker, Space, message } from 'ant-design-vue'
import EXAHistoryLine from '../EXAHistoryLine.vue'
import HistoryLine from '../HistoryLine.vue'
import PointModal from './PointModal.vue'
import { getExaHistorys } from '@/api/alert/exa'
import { useModal } from '@/components/Modal'
@ -59,6 +59,7 @@ async function getHistoryChart() {
startTime: searchForm.publishTime[0],
endTime: searchForm.publishTime[1],
itemName: pointCode,
interval: 100,
}
historyData.value = await getExaHistorys(exaHistoryReqVO)
legendName.value = pointDesc
@ -98,7 +99,7 @@ function handlePointModal() {
</Form>
</Card>
<Card style="margin:5px" :loading="loading">
<EXAHistoryLine :data="historyData" :name="legendName" height="70vh" />
<HistoryLine :data="historyData" :name="legendName" height="70vh" />
</Card>
<PointModal :selected-row-keys="state.selectedRowKeys" :selected-data="selectedData" @register="registerPointModal" @success="getHistoryChart" />
</div>

211
src/views/run/instant/CreateModal.vue

@ -0,0 +1,211 @@
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import { Card, Divider, Steps } from 'ant-design-vue'
import ModalTable from '../model/ModelTable.vue'
import PointTable from '../model/PointTable.vue'
import { createInstantForm } from './instant.data'
import { useI18n } from '@/hooks/web/useI18n'
import { BasicModal, useModalInner } from '@/components/Modal'
import { BasicForm, useForm } from '@/components/Form'
import { getModelVersionList } from '@/api/alert/run/model/index'
import { getCalcGroupList } from '@/api/alert/run/calcgroup/index'
import { createInstant } from '@/api/alert/run/instant/index'
import { useMessage } from '@/hooks/web/useMessage'
const emit = defineEmits(['success'])
const { createMessage } = useMessage()
const { t } = useI18n()
const [registerCreateModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
setModalProps({ destroyOnClose: true, showCancelBtn: false, showOkBtn: false })
})
const current = ref<number>(0)
function next() {
current.value++
}
function prev() {
current.value--
}
const steps = [
{
title: '壹',
content: 'First-content',
},
{
title: '贰',
content: 'Second-content',
},
]
const items = steps.map(item => ({ key: item.title, title: item.title }))
const [registerForm, { validate, setFieldsValue, updateSchema, setProps }] = useForm({
labelWidth: 100,
schemas: createInstantForm,
showSubmitButton: false,
showResetButton: false,
layout: 'horizontal',
actionColOptions: { span: 2 },
disabled: true,
})
interface instantForms {
modelId?: string
mpName?: string
}
const instantForm = reactive<instantForms>({
modelId: '',
mpName: '',
})
const isDisabled = ref<boolean>(true)
const state = reactive<any>({
pointInfo: [],
type: false,
})
async function updatempName(selectedRowKeys, selectedRows) {
console.log(selectedRows.length)
if (selectedRows.length !== 0) {
state.type = selectedRows[0].algorithm === 'ANN'
console.log(state.type)
state.pointInfo = JSON.parse(selectedRows[0].modelInfo).pointInfo
for (const p of state.pointInfo) {
p.modelName = selectedRows[0].modelName
p.modelDescription = selectedRows[0].description
p.algorithm = selectedRows[0].algorithm
}
}
//
isDisabled.value = selectedRows.length === 0
console.log(isDisabled)
if (selectedRows.length === 0)
setProps({ disabled: true })
else
setProps({ disabled: false })
instantForm.modelId = selectedRows.length !== 0 ? `${selectedRows[0].id}` : ``
instantForm.mpName = selectedRows.length !== 0 ? `${selectedRows[0].modelName}-实例` : ``
setFieldsValue(instantForm)
const versionData = selectedRows.length !== 0 ? await getModelVersionList({ modelId: selectedRows[0].id }) : []
const versionList = [] as any
// //
versionData.forEach((item) => {
versionList.push({ label: item.version, value: item.id })
})
const calcGroupData = selectedRows.length !== 0 ? await getCalcGroupList({ unitId: selectedRows[0].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,
},
})
}
function onCanel() {
current.value = 0
closeModal()
}
const loading = ref<boolean>(false)
const pointRef = ref()
async function CompleteCreate() {
try {
loading.value = true
// confirmLoading
setModalProps({ confirmLoading: true, loading: true })
const values = await validate()
// if (unref(isUpdate)) {
// await updateDemo02Category(values)
// } else {
// await createDemo02Category(values)
// }
//
//
const pointInfoNew = pointRef.value.getPointTableData()
values.pointInfo = pointInfoNew
console.log(values)
await createInstant(values)
emit('success')
createMessage.success(t('common.saveSuccessText'))
}
finally {
closeModal()
loading.value = false
// confirmLoading
setModalProps({ confirmLoading: false, loading: false })
}
}
</script>
<template>
<BasicModal v-bind="$attrs" title="新增模型实例" width="80%" @cancel="onCanel" @register="registerCreateModal">
<Card title="实例信息">
<BasicForm @register="registerForm" />
</Card>
<Divider />
<Steps :current="current" :items="items" />
<div class="steps-content">
<ModalTable v-if="current === 0" @success="updatempName" />
<PointTable v-if="current === 1" ref="pointRef" :data="state.pointInfo" :type="state.type" />
</div>
<!-- modal 底部区域插槽实现--替换原按钮 -->
<template #footer>
<div class="steps-action">
<a-button v-if="current < steps.length - 1 " :disabled="isDisabled" type="primary" @click="next">
下一步
</a-button>
<a-button
v-if="current === steps.length - 1"
type="primary"
:loading="loading"
@click="CompleteCreate"
>
完成
</a-button>
<!-- <a-button v-if="current > 0" style="margin-left: 8px" @click="prev">
上一步+
</a-button> -->
</div>
</template>
</BasicModal>
</template>
<style scoped>
.steps-content {
margin-top: 16px;
text-align: center;
background-color: #fafafa;
border: 1px dashed #e9e9e9;
border-radius: 6px;
}
.steps-action {
margin-top: 24px;
}
[data-theme='dark'] .steps-content {
background-color: #2f2f2f;
border: 1px dashed #404040;
}
</style>

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>

195
src/views/run/instant/detail.vue

@ -0,0 +1,195 @@
<script lang="ts" setup>
import { onMounted, reactive, ref } from 'vue'
import type { Dayjs } from 'dayjs'
import moment from 'moment'
import { Card, Descriptions, DescriptionsItem, Form, FormItem, RangePicker, Space, Switch, message } from 'ant-design-vue'
import { mount } from 'sortablejs'
import { number } from 'vue-types'
import { useRoute } from 'vue-router'
import HistoryLine from '../../exa/HistoryLine.vue'
import { detailColumns, instantForm } from './instant.data'
import { getExaHistorys } from '@/api/alert/exa'
import { useModal } from '@/components/Modal'
import { BasicTable, TableAction, useTable } from '@/components/Table'
import { getInstant, getInstantChart, getInstantPage, getInstantPoint } from '@/api/alert/run/instant'
import { useI18n } from '@/hooks/web/useI18n'
import { router } from '@/router'
import { BasicForm, useForm } from '@/components/Form'
import PropsPanel from '@/components/FormDesign/src/components/VFormDesign/modules/PropsPanel.vue'
import echarts from '@/utils/lib/echarts'
defineOptions({ name: 'InstantDetail' })
const route = useRoute()
// const props = defineProps({
// id: {
// type: Number,
// default: null,
// },
// })
const { t } = useI18n()
const loadingBasic = ref<boolean>(false)
const loadingChart = ref<boolean>(false)
const basicInfo = ref<any>({})
const modelInfo = ref<any>({})
const pointInfo = ref<any>({})
const pointList = ref<any>([])
const historyList = ref<any>([])
const [registerForm, { getFieldsValue, setProps }] = useForm({
labelWidth: 100,
// baseColProps: { span: 24 },
schemas: instantForm,
showResetButton: false,
layout: 'horizontal',
// model: { time: [moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')] },
fieldMapToTime: [
// datastartTimeendTime
['time', ['startTime', 'endTime'], 'YYYY-MM-DD HH:mm:ss'],
],
actionColOptions: { span: 2 },
})
const instantId = ref<any>(route.query.id) // URLquery
onMounted(async () => {
loadingBasic.value = true
basicInfo.value = await getInstant(instantId.value)
loadingBasic.value = false
modelInfo.value = JSON.parse(basicInfo.value.modelInfo)
pointInfo.value = modelInfo.value.pointInfo
console.log(modelInfo.value)
pointList.value = await getInstantPoint(instantId.value)
getChartsData()
})
function handleSubmitR() {
getChartsData()
}
async function getChartsData() {
setProps({
submitButtonOptions: {
loading: true,
},
})
loadingChart.value = true
console.log(getFieldsValue())
const instantForm = getFieldsValue()
historyList.value = await getInstantChart({ ...{ id: instantId.value }, ...instantForm })
echarts.connect('async')
loadingChart.value = false
setProps({
submitButtonOptions: {
loading: false,
},
})
}
const [registerTable] = useTable({
title: '测点列表',
size: 'small',
dataSource: pointList,
columns: detailColumns,
useSearchForm: false,
showTableSetting: true,
showIndexColumn: false,
actionColumn: {
width: 140,
title: t('common.action'),
dataIndex: 'action',
fixed: 'right',
},
})
function handleDetail(record) {
console.log(record)
router.push('/run/instant/detail')
}
function config(value) {
console.log(value)
}
</script>
<template>
<div>
<Card :loading="loadingBasic">
<Descriptions size="small" title="模型基本信息" bordered :column="{ xxl: 4, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 }">
<DescriptionsItem label="实例名称" :span="4">
{{ basicInfo.mpName }}
</DescriptionsItem>
<DescriptionsItem label="创建人">
{{ basicInfo.createName }}
</DescriptionsItem>
<DescriptionsItem label="创建时间">
{{ moment(basicInfo.createTime).format("YYYY-MM-DD HH:mm:ss") }}
</DescriptionsItem>
<DescriptionsItem label="最近修改人">
{{ basicInfo.updateName }}
</DescriptionsItem>
<DescriptionsItem label="最近修改时间">
{{ moment(basicInfo.updateTime).format("YYYY-MM-DD HH:mm:ss") }}
</DescriptionsItem>
<DescriptionsItem label="算法">
{{ basicInfo.algorithmShortname }}
</DescriptionsItem>
<DescriptionsItem label="训练采样间隔">
{{ modelInfo.sampling }}
</DescriptionsItem>
<DescriptionsItem label="参数个数">
{{ pointInfo.length }}
</DescriptionsItem>
<DescriptionsItem label="最小主元贡献率">
{{ modelInfo.rate }}
</DescriptionsItem>
<DescriptionsItem label="主元个数">
{{ modelInfo.principal }}
</DescriptionsItem>
<DescriptionsItem label="模型精度">
{{ modelInfo.precision }}
</DescriptionsItem>
</Descriptions>
</Card>
<Card>
<BasicTable @register="registerTable">
<template #detail="{ record }">
<a class="click-status" @click="handleDetail(record)">
{{ record.mpName }}
</a>
<!-- <SlidersOutlined class="click-status" /> -->
</template>
</BasicTable>
</Card>
<Card>
<BasicForm @register="registerForm" @submit="handleSubmitR">
<!-- 添加button的插槽 -->
<template #configButton="{ field }">
<a-button style="margin-left:20px" @click="config">
故障配置
</a-button>
</template>
</BasicForm>
</Card>
<Card :loading="loadingChart">
<div>
<div v-for="(item, index) in historyList" :key="index">
<div style="border:1px solid #ccc">
<HistoryLine :is-async="index !== 0" :title="item.title" :data="item.seriesData" :name="item.name" height="250px" />
</div>
</div>
</div>
</Card>
</div>
</template>
<style lang="less" scoped>
:deep(.ant-table-body){
height:100% !important;
max-height:100% !important
}
</style>

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

@ -0,0 +1,260 @@
<script lang="ts" setup>
import { Badge, Switch } from 'ant-design-vue'
import { onMounted, ref } from 'vue'
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'
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: 'Instant' })
const { createMessage } = useMessage()
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: '实例列表',
api: getInstantPage,
rowKey: 'id',
immediate: true,
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
showResetButton: false,
actionColOptions: {
span: 2,
},
},
useSearchForm: true,
showTableSetting: true,
showIndexColumn: false,
actionColumn: {
width: 240,
title: t('common.action'),
dataIndex: 'action',
fixed: 'right',
},
})
function handleDetail(record) {
console.log(record)
router.push(`/run/instant/detail?id=${record.id}`)
}
async function updateStatus(record) {
await updateInstant(record)
createMessage.success(t('common.saveSuccessText'))
console.log(record)
reload()
}
const isShow = ref<boolean>(false)
function handleCreate() {
openCreateModal(true, { isUpdate: false })
isShow.value = true
}
function handleEdit(record: Recordable) {
openUpdateModal(true, { record, isUpdate: true })
}
async function handleDelete(record: Recordable) {
await deleteRole(record.id)
createMessage.success(t('common.delSuccessText'))
reload()
}
const itemName = ref<string>()
const legendName = ref<string[]>()
function handleHistory(record: Recordable) {
itemName.value = (JSON.parse(record.instantInfo)).model_state
legendName.value = []
legendName.value.push(`${record.mpName}-${itemName.value}`)
openHistoryModal(true, { record })
}
interface countObj {
normal: number
outside: number
failure: number
update: number
stop: number
}
const countData = ref<countObj>()
onMounted(async () => {
countData.value = await getInstantCount()
console.log(countData.value)
getNow()
})
async function getTableData(type) {
const { getFieldsValue, setFieldsValue } = getForm()
await setFieldsValue({ runningLog: null, running: null, isUpdate: null })
if (type === 'normal') {
await setFieldsValue({ runningLog: '运行正常' })
console.log(getFieldsValue())
}
else if (type === 'outside') {
await setFieldsValue({ runningLog: '模式外运行' })
}
else if (type === 'stop') {
await setFieldsValue({ runningLog: '模型已停运' })
}
else if (type === 'failure') {
await setFieldsValue({ running: 0 })
}
else if (type === 'isUpdate') {
await setFieldsValue({ isUpdate: 1 })
}
else {
await setFieldsValue({ runningLog: null, running: null, isUpdate: null })
}
reload()
}
async function getNow() {
const params = getDataSource()
params.forEach((item: any) => {
const pointCode = (JSON.parse(item.instantInfo)).model_state
//
getExaNow(pointCode).then((result) => {
updateTableDataRecord(item.id, Object.assign(item, { pointSte: result }))
})
})
}
function handleWarnConfig(record: Recordable) {
router.push(`/run/warnConfig?id=${record.id}`)
}
</script>
<template>
<div>
<BasicTable @register="registerTable">
<template #detail="{ record }">
<a class="click-status" @click="handleDetail(record)">
{{ record.mpName }}
</a>
<!-- <SlidersOutlined class="click-status" /> -->
</template>
<!-- 统计量点击跳转历史曲线 -->
<template #history="{ record }">
<a @click="handleHistory(record)">
{{ record.pointSte }}
</a>
<!-- <SlidersOutlined class="click-status" /> -->
</template>
<template #toolbar>
<span class="runningStatus" @click="getTableData('all')">
全部</span>
<Badge
:class="countData?.normal === 0 ? 'runningStatus' : 'runningStatus alarm'" color="green" text="正常运行"
@click="getTableData('normal')"
/>
<Badge
:class="countData?.outside === 0 ? 'runningStatus' : 'runningStatus alarm'" color="#0B55A4" text="模式外运行"
@click="getTableData('outside')"
/>
<Badge
:class="countData?.failure === 0 ? 'runningStatus' : 'runningStatus alarm'" color="red" text="运行失败"
@click="getTableData('failure')"
/>
<Badge
:class="countData?.update === 0 ? 'runningStatus' : 'runningStatus alarm'" color="orange" text="版本更新"
@click="getTableData('isUpdate')"
/>
<Badge
:class="countData?.stop === 0 ? 'runningStatus' : 'runningStatus alarm'" color="black" text="模型停运"
@click="getTableData('stop')"
/>
<a-button v-auth="['run:instant:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate">
{{ t('action.create') }}
</a-button>
</template>
<template #runStatus="{ record }">
<div v-if="record.runningLog === '模式已停运'">
<span style="color:black">模式已停运</span>
</div>
<div v-else-if="record.running === '0'">
<span style="color:red">运行失败</span>
</div>
<div v-else-if="record.runningLog === '模式外运行'">
<span style="color:#0B55A4">模式外运行</span>
</div>
<div v-else-if="record.isUpdate === '1'">
<span style="color:orange">版本更新</span>
</div>
<div v-else>
<span style="color:green">正常运行</span>
</div>
</template>
<template #status="{ record }">
<Switch
v-model:checked="record.status" :checked-value="1" :un-checked-value="0" checked-children="开"
un-checked-children="关" @change="updateStatus(record)"
/>
</template>
<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) },
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'run:instant:update', onClick: handleEdit.bind(null, record) },
{
icon: IconEnum.DELETE,
danger: true,
label: t('action.delete'),
auth: 'run:instant:delete',
popConfirm: {
title: t('common.delMessage'),
placement: 'left',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</template>
</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>
<style lang="less" scoped>
:deep(.instant) {
font-weight: bold;
color: #0B55A4
}
:deep(.alarm .ant-badge-status-dot) {
animation: flash 1s linear infinite;
}
@keyframes flash {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.runningStatus {
cursor: pointer;
}
</style>

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

@ -0,0 +1,479 @@
import moment from 'moment'
import { left } from 'inquirer/lib/utils/readline'
import type { BasicColumn, FormSchema } from '@/components/Table'
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
import { getModelVersionList } from '@/api/alert/run/model/index'
export const columns: BasicColumn[] = [
{
title: '编号',
dataIndex: 'id',
width: 80,
fixed: 'left',
},
{
title: '实例状态',
dataIndex: 'status1',
width: 100,
slots: { customRender: 'runStatus' },
fixed: 'left',
},
{
title: '实例名称',
dataIndex: 'mpName',
width: 250,
className: 'instant',
slots: { customRender: 'detail' },
fixed: 'left',
},
{
title: '专业',
dataIndex: 'systemName',
width: 200,
},
{
title: '算法',
dataIndex: 'algorithmName',
width: 200,
},
{
title: '模式',
dataIndex: 'conditionName',
width: 200,
},
{
title: '原模型名称',
dataIndex: 'modelName',
width: 200,
},
{
title: '版本',
dataIndex: 'modelVersion',
width: 200,
},
{
title: '运行日志',
dataIndex: 'runningLog',
width: 200,
},
{
title: '计算组',
dataIndex: 'groupName',
width: 200,
},
{
title: '统计量',
dataIndex: 'pointSte',
width: 120,
slots: { customRender: 'history' },
fixed: 'left',
},
{
title: '投切',
dataIndex: 'status',
width: 100,
slots: { customRender: 'status' },
fixed: 'right',
},
// {
// title: '实时值',
// dataIndex: 'value',
// width: 90,
// className: 'value',
// slots: { customRender: 'value' },
// }
]
export const searchFormSchema: FormSchema[] = [
{
label: '模型实例名称',
field: 'mpName',
component: 'Input',
defaultValue: '',
required: true,
colProps: { span: 8 },
},
{
label: '状态1',
field: 'running',
component: 'Input',
show: false,
},
{
label: '状态2',
field: 'runningLog',
component: 'Input',
show: false,
},
{
label: '状态3',
field: 'isUpdate',
component: 'Input',
show: false,
},
]
export const formSchema: FormSchema[] = [
{
label: '测点编码',
field: 'ItemName',
required: true,
component: 'Input',
},
{
label: '测点描述',
field: 'Descriptor',
required: true,
component: 'Input',
},
{
label: '单位',
field: 'EngUnits',
required: true,
component: 'Input',
},
{
label: '组名',
field: 'GroupName',
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.COMMON_STATUS),
},
required: true,
},
{
label: '类型',
field: 'ItemType',
component: 'Select',
componentProps: {
options: [{ value: 1, label: 1 }, { value: 2, label: 2 }, { value: 3, label: 3 }, { value: 4, label: 4 }, { value: 5, label: 5 }],
},
required: true,
},
{
label: '自动保存',
field: 'AutoSave',
component: 'Select',
componentProps: {
options: [{ value: 1, label: '是' }, { value: 2, label: '否' }],
},
required: true,
},
{
label: '数据来源',
field: 'Source',
component: 'Input',
},
]
export const instantForm: FormSchema[] = [
{
label: '时间范围',
field: 'time',
show: true,
component: 'RangePicker',
defaultValue: [moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')],
componentProps: {
placeholder: ['开始时间', '结束时间'],
valueFormat: 'YYYY-MM-DD HH:mm:ss',
showTime: {
defaultValue: [moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')],
},
onChange: (e: any) => {
console.log(e)
},
},
},
{
label: '时间间隔',
field: 'interval',
component: 'Select',
defaultValue: 300,
componentProps: {
options: [{ value: 1, label: '1秒' }, { value: 10, label: '10秒' }, { value: 100, label: '100秒' }, { value: 300, label: '300秒' }],
},
required: true,
colProps: {
span: 3,
},
},
{
label: '',
field: '0',
component: 'Input',
slot: 'configButton',
colProps: {
span: 2,
},
},
{
label: '复盘',
field: 'fp',
component: 'RadioGroup',
defaultValue: 0,
componentProps: {
options: [
{
label: '是',
value: 1,
},
{
label: '否',
value: 0,
},
],
},
required: true,
},
]
export const searchFormSchemaModel: FormSchema[] = [
{
label: '模型实例名称',
field: 'mpName',
component: 'Input',
defaultValue: '',
required: true,
colProps: { span: 8 },
},
]
export const createInstantForm: FormSchema[] = [
{
label: '所用模型的id',
field: 'modelId',
component: 'Input',
required: true,
show: false,
colProps: {
span: 12,
},
},
{
label: '实例名称',
field: 'mpName',
component: 'Input',
required: true,
colProps: {
span: 12,
},
componentProps: {
placeholder: '请选择下方模型以生成实例',
},
rules: [{ required: true, message: '请选择下方模型以生成实例' }],
},
{
label: '运行周期',
field: 'intervalTime',
component: 'Input',
required: true,
defaultValue: 30,
colProps: {
span: 6,
},
},
{
label: '计算组',
field: 'calcGroup',
component: 'Select',
componentProps: {
options: [],
},
colProps: {
span: 6,
},
required: true,
},
{
label: '版本号',
field: 'modelVersionId',
component: 'Select',
componentProps: {
// api: getModelVersionList,
// labelField: 'version',
// valueField: 'id',
// params: {},
options: [],
},
colProps: {
span: 12,
},
required: true,
},
{
label: '是否存储',
field: 'hisSto',
component: 'RadioGroup',
defaultValue: '1',
componentProps: {
options: [
{
label: '是',
value: '1',
},
{
label: '否',
value: '0',
},
],
},
colProps: {
span: 6,
},
required: true,
},
]
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[] = [
{
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,
},
]

66
src/views/run/model/ModelTable.vue

@ -0,0 +1,66 @@
<script lang="ts" setup>
import { onMounted, reactive, ref, watch } from 'vue'
import { columns, searchFormSchema } from './model.data'
import { BasicTable, TableAction, useTable } from '@/components/Table'
import { getModelPage } from '@/api/alert/run/model'
import { IconEnum } from '@/enums/appEnum'
import { useI18n } from '@/hooks/web/useI18n'
defineOptions({ name: 'ModelTable' })
const emit = defineEmits(['success'])
const { t } = useI18n()
const [registerTable, { setSelectedRowKeys }] = useTable({
title: '模型列表',
api: getModelPage,
rowKey: 'id',
rowSelection: { type: 'radio', async onChange(selectedRowKeys, selectedRows) {
emit('success', selectedRowKeys, selectedRows)
} },
size: 'small',
immediate: true,
columns,
formConfig: {
labelWidth: 80,
schemas: searchFormSchema,
showResetButton: false,
actionColOptions: {
span: 2,
},
},
useSearchForm: true,
showTableSetting: true,
showIndexColumn: false,
})
onMounted(async () => {
})
// watch(
// () => props.selectedRowKeys,
// () => {
// state.selectedRowKeys = props.selectedRowKeys
// },
// )
</script>
<template>
<div>
<BasicTable @register="registerTable">
<template #pointNumber="{ record }">
{{ (JSON.parse(record.modelInfo)).pointInfo.length }}
</template>
<template #precision="{ record }">
{{ (JSON.parse(record.modelInfo)).precision }}
</template>
</BasicTable>
</div>
</template>
<style lang="less" scoped>
:deep(.ant-table-body){
height:100% !important;
max-height:100% !important
}
</style>

110
src/views/run/model/PointTable.vue

@ -0,0 +1,110 @@
<script lang="ts" setup>
import { defineExpose, onMounted, reactive, ref, watch } from 'vue'
import { autoCompleteProps } from 'ant-design-vue/es/auto-complete'
import PointModal from '../../exa/history/PointModal.vue'
import { columns } from './point.data'
import { BasicTable, TableAction, useTable } from '@/components/Table'
import { useI18n } from '@/hooks/web/useI18n'
import { IconEnum } from '@/enums/appEnum'
import { useModal } from '@/components/Modal'
defineOptions({ name: 'ModelTable' })
const props = defineProps({
data: {
type: Array<Recordable>,
default: () => [],
},
type: {
type: Boolean,
default: false,
},
})
const { t } = useI18n()
const updateIndex = ref<number>(0)
const [registerPointModal, { openModal: openPointModal }] = useModal()
function handlePoint(record) {
openPointModal(true, record)
console.log(record)
updateIndex.value = record.LAY_TABLE_INDEX
}
const [registerTable, { setColumns, getDataSource, updateTableDataRecord }] = useTable({
title: '测点列表',
maxHeight: 300,
dataSource: props.data,
size: 'small',
columns,
useSearchForm: false,
showTableSetting: false,
showIndexColumn: true,
actionColumn: {
width: 140,
title: t('common.action'),
dataIndex: 'action',
fixed: 'right',
},
})
//
onMounted(() => {
console.log(props.type)
if (props.type) {
console.log('改变列')
setColumns([...columns, {
title: '测点类型',
dataIndex: 'type',
width: 80,
slots: { customRender: 'type' },
}])
}
})
const source = ref<string>('run')
const rowSelectType = ref<string>('radio')
function updateTableData(selectedData) {
const item = getDataSource()[updateIndex.value]
item.PointId = selectedData[0].itemName
item.Description = selectedData[0].descriptor
item.Unit = selectedData[0].engUnits
updateTableDataRecord(updateIndex.value, item)
console.log(selectedData)
//
console.log('更新表格数据')
}
function getPointTableData() {
const tableData = getDataSource()
return tableData
}
// <!-- 使defineExposedemoRef.value访 -->
defineExpose({ getPointTableData })
</script>
<template>
<div>
<BasicTable @register="registerTable">
<template #type="{ record }">
{{ record.type ? '输入' : '输出' }}
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[{ icon: IconEnum.CHANGE, label: t('action.pointConfig'), auth: 'run:instant:update', onClick: handlePoint.bind(null, record) },
]"
/>
</template>
</template>
</BasicTable>
<PointModal :source="source" :row-select-type="rowSelectType" @register="registerPointModal" @success="updateTableData" />
</div>
</template>
<style lang="less" scoped>
:deep(.ant-table-body){
height:100% !important;
max-height:100% !important
}
</style>

55
src/views/run/model/model.data.ts

@ -0,0 +1,55 @@
import moment from 'moment'
import { left } from 'inquirer/lib/utils/readline'
import type { BasicColumn, FormSchema } from '@/components/Table'
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
export const columns: BasicColumn[] = [
{
title: '编号',
dataIndex: 'id',
width: 80,
fixed: 'left',
},
{
title: '机组',
dataIndex: 'unitName',
width: 100,
fixed: 'left',
},
{
title: '模型名称',
dataIndex: 'modelName',
width: 250,
fixed: 'left',
},
{
title: '算法',
dataIndex: 'algorithmName',
width: 200,
},
{
title: '测点个数',
dataIndex: 'pointNumber',
width: 200,
slots: { customRender: 'pointNumber' },
},
{
title: '模型精度',
dataIndex: 'precision',
width: 200,
slots: { customRender: 'precision' },
},
]
export const searchFormSchema: FormSchema[] = [
{
label: '模型名称',
field: 'modelName',
component: 'Input',
defaultValue: '',
colProps: { span: 6 },
},
]

34
src/views/run/model/point.data.ts

@ -0,0 +1,34 @@
import moment from 'moment'
import { left } from 'inquirer/lib/utils/readline'
import type { BasicColumn, FormSchema } from '@/components/Table'
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
export const columns: BasicColumn[] = [
{
title: '点号',
dataIndex: 'PointId',
width: 150,
},
{
title: '描述',
dataIndex: 'Description',
width: 200,
},
{
title: '单位',
dataIndex: 'Unit',
width: 80,
},
{
title: '所属模型',
dataIndex: 'modelName',
width: 150,
},
{
title: '模型描述',
dataIndex: 'modelDescirption',
width: 150,
},
]

4
src/views/system/role/index.vue

@ -72,8 +72,8 @@ async function handleDelete(record: Recordable) {
<template>
<div>
<!-- <DocAlert title="功能权限" url="https://doc.iocoder.cn/resource-permission" />
<DocAlert title="数据权限" url="https://doc.iocoder.cn/data-permission" /> -->
<DocAlert title="功能权限" url="https://doc.iocoder.cn/resource-permission" />
<DocAlert title="数据权限" url="https://doc.iocoder.cn/data-permission" />
<BasicTable @register="registerTable">
<template #toolbar>

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