Browse Source
- Updated ModelItem interface to include createTime property. - Refactored index.vue to improve code readability and structure. - Enhanced Step1.vue to handle form submission and validation. - Simplified Step2.vue and Step3.vue for better data handling and user experience. - Removed Step5.vue as it was redundant. - Introduced new API models and methods for better data management. - Updated form schemas for steps to reflect new requirements and improve validation logic. - Improved styling and layout for better user interface consistency.pull/22/head
18 changed files with 8283 additions and 9213 deletions
File diff suppressed because it is too large
@ -0,0 +1,38 @@ |
|||
export interface ModelCardItem { |
|||
id: number |
|||
name: string |
|||
status: number |
|||
algorithm: string |
|||
creator: string |
|||
createTime: string |
|||
} |
|||
|
|||
interface MovingWindows { |
|||
windowLength: number |
|||
samplingInterval: number |
|||
movingSpeed: number |
|||
} |
|||
|
|||
export interface ModelInfo { |
|||
id: number |
|||
btmState: string |
|||
unitID: string |
|||
createName: string |
|||
createTime: string |
|||
modelName: string |
|||
movingWindows: MovingWindows |
|||
steadyPoint: any[] |
|||
targetParameter: any |
|||
relationParameter: any[] |
|||
boundaryParameter: any[] |
|||
} |
|||
|
|||
export interface ModelQueryParams { |
|||
unitId: number |
|||
typeId: number |
|||
systemId: number |
|||
name?: string | null |
|||
status?: number | null |
|||
visible?: number | null |
|||
trash?: number | null |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
import { BasicFetchResult } from '/@/api/model/baseModel'; |
|||
|
|||
export interface OptionsItem { |
|||
id: number; |
|||
name: string; |
|||
} |
|||
|
|||
export interface AllOptionsItem { |
|||
units: OptionsItem[]; |
|||
types: OptionsItem[]; |
|||
systems: OptionsItem[]; |
|||
} |
|||
|
|||
export interface DemoOptionsItem { |
|||
name: string; |
|||
id: string; |
|||
} |
|||
|
|||
export interface selectParams { |
|||
id: number | string; |
|||
} |
|||
|
|||
export interface systemSelectParams { |
|||
unitId: number | null; |
|||
typeId: number | null; |
|||
} |
|||
|
|||
/** |
|||
* @description: Request list return value |
|||
*/ |
|||
export type DemoOptionsGetResultModel = BasicFetchResult<DemoOptionsItem>; |
|||
@ -0,0 +1,33 @@ |
|||
import type { ModelCardItem, ModelInfo, ModelQueryParams } from './model/models' |
|||
import { defHttp } from '@/utils/http/axios' |
|||
|
|||
enum Api { |
|||
MODEL_CARD_LIST = '/alert/model/card/list', |
|||
MODEL_INFO = '/alert/model/info/', |
|||
MODEL_SAVE = '/alert/model/', |
|||
MODEL_DATA = '/alert/model/data/', |
|||
CALCULATE_BACK = '/alert/model/data/calculate/', |
|||
OPTIMISTIC = '/alert/optimistic', |
|||
} |
|||
export function modelCardListApi(params?: ModelQueryParams) { |
|||
return defHttp.get<ModelCardItem[]>({ url: Api.MODEL_CARD_LIST, params }) |
|||
} |
|||
|
|||
export const modelInfoApi = (id: any) => defHttp.get<ModelInfo>({ url: Api.MODEL_INFO + id }) |
|||
|
|||
export function updateModelInfo(params: any) { |
|||
return defHttp.patch<boolean>({ url: Api.MODEL_INFO, params }) |
|||
} |
|||
|
|||
export function modelSaveApi(params?: any) { |
|||
return defHttp.post<number>({ url: Api.MODEL_SAVE, data: params }) |
|||
} |
|||
|
|||
export function modelDataApi(id: any, params: any) { |
|||
return defHttp.get<any>({ url: Api.MODEL_DATA + id, params }) |
|||
} |
|||
|
|||
export function calculateBackApi(id: any, params: any) { |
|||
return defHttp.post<boolean>({ url: Api.CALCULATE_BACK + id, params }) |
|||
} |
|||
export const getOptimisticApi = (params: any) => defHttp.get<any>({ url: Api.OPTIMISTIC, params }) |
|||
@ -0,0 +1,42 @@ |
|||
import type { |
|||
AllOptionsItem, |
|||
DemoOptionsItem, |
|||
OptionsItem, |
|||
selectParams, |
|||
systemSelectParams, |
|||
} from './model/optionsModel' |
|||
import { defHttp } from '@/utils/http/axios' |
|||
|
|||
enum Api { |
|||
LIST = '/alert/select/list', |
|||
UNIT_LIST = '/alert/select/unit/options', |
|||
SYSTEM_LIST = '/alert/select/system/options', |
|||
POINT_LIST = '/alert/select/point/options', |
|||
} |
|||
|
|||
export const optionListApi = () => defHttp.get<AllOptionsItem>({ url: Api.LIST }) |
|||
|
|||
/** |
|||
* @description: 获取机组选项 |
|||
*/ |
|||
export function unitListApi(params?: selectParams) { |
|||
return defHttp.get<DemoOptionsItem[]>({ url: Api.UNIT_LIST, params }) |
|||
} |
|||
|
|||
/** |
|||
* @description: 获取系统机组 |
|||
*/ |
|||
export function systemListApi(params?: selectParams) { |
|||
return defHttp.get<DemoOptionsItem[]>({ url: Api.UNIT_LIST, params }) |
|||
} |
|||
|
|||
/** |
|||
* @description: 获取子系统选项 |
|||
*/ |
|||
export function subSystemListApi(params?: systemSelectParams) { |
|||
return defHttp.get<OptionsItem[]>({ url: Api.SYSTEM_LIST, params }) |
|||
} |
|||
|
|||
export function pointListApi(params?: string) { |
|||
return defHttp.get<OptionsItem[]>({ url: Api.POINT_LIST, params }) |
|||
} |
|||
@ -1,15 +1,16 @@ |
|||
import { CSSProperties } from 'vue'; |
|||
import type { CSSProperties } from 'vue' |
|||
|
|||
export interface ModelItem { |
|||
id: number; |
|||
icon: string; |
|||
title: string; |
|||
value: number; |
|||
total: number; |
|||
color: string; |
|||
status: string; |
|||
creator: string; |
|||
description: string; |
|||
headStyle: CSSProperties; |
|||
bodyStyle: CSSProperties; |
|||
id: number |
|||
icon: string |
|||
title: string |
|||
value: number |
|||
total: number |
|||
color: string |
|||
status: string |
|||
creator: string |
|||
createTime: string |
|||
description: string |
|||
headStyle: CSSProperties |
|||
bodyStyle: CSSProperties |
|||
} |
|||
|
|||
@ -1,45 +1,46 @@ |
|||
<template> |
|||
<PageWrapper contentFullHeight> |
|||
<a-card> |
|||
<UnitSelect @option-selected="handleOptionSelected" /> |
|||
<ModelCard :loading="loading" :systemId="systemId" :selectData="selectData" class="enter-y" /> |
|||
</a-card> |
|||
</PageWrapper> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { defineComponent, ref } from 'vue'; |
|||
import { PageWrapper } from '/@/components/Page'; |
|||
import ModelCard from './ModelCard.vue'; |
|||
import UnitSelect from './UnitSelect.vue'; |
|||
import { Card } from 'ant-design-vue'; |
|||
import { defineComponent, ref } from 'vue' |
|||
import { Card } from 'ant-design-vue' |
|||
import ModelCard from './ModelCard.vue' |
|||
import UnitSelect from './UnitSelect.vue' |
|||
import { PageWrapper } from '@/components/Page' |
|||
|
|||
const loading = ref(true); |
|||
const selectData = ref(null); |
|||
const systemId = ref(null); |
|||
const loading = ref(true) |
|||
const selectData = ref(null) |
|||
const systemId = ref(null) |
|||
|
|||
const handleOptionSelected = (values) => { |
|||
selectData.value = values; |
|||
systemId.value = values['system']; |
|||
}; |
|||
function handleOptionSelected(values) { |
|||
selectData.value = values |
|||
systemId.value = values.system |
|||
} |
|||
|
|||
setTimeout(() => { |
|||
loading.value = false; |
|||
}, 1500); |
|||
setTimeout(() => { |
|||
loading.value = false |
|||
}, 1500) |
|||
|
|||
export default defineComponent({ |
|||
components: { |
|||
PageWrapper, |
|||
ModelCard, |
|||
UnitSelect, |
|||
ACard: Card, |
|||
}, |
|||
setup() { |
|||
return { |
|||
loading, |
|||
handleOptionSelected, |
|||
selectData, |
|||
systemId, |
|||
}; |
|||
}, |
|||
}); |
|||
export default defineComponent({ |
|||
components: { |
|||
ModelCard, |
|||
UnitSelect, |
|||
ACard: Card, |
|||
PageWrapper, |
|||
}, |
|||
setup() { |
|||
return { |
|||
loading, |
|||
handleOptionSelected, |
|||
selectData, |
|||
systemId, |
|||
} |
|||
}, |
|||
}) |
|||
</script> |
|||
|
|||
<template> |
|||
<PageWrapper content-full-height> |
|||
<a-card> |
|||
<UnitSelect @option-selected="handleOptionSelected" /> |
|||
<ModelCard :loading="loading" :system-id="systemId" :select-data="selectData" class="enter-y" /> |
|||
</a-card> |
|||
</PageWrapper> |
|||
</template> |
|||
|
|||
@ -1,190 +1,78 @@ |
|||
<template> |
|||
<div class="step4"> |
|||
<a-alert message="选择系统测点作为模型输出。" show-icon /> |
|||
<a-descriptions :column="1" class="mt-5"> |
|||
<a-descriptions-item label="模型名称"> 测试模型 </a-descriptions-item> |
|||
<a-descriptions-item label="目标参数名称"> 送风机电流 </a-descriptions-item> |
|||
<a-descriptions-item label="滑动窗速度"> 600 </a-descriptions-item> |
|||
<a-descriptions-item label="滑动窗长度"> 120 </a-descriptions-item> |
|||
<a-descriptions-item label="取样间隔"> 30 </a-descriptions-item> |
|||
</a-descriptions> |
|||
<a-divider /> |
|||
<BasicForm @register="register"> |
|||
<template #remoteSearch="{ model, field }"> |
|||
<ApiSelect |
|||
:api="pointListApi" |
|||
showSearch |
|||
v-model:value="model[field]" |
|||
:filterOption="false" |
|||
resultField="list" |
|||
labelField="name" |
|||
valueField="id" |
|||
:params="searchParams" |
|||
@search="onSearch" |
|||
/> |
|||
</template> |
|||
<template #add="{ field }"> |
|||
<Button v-if="Number(field) === 0" @click="add">+</Button> |
|||
<Button v-if="field > 0" @click="del(field)">-</Button> |
|||
</template></BasicForm |
|||
> |
|||
</div> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { defineComponent, ref, computed, unref, PropType, toRaw } from 'vue'; |
|||
import { BasicForm, useForm, ApiSelect } from '/@/components/Form'; |
|||
import { step4Schemas } from './data'; |
|||
import { Alert, Divider, Descriptions } from 'ant-design-vue'; |
|||
import { Button } from '/@/components/Button'; |
|||
import { pointListApi } from '/@/api/benchmark/select'; |
|||
import { modelSaveApi } from '/@/api/benchmark/models'; |
|||
import { type Recordable } from '@vben/types'; |
|||
import { useDebounceFn } from '@vueuse/core'; |
|||
import { defineComponent } from 'vue' |
|||
import { Descriptions, Result } from 'ant-design-vue' |
|||
import { useGo } from '@/hooks/web/usePage' |
|||
|
|||
export default defineComponent({ |
|||
components: { |
|||
Button, |
|||
BasicForm, |
|||
ApiSelect, |
|||
[Alert.name]: Alert, |
|||
[Divider.name]: Divider, |
|||
[Descriptions.name]: Descriptions, |
|||
[Descriptions.Item.name]: Descriptions.Item, |
|||
export default defineComponent({ |
|||
components: { |
|||
[Result.name]: Result, |
|||
[Descriptions.name]: Descriptions, |
|||
[Descriptions.Item.name]: Descriptions.Item, |
|||
}, |
|||
props: { |
|||
modelId: { |
|||
type: Number, |
|||
}, |
|||
props: { |
|||
beforeData: { |
|||
type: Object as PropType<Record<string, any> | null | undefined>, |
|||
}, |
|||
systemId: { |
|||
type: Number, |
|||
}, |
|||
emits: ['redo'], |
|||
setup(props, { emit }) { |
|||
const go = useGo() |
|||
const goTrain = () => { |
|||
go(`/model/train/${props.modelId}`) |
|||
} |
|||
return { |
|||
redo: () => { |
|||
emit('redo') |
|||
}, |
|||
}, |
|||
emits: ['next', 'prev'], |
|||
setup(props, { emit }) { |
|||
const [register, { appendSchemaByField, removeSchemaByField, validate, setProps }] = useForm({ |
|||
labelWidth: 100, |
|||
schemas: step4Schemas, |
|||
actionColOptions: { |
|||
span: 14, |
|||
}, |
|||
resetButtonOptions: { |
|||
text: '上一步', |
|||
}, |
|||
submitButtonOptions: { |
|||
text: '创建模型', |
|||
}, |
|||
resetFunc: customResetFunc, |
|||
submitFunc: customSubmitFunc, |
|||
}); |
|||
const n = ref(1); |
|||
|
|||
function add() { |
|||
appendSchemaByField( |
|||
[ |
|||
{ |
|||
field: `point${n.value}`, |
|||
component: 'Input', |
|||
label: '边界参数' + n.value, |
|||
required: true, |
|||
slot: 'remoteSearch', |
|||
colProps: { |
|||
span: 16, |
|||
}, |
|||
}, |
|||
{ |
|||
field: `${n.value}`, |
|||
component: 'Input', |
|||
label: ' ', |
|||
slot: 'add', |
|||
colProps: { |
|||
span: 2, |
|||
}, |
|||
}, |
|||
], |
|||
'', |
|||
); |
|||
n.value++; |
|||
} |
|||
|
|||
function del(field) { |
|||
removeSchemaByField([`point${field}`, `${field}`]); |
|||
n.value--; |
|||
} |
|||
|
|||
async function customResetFunc() { |
|||
emit('prev'); |
|||
} |
|||
|
|||
async function customSubmitFunc() { |
|||
try { |
|||
const values = await validate(); |
|||
const relationParameter = []; |
|||
for (const key in values) { |
|||
if (key.startsWith('point')) { |
|||
const point = values[key].split('|'); |
|||
const p = { |
|||
description: point[0], |
|||
targetPoint: point[1], |
|||
unit: point[2], |
|||
upperlimit: point[3], |
|||
lowerlimit: point[4], |
|||
}; |
|||
relationParameter.push(p); |
|||
} |
|||
} |
|||
const systemId = props.systemId; |
|||
const modelInfo = toRaw(props.beforeData); |
|||
modelInfo['relationParameter'] = relationParameter; |
|||
console.log(modelInfo); |
|||
const model = { |
|||
systemId: systemId, |
|||
modelInfo: modelInfo, |
|||
}; |
|||
const modelId = await modelSaveApi(model); |
|||
setProps({ |
|||
submitButtonOptions: { |
|||
loading: true, |
|||
}, |
|||
}); |
|||
setTimeout(() => { |
|||
setProps({ |
|||
submitButtonOptions: { |
|||
loading: false, |
|||
}, |
|||
}); |
|||
emit('next', modelId); |
|||
}, 1500); |
|||
} catch (error) { |
|||
console.error(error); |
|||
} |
|||
} |
|||
|
|||
const keyword = ref<string>(''); |
|||
const searchParams = computed<Recordable>(() => { |
|||
return { keyword: unref(keyword) }; |
|||
}); |
|||
goTrain, |
|||
} |
|||
}, |
|||
}) |
|||
</script> |
|||
|
|||
function onSearch(value: string) { |
|||
keyword.value = value; |
|||
} |
|||
<template> |
|||
<div class="step4"> |
|||
<a-result status="success" title="新建成功" sub-title="可查看模型进行编辑"> |
|||
<template #extra> |
|||
<a-button type="primary" @click="redo"> |
|||
再建一个 |
|||
</a-button> |
|||
<a-button @click="goTrain"> |
|||
查看模型 |
|||
</a-button> |
|||
</template> |
|||
</a-result> |
|||
<div class="desc-wrap"> |
|||
<a-descriptions :column="1" class="mt-5"> |
|||
<a-descriptions-item label="模型名称"> |
|||
测试模型 |
|||
</a-descriptions-item> |
|||
<a-descriptions-item label="目标参数名称"> |
|||
送风机电流 |
|||
</a-descriptions-item> |
|||
<a-descriptions-item label="滑动窗速度"> |
|||
600 |
|||
</a-descriptions-item> |
|||
<a-descriptions-item label="滑动窗长度"> |
|||
120 |
|||
</a-descriptions-item> |
|||
<a-descriptions-item label="取样间隔"> |
|||
30 |
|||
</a-descriptions-item> |
|||
</a-descriptions> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
return { |
|||
register, |
|||
del, |
|||
add, |
|||
onSearch: useDebounceFn(onSearch, 300), |
|||
searchParams, |
|||
pointListApi, |
|||
handleReset: () => { |
|||
keyword.value = ''; |
|||
}, |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
<style lang="less" scoped> |
|||
.step4 { |
|||
width: 450px; |
|||
width: 600px; |
|||
margin: 0 auto; |
|||
} |
|||
|
|||
.desc-wrap { |
|||
padding: 24px 40px; |
|||
margin-top: 24px; |
|||
background-color: @background-color-light; |
|||
} |
|||
</style> |
|||
|
|||
@ -1,62 +0,0 @@ |
|||
<template> |
|||
<div class="step5"> |
|||
<a-result status="success" title="新建成功" sub-title="可查看模型进行编辑"> |
|||
<template #extra> |
|||
<a-button type="primary" @click="redo"> 再建一个 </a-button> |
|||
<a-button @click="goTrain"> 查看模型 </a-button> |
|||
</template> |
|||
</a-result> |
|||
<div class="desc-wrap"> |
|||
<a-descriptions :column="1" class="mt-5"> |
|||
<a-descriptions-item label="模型名称"> 测试模型 </a-descriptions-item> |
|||
<a-descriptions-item label="目标参数名称"> 送风机电流 </a-descriptions-item> |
|||
<a-descriptions-item label="滑动窗速度"> 600 </a-descriptions-item> |
|||
<a-descriptions-item label="滑动窗长度"> 120 </a-descriptions-item> |
|||
<a-descriptions-item label="取样间隔"> 30 </a-descriptions-item> |
|||
</a-descriptions> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { defineComponent } from 'vue'; |
|||
import { Result, Descriptions } from 'ant-design-vue'; |
|||
import { useGo } from '/@/hooks/web/usePage'; |
|||
|
|||
export default defineComponent({ |
|||
components: { |
|||
[Result.name]: Result, |
|||
[Descriptions.name]: Descriptions, |
|||
[Descriptions.Item.name]: Descriptions.Item, |
|||
}, |
|||
props: { |
|||
modelId: { |
|||
type: Number, |
|||
}, |
|||
}, |
|||
emits: ['redo'], |
|||
setup(props, { emit }) { |
|||
const go = useGo(); |
|||
const goTrain = () => { |
|||
go(`/model/train/${props.modelId}`); |
|||
}; |
|||
return { |
|||
redo: () => { |
|||
emit('redo'); |
|||
}, |
|||
goTrain, |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
<style lang="less" scoped> |
|||
.step5 { |
|||
width: 600px; |
|||
margin: 0 auto; |
|||
} |
|||
|
|||
.desc-wrap { |
|||
margin-top: 24px; |
|||
padding: 24px 40px; |
|||
background-color: @background-color-light; |
|||
} |
|||
</style> |
|||
Loading…
Reference in new issue