|
@@ -0,0 +1,369 @@
|
|
|
+<template>
|
|
|
+ <el-dialog
|
|
|
+ title="性能评估"
|
|
|
+ :visible.sync="dialogOpen"
|
|
|
+ width="1000px"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ append-to-body
|
|
|
+ @close="handleClose"
|
|
|
+ >
|
|
|
+ <!-- 任务未开始时显示表单 -->
|
|
|
+ <div>
|
|
|
+ <el-form ref="form" :model="formData" label-width="100px">
|
|
|
+ <el-form-item label="任务名称" prop="name">
|
|
|
+ <el-input v-model="formData.name" placeholder="请输入任务名称" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="诊断模型">
|
|
|
+ <el-select
|
|
|
+ v-model="formData.fdAlgorithmId"
|
|
|
+ placeholder="请选择诊断模型"
|
|
|
+ :disabled="isProcessing"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in faultOptions"
|
|
|
+ :key="item.modelId"
|
|
|
+ :label="item.modelName"
|
|
|
+ :value="item.modelId"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="噪声模型" prop="type">
|
|
|
+ <el-select
|
|
|
+ v-model="formData.noseModelId"
|
|
|
+ placeholder="请选择噪声模型"
|
|
|
+ @change="onModelChange"
|
|
|
+ :disabled="isProcessing"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in faultPhysicalOptions"
|
|
|
+ :key="item.modelId"
|
|
|
+ :label="item.modelName"
|
|
|
+ :value="item.modelId"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="参数普">
|
|
|
+ <dynamic-parameter-form
|
|
|
+ :limit="1"
|
|
|
+ :config-data="initialData"
|
|
|
+ @submit="handleSubmitDataList"
|
|
|
+ :disabled="isProcessing"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ @click="submitForm"
|
|
|
+ :loading="submitting"
|
|
|
+ :disabled="isProcessing"
|
|
|
+ >
|
|
|
+ 确 定
|
|
|
+ </el-button>
|
|
|
+ <el-button @click="handleClose" :disabled="isProcessing">
|
|
|
+ 取消
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getDataOptions } from "@/api/data/data";
|
|
|
+import { getFaultPhysical, getFaultPhysicalOptions } from '@/api/model/faultPhysical';
|
|
|
+import { addPerf, addPerf2index, cancelPerf } from '@/api/test/perf'
|
|
|
+import DynamicParameterForm from '@/views/dataGen/DynamicParameterForm.vue';
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "DdAlgorithmDetail",
|
|
|
+ components: { DynamicParameterForm },
|
|
|
+ dicts: ["biz_perf_eval_type"],
|
|
|
+ props: {
|
|
|
+ value: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ formData: {
|
|
|
+ name: '',
|
|
|
+ noseModelId: '',
|
|
|
+ noseParams: '',
|
|
|
+ diagModelId: '',
|
|
|
+ postApiData: null,
|
|
|
+ noseDataIds: '',
|
|
|
+ fdAlgorithmId: ''
|
|
|
+ },
|
|
|
+ dataOptions: [],
|
|
|
+ faultPhysicalOptions: [],
|
|
|
+ initialData: [],
|
|
|
+ modelType: null,
|
|
|
+ faultOptions: [],
|
|
|
+ dialogOpen: false,
|
|
|
+ isProcessing: false,
|
|
|
+ submitting: false,
|
|
|
+ taskId: null,
|
|
|
+ statusMessage: '准备开始...',
|
|
|
+ errorMessage: '',
|
|
|
+ websocket: null,
|
|
|
+ isWebSocketConnected: false,
|
|
|
+ reconnectTimer: null,
|
|
|
+ reconnectAttempts: 0,
|
|
|
+ maxReconnectAttempts: 10,
|
|
|
+ reconnectInterval: 3000, // 3秒后重连
|
|
|
+ wsUrl: "ws://127.0.0.1:8080/websocket/message", // WebSocket连接地址
|
|
|
+ receivedMessages: [] // 存储接收到的WebSocket消息
|
|
|
+ };
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ value(newVal) {
|
|
|
+ console.log('状态更新了', newVal);
|
|
|
+ this.dialogOpen = newVal;
|
|
|
+
|
|
|
+ // 关闭对话框时清理资源
|
|
|
+ if (!newVal && this.isProcessing) {
|
|
|
+ this.cancelTask();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.fetchDataOptions();
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ // 组件挂载后可以初始化WebSocket,但通常在需要时建立连接
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 获取数据选项
|
|
|
+ fetchDataOptions() {
|
|
|
+ getDataOptions().then((resp) => {
|
|
|
+ this.dataOptions = resp.data;
|
|
|
+ });
|
|
|
+
|
|
|
+ getFaultPhysicalOptions({ modelAttribution: 2 }).then((resp) => {
|
|
|
+ this.faultPhysicalOptions = resp.data;
|
|
|
+ });
|
|
|
+
|
|
|
+ // 诊断模型选项(类型1)
|
|
|
+ getFaultPhysicalOptions({ modelAttribution: 1 }).then(resp => {
|
|
|
+ this.faultOptions = resp.data || [];
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 建立WebSocket连接
|
|
|
+ connectWebSocket(taskId) {
|
|
|
+ if (this.websocket) {
|
|
|
+ this.closeWebSocket();
|
|
|
+ }
|
|
|
+
|
|
|
+ this.websocket = new WebSocket(`${this.wsUrl}`);
|
|
|
+ this.isWebSocketConnected = false;
|
|
|
+ this.reconnectAttempts = 0;
|
|
|
+
|
|
|
+ this.websocket.onopen = (event) => {
|
|
|
+ this.isWebSocketConnected = true;
|
|
|
+ this.reconnectAttempts = 0;
|
|
|
+ this.statusMessage = 'WebSocket连接已建立,正在接收任务进度...';
|
|
|
+ console.log('WebSocket连接成功', event);
|
|
|
+ };
|
|
|
+
|
|
|
+ this.websocket.onmessage = (event) => {
|
|
|
+ // 存储接收到的消息
|
|
|
+ this.receivedMessages.push(event.data);
|
|
|
+ // 更新状态消息
|
|
|
+ this.statusMessage = event.data;
|
|
|
+ // 返回消息给父组件
|
|
|
+ this.$emit('message', event.data);
|
|
|
+ // 任务结束时关闭对话框
|
|
|
+ if (event.data === '任务结束') {
|
|
|
+ this.closeWithCleanup();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ this.websocket.onerror = (error) => {
|
|
|
+ this.isWebSocketConnected = false;
|
|
|
+ this.statusMessage = 'WebSocket连接错误';
|
|
|
+ this.errorMessage = `WebSocket错误: ${error.message}`;
|
|
|
+ console.error('WebSocket错误', error);
|
|
|
+ this.tryToReconnect();
|
|
|
+ };
|
|
|
+
|
|
|
+ this.websocket.onclose = (event) => {
|
|
|
+ this.isWebSocketConnected = false;
|
|
|
+ };
|
|
|
+ },
|
|
|
+
|
|
|
+ // 尝试重连
|
|
|
+ tryToReconnect() {
|
|
|
+ if (this.reconnectTimer) {
|
|
|
+ clearTimeout(this.reconnectTimer);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.maxReconnectAttempts === 0 || this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
|
+ this.reconnectAttempts++;
|
|
|
+ this.reconnectTimer = setTimeout(() => {
|
|
|
+ this.connectWebSocket(this.taskId);
|
|
|
+ }, this.reconnectInterval);
|
|
|
+ this.statusMessage = `尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`;
|
|
|
+ } else {
|
|
|
+ this.statusMessage = '达到最大重连次数,停止重连';
|
|
|
+ this.errorMessage = 'WebSocket重连失败,达到最大重连次数';
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 关闭WebSocket连接
|
|
|
+ closeWebSocket() {
|
|
|
+ if (this.websocket) {
|
|
|
+ this.websocket.close();
|
|
|
+ this.websocket = null;
|
|
|
+ }
|
|
|
+ this.isWebSocketConnected = false;
|
|
|
+ if (this.reconnectTimer) {
|
|
|
+ clearTimeout(this.reconnectTimer);
|
|
|
+ this.reconnectTimer = null;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 提交表单
|
|
|
+ submitForm() {
|
|
|
+ // 表单验证
|
|
|
+ this.$refs.form.validate(valid => {
|
|
|
+ if (valid) {
|
|
|
+ this.submitting = true;
|
|
|
+ this.isProcessing = true;
|
|
|
+ this.errorMessage = '';
|
|
|
+ // 发送请求启动任务
|
|
|
+ this.statusMessage = '任务已启动,正在建立WebSocket连接...';
|
|
|
+ // 建立WebSocket连接以接收进度
|
|
|
+ this.connectWebSocket();
|
|
|
+ this.taskPromise = addPerf2index(this.formData).then((response) => {
|
|
|
+ return response;
|
|
|
+ }).catch(error => {
|
|
|
+ this.isProcessing = false;
|
|
|
+ this.errorMessage = error.response?.data?.message || '启动任务失败';
|
|
|
+ this.$message.error(this.errorMessage);
|
|
|
+ console.error(error);
|
|
|
+ }).finally(() => {
|
|
|
+ this.submitting = false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 处理动态参数提交
|
|
|
+ handleSubmitDataList(data) {
|
|
|
+ console.log('data', data);
|
|
|
+ this.formData.postApiData = JSON.stringify(data);
|
|
|
+ this.formData.noseParams = JSON.stringify(data);
|
|
|
+ this.formData.noseDataIds = data.file_path;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 模型变更处理
|
|
|
+ onModelChange(modelId) {
|
|
|
+ getFaultPhysical(modelId).then(rest => {
|
|
|
+ this.initialData = rest.data.configData;
|
|
|
+ this.modelType = rest.data.modelAttribution;
|
|
|
+ this.formData.modelId = rest.data.modelId;
|
|
|
+ console.log('modelDataParams', rest.data.modelAttribution);
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 取消任务
|
|
|
+ cancelTask() {
|
|
|
+ if (this.taskId) {
|
|
|
+ // 调用取消任务API
|
|
|
+ cancelPerf(this.taskId).then(() => {
|
|
|
+ this.$message.info('已请求取消任务');
|
|
|
+ }).catch(error => {
|
|
|
+ this.$message.error('取消任务请求失败');
|
|
|
+ console.error(error);
|
|
|
+ }).finally(() => {
|
|
|
+ this.closeWithCleanup();
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.closeWithCleanup();
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 关闭对话框并清理资源
|
|
|
+ closeWithCleanup() {
|
|
|
+ this.isProcessing = false;
|
|
|
+ this.submitting = false;
|
|
|
+ this.statusMessage = '准备开始...';
|
|
|
+ this.errorMessage = '';
|
|
|
+
|
|
|
+ // 发送所有消息给父组件
|
|
|
+ this.$emit('allMessages', this.receivedMessages);
|
|
|
+
|
|
|
+ // 关闭WebSocket连接
|
|
|
+ this.closeWebSocket();
|
|
|
+
|
|
|
+ // 重置表单
|
|
|
+ this.formData = {
|
|
|
+ name: '',
|
|
|
+ noseModelId: '',
|
|
|
+ noseParams: '',
|
|
|
+ diagModelId: '',
|
|
|
+ postApiData: null,
|
|
|
+ noseDataIds: '',
|
|
|
+ fdAlgorithmId: ''
|
|
|
+ };
|
|
|
+
|
|
|
+ // 清空消息列表
|
|
|
+ this.receivedMessages = [];
|
|
|
+
|
|
|
+ // 关闭对话框
|
|
|
+ this.dialogOpen = false;
|
|
|
+ this.$emit('callback', false);
|
|
|
+ },
|
|
|
+
|
|
|
+ // 对话框关闭处理
|
|
|
+ handleClose() {
|
|
|
+ if (this.isProcessing) {
|
|
|
+ this.$confirm('任务正在处理中,确定要取消吗?', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
+ }).then(() => {
|
|
|
+ this.cancelTask();
|
|
|
+ }).catch(() => {
|
|
|
+ // 取消关闭
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.closeWithCleanup();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ // 组件销毁时清理资源
|
|
|
+ this.closeWebSocket();
|
|
|
+ if (this.reconnectTimer) {
|
|
|
+ clearTimeout(this.reconnectTimer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.processing-container {
|
|
|
+ padding: 20px;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.status-message {
|
|
|
+ margin-bottom: 20px;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #666;
|
|
|
+}
|
|
|
+
|
|
|
+.error-message {
|
|
|
+ margin-bottom: 20px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #f56c6c;
|
|
|
+}
|
|
|
+
|
|
|
+.footer-actions {
|
|
|
+ text-align: center;
|
|
|
+ margin-top: 30px;
|
|
|
+}
|
|
|
+</style>
|