wyj0522 1 ヶ月 前
コミット
d26ff7965f

+ 0 - 1
fdapfe-admin/pom.xml

@@ -56,7 +56,6 @@
             <groupId>com.cn.fdapfe</groupId>
             <artifactId>fdapfe-framework</artifactId>
         </dependency>
-
         <!-- 定时任务-->
         <dependency>
             <groupId>com.cn.fdapfe</groupId>

+ 84 - 21
fdapfe-admin/src/main/java/com/cn/fdapfe/biz/service/impl/ModelDataGenServiceImpl.java

@@ -1,10 +1,14 @@
 package com.cn.fdapfe.biz.service.impl;
 
 import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
 import com.cn.fdapfe.biz.domain.Data;
 import com.cn.fdapfe.biz.domain.FaultPhysicalModel;
 import com.cn.fdapfe.biz.mapper.FaultPhysicalModelMapper;
 import com.cn.fdapfe.biz.service.IDataService;
+import com.cn.fdapfe.common.core.domain.AjaxResult;
+import com.cn.fdapfe.common.utils.FileToJsonConverter;
+import com.cn.fdapfe.common.utils.file.FileToMultipartFile;
 import com.cn.fdapfe.common.utils.http.HttpClientUtils;
 import com.cn.fdapfe.web.controller.common.CommonController;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -20,6 +24,8 @@ import com.cn.fdapfe.biz.service.IModelDataGenService;
 import com.cn.fdapfe.common.utils.DateUtils;
 import com.cn.fdapfe.common.utils.SecurityUtils;
 import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
 import javax.annotation.Resource;
 import java.io.*;
 import java.net.HttpURLConnection;
@@ -48,10 +54,9 @@ public class ModelDataGenServiceImpl implements IModelDataGenService {
     private IDataService dataService;
     @Resource
     private FaultPhysicalModelMapper faultPhysicalModelMapper;
-
-
     @Resource
     private CommonController commonController;
+
     private static final Pattern FILE_PATH_PATTERN = Pattern.compile(
             // Windows路径(支持斜杠或反斜杠)
             "^([a-zA-Z]:(?:[/\\\\](?:[^/\\\\:*?\"<>|\r\n]+))*[/\\\\]?[^/\\\\:*?\"<>|\r\n]*)$|" +
@@ -106,32 +111,95 @@ public class ModelDataGenServiceImpl implements IModelDataGenService {
     @Override
     public int add(ModelDataGen po) throws IOException {
         FaultPhysicalModel model = faultPhysicalModelMapper.selectById(po.getModelId());
+
         ObjectMapper mapper = new ObjectMapper();
         LinkedHashMap[] array = mapper.readValue(po.getPostApiData(), LinkedHashMap[].class);
         for (LinkedHashMap item : array) {
-            Map map = processMap(item);
-            Map returnMap = HttpClientUtils.sendPostRequest(model.getModelPath(), map);
+            Data data = new Data();
+            if(model.getModelAttribution().equals("0")){
+                try {
+                    //启动模型开始生成
+                    startExe(item.get("exePath").toString());
+                    //判断是否进行加噪
+                    if(item.get("isNoise").toString().equals("true")){
+                        //如果加噪,根据模型id查询
+                        FaultPhysicalModel noiseModel = faultPhysicalModelMapper.selectById(item.get("noiseModel").toString());
+                        HashMap<String, Object> noiseMap = new HashMap<>();
+                        noiseMap.put("noiseType",item.get("noiseType").toString());
+                        noiseMap.put("noiseFilePath",item.get("outputPath").toString());
+                        //调用噪声算法进行加噪
+                        sendPostRequest(noiseModel.getModelPath(),JSON.toJSONString(noiseMap));
+                        //如果加噪声了数据类型就是噪声数据
+                        data.setType("3");
+                    }
+                    //没有加噪声了数据类型就是物理模型数据数据
+                    data.setType("0");
+                    //将文件进行备份存储
+                    FileToMultipartFile file = new FileToMultipartFile(item.get("outputPath").toString(), "file");
+                    AjaxResult ajaxResult = commonController.customUploadFile(file, "D:/modelData");
+                    data.setUrl(ajaxResult.get("url").toString());
+                    data.setName(po.getDataGenName());
+                    data.setFileName(ajaxResult.get("originalFilename").toString());
+                    data.setFileSize(ajaxResult.get("fileSize").toString());
+                    data.setFileSizeBytes(ajaxResult.get("fileSizeBytes").toString());
+                    data.setFileSuffix(ajaxResult.get("fileSuffix").toString());
+                    dataService.insertData(data);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }else if(model.getModelAttribution().equals("2")){
+                //直接调用噪声,手动上传的为实际数据
+                data.setType("1");
+                String key = processMap(item);
+                HashMap<String, Object> noiseMap = new HashMap<>();
+                noiseMap.put("noiseType",item.get("noiseType").toString());
+                noiseMap.put(key,item.get(key).toString());
+                FaultPhysicalModel noiseModel = faultPhysicalModelMapper.selectById(po.getModelId());
+                //调用噪声算法进行加噪
+                sendPostRequest(noiseModel.getModelPath(),JSON.toJSONString(noiseMap));
+                //将文件进行备份存储
+                FileToMultipartFile file = new FileToMultipartFile(item.get("outputPath").toString(), "file");
+                try {
+                    AjaxResult ajaxResult = commonController.customUploadFile(file, "D:/modelData");
+                    data.setUrl(ajaxResult.get("url").toString());
+                    data.setName(po.getDataGenName());
+                    data.setFileName(ajaxResult.get("originalFilename").toString());
+                    data.setFileSize(ajaxResult.get("fileSize").toString());
+                    data.setFileSizeBytes(ajaxResult.get("fileSizeBytes").toString());
+                    data.setFileSuffix(ajaxResult.get("fileSuffix").toString());
+                    dataService.insertData(data);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
         }
         return 1;
     }
+    public static void startExe(String exePath) throws IOException, InterruptedException {
+        ProcessBuilder processBuilder = new ProcessBuilder(exePath);
+        Process process = processBuilder.start();
+        int exitCode = process.waitFor();
+        logger.info("程序退出码: {}", exitCode);
+    }
+        public static void main(String[] args) throws IOException {
+            String filePath = "C:/Users/15138/Desktop/fea_all.mat"; // 替换为实际的文件路径
+            JSONArray jsonArray = FileToJsonConverter.convertFileToJsonArray(filePath);
+            System.out.println(jsonArray.toString());
+        }
 
-    private Map processMap(LinkedHashMap<String, Object> map) {
+    private String processMap(LinkedHashMap<String, Object> map) {
         for (Map.Entry<String, Object> entry : map.entrySet()) {
             String key = entry.getKey();
             Object value = entry.getValue();
+
             // 检查值是否为字符串且符合文件路径格式
-            if (value instanceof String) {
-                String filePath = (String) value;
-                boolean validFilePath = isValidFilePath(filePath);
-                if (validFilePath) {
-                    // 转换为File对象并更新map
-                    File file = new File(filePath);
-                    map.put(key, file);
-                    System.out.println("字段 '" + key + "' 已转换为File对象: " + file);
-                }
+            if (value instanceof String && isValidFilePath((String) value)) {
+                return key; // 找到路径参数,返回对应的key
             }
         }
-        return map;
+
+        // 没有找到符合条件的路径参数
+        throw new IllegalArgumentException("Map中未找到有效的文件路径参数");
     }
 
     /**
@@ -166,12 +234,7 @@ public class ModelDataGenServiceImpl implements IModelDataGenService {
         return ids.length == 1 ? mapper.deleteById(ids[0]) : mapper.deleteBatchIds(Arrays.asList(ids));
     }
 
-    public static void startExe(String exePath) throws IOException, InterruptedException {
-        ProcessBuilder processBuilder = new ProcessBuilder(exePath);
-        Process process = processBuilder.start();
-        int exitCode = process.waitFor();
-        logger.info("程序退出码: {}", exitCode);
-    }
+
 
     public static void writeToTxt(String filePath, String content) throws IOException {
         try (FileWriter writer = new FileWriter(filePath, false)) {

+ 7 - 1
fdapfe-admin/src/main/resources/mapper/model/FaultPhysicalModelMapper.xml

@@ -23,6 +23,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
 
     <select id="getOptions" resultMap="FaultPhysicalModelResult">
-        select * from biz_fault_model_t WHERE model_attribution=#{typs} order by create_time desc
+        select * from biz_fault_model_t
+        <where>
+            <if test="typs != null and typs != ''">
+                model_attribution = #{typs}
+            </if>
+        </where>
+        order by create_time desc
     </select>
 </mapper>

+ 13 - 1
fdapfe-common/pom.xml

@@ -14,7 +14,12 @@
     <description>
         common通用工具
     </description>
-
+    <repositories>
+        <repository>
+            <id>jcenter</id>
+            <url>https://jcenter.bintray.com/</url>
+        </repository>
+    </repositories>
     <dependencies>
 
         <!-- Spring框架基本的核心工具 -->
@@ -27,6 +32,13 @@
             <artifactId>opencsv</artifactId>
             <version>5.7.1</version>
         </dependency>
+        <!-- MATLAB MAT 文件解析库 -->
+        <!-- https://mvnrepository.com/artifact/org.tallison/jmatio -->
+        <dependency>
+            <groupId>org.tallison</groupId>
+            <artifactId>jmatio</artifactId>
+            <version>1.2</version>
+        </dependency>
         <!-- SpringWeb模块 -->
         <dependency>
             <groupId>org.springframework</groupId>

+ 127 - 0
fdapfe-common/src/main/java/com/cn/fdapfe/common/utils/FileToJsonConverter.java

@@ -0,0 +1,127 @@
+package com.cn.fdapfe.common.utils;
+
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.jmatio.io.MatFileReader;
+import com.jmatio.types.MLArray;
+import com.jmatio.types.MLDouble;
+import com.opencsv.exceptions.CsvValidationException;
+
+import com.opencsv.CSVReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class FileToJsonConverter {
+
+    public static JSONArray convertFileToJsonArray(String filePath) throws IOException {
+        if (filePath.endsWith(".csv")) {
+            return convertCsvToJsonArray(filePath);
+        } else if (filePath.endsWith(".mat")) {
+            return convertMatToJsonArray(filePath);
+        } else {
+            throw new IllegalArgumentException("Unsupported file format. Only .csv and .mat are supported.");
+        }
+    }
+
+    private static JSONArray convertCsvToJsonArray(String csvFilePath) throws IOException {
+        JSONArray jsonArray = new JSONArray();
+        try (CSVReader reader = new CSVReader(new FileReader(csvFilePath))) {
+            List<String> headerList = new ArrayList<>();
+            String[] line;
+            boolean isHeader = true;
+            while ((line = reader.readNext()) != null) {
+                if (isHeader) {
+                    for (String header : line) {
+                        headerList.add(header);
+                    }
+                    isHeader = false;
+                } else {
+                    JSONObject jsonObject = new JSONObject();
+                    for (int i = 0; i < line.length; i++) {
+                        jsonObject.put(headerList.get(i), line[i]);
+                    }
+                    jsonArray.add(jsonObject); // 使用add替代put
+                }
+            }
+        } catch (CsvValidationException e) {
+            throw new RuntimeException(e);
+        }
+        return jsonArray;
+    }
+
+    public static JSONArray convertMatToJsonArray(String matFilePath) throws IOException {
+        JSONArray jsonArray = new JSONArray();
+        try {
+            MatFileReader matFileReader = new MatFileReader(matFilePath);
+            Map<String, MLArray> content = matFileReader.getContent();
+
+            for (Map.Entry<String, MLArray> entry : content.entrySet()) {
+                MLArray mlArray = entry.getValue();
+                if (mlArray instanceof MLDouble) {
+                    MLDouble matrix = (MLDouble) mlArray;
+                    int[] dimensions = matrix.getDimensions();
+
+                    // 校验至少是二维矩阵
+                    if (dimensions.length < 2) {
+                        System.err.println("跳过低维数据: " + entry.getKey());
+                        continue;
+                    }
+
+                    // 获取各维度大小(MATLAB维度顺序:[行, 列, 页])
+                    int rows = dimensions[0];
+                    int cols = dimensions[1];
+                    int pages = (dimensions.length > 2) ? dimensions[2] : 1;
+
+                    // 获取矩阵数据(jmatio返回一维数组,按列优先存储)
+//                        double[] data = matrix.getArray();
+
+                    // 构建JSON结构
+                    for (int page = 0; page < pages; page++) {
+                        JSONObject pageObj = new JSONObject();
+                        pageObj.put("page", page + 1); // 页码从1开始
+
+                        JSONArray tableData = new JSONArray();
+                        for (int row = 0; row < rows; row++) {
+                            JSONObject rowObj = new JSONObject();
+                            for (int col = 0; col < cols; col++) {
+                                // 计算一维数组中的索引(考虑列优先存储)
+                                int index = row + col * rows + page * rows * cols;
+//                                rowObj.put("col_" + (col + 1), data[index]);
+                            }
+                            tableData.add(rowObj);
+                        }
+                        pageObj.put("data", tableData);
+                        jsonArray.add(pageObj);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new IOException("三维矩阵转换失败: " + matFilePath, e);
+        }
+        return jsonArray;
+    }
+
+
+    // 将二维数组转换为三维数组(处理jmatio的数据存储格式)
+    private static double[][][] convertTo3DArray(double[][] rawData, int rows, int cols, int pages) {
+        double[][][] data3D = new double[pages][cols][rows];
+        int elementsPerPage = rows * cols;
+
+        for (int page = 0; page < pages; page++) {
+            int startIdx = page * elementsPerPage;
+            for (int col = 0; col < cols; col++) {
+                System.arraycopy(
+                        rawData[col],
+                        startIdx,
+                        data3D[page][col],
+                        0,
+                        rows
+                );
+            }
+        }
+        return data3D;
+    }
+}

+ 85 - 0
fdapfe-common/src/main/java/com/cn/fdapfe/common/utils/file/FileToMultipartFile.java

@@ -0,0 +1,85 @@
+package com.cn.fdapfe.common.utils.file;
+
+import org.springframework.web.multipart.MultipartFile;
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class FileToMultipartFile implements MultipartFile {
+
+    private final File file;
+    private final String name;
+    private final String originalFilename;
+    private final String contentType;
+
+    public FileToMultipartFile(File file, String name, String originalFilename, String contentType) {
+        this.file = file;
+        this.name = name;
+        this.originalFilename = originalFilename;
+        this.contentType = contentType;
+    }
+
+    public FileToMultipartFile(String filePath, String name) throws IOException {
+        String contentType1;
+        this.file = new File(filePath);
+        this.name = name;
+        this.originalFilename = file.getName();
+
+        // 尝试确定内容类型
+        Path path = Paths.get(filePath);
+        contentType1 = Files.probeContentType(path);
+        if (contentType1 == null) {
+            contentType1 = "application/octet-stream";
+        }
+        this.contentType = contentType1;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getOriginalFilename() {
+        return originalFilename;
+    }
+
+    @Override
+    public String getContentType() {
+        return contentType;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return file == null || file.length() == 0;
+    }
+
+    @Override
+    public long getSize() {
+        return file.length();
+    }
+
+    @Override
+    public byte[] getBytes() throws IOException {
+        try (InputStream is = new FileInputStream(file)) {
+            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+            int nRead;
+            byte[] data = new byte[1024];
+            while ((nRead = is.read(data, 0, data.length)) != -1) {
+                buffer.write(data, 0, nRead);
+            }
+            return buffer.toByteArray();
+        }
+    }
+
+    @Override
+    public InputStream getInputStream() throws IOException {
+        return new FileInputStream(file);
+    }
+
+    @Override
+    public void transferTo(File dest) throws IOException, IllegalStateException {
+        Files.copy(file.toPath(), dest.toPath());
+    }
+}

+ 63 - 18
fdapfe-ui/src/views/dataGen/DynamicParameterForm.vue

@@ -66,14 +66,36 @@
             </template>
 
             <!-- 字符串类型 -->
-            <template v-else-if="param.paramType === 'string' || !param.paramType">
+            <template  v-else-if="param.paramType === 'string' || !param.paramType">
+              <el-input
+                size="small"
+                v-model="group.formData[param.paramName]"
+                :placeholder="param.paramDescription"
+              />
+            </template>
+            <template  v-else-if="param.paramType === 'txt' || !param.paramType">
+              <el-input
+                type="textarea"
+                size="small"
+                v-model="group.formData[param.paramName]"
+                :placeholder="param.paramDescription"
+              />
+            </template>
+            <template  v-else-if="param.paramType === 'json' || !param.paramType">
+              <el-input
+                type="textarea"
+                size="small"
+                v-model="group.formData[param.paramName]"
+                :placeholder="param.paramDescription"
+              />
+            </template>
+            <template v-else-if="param.paramType === 'txt' || !param.paramType">
               <el-input
                 size="small"
                 v-model="group.formData[param.paramName]"
                 :placeholder="param.paramDescription"
               />
             </template>
-
             <!-- 数字类型 -->
             <template v-else-if="param.paramType === 'number'">
               <el-input-number
@@ -87,7 +109,7 @@
             </template>
 
             <!-- 布尔类型 -->
-            <template v-else-if="param.paramType === 'boolean'">
+            <template v-else-if="param.paramType === 'Boolean'">
               <el-switch
                 v-model="group.formData[param.paramName]"
                 active-text="开启"
@@ -96,7 +118,23 @@
             </template>
 
             <!-- 下拉选择类型 -->
-            <template v-else-if="param.paramType === 'select'">
+            <template v-else-if="param.paramType === 'select'&&param.paramName==='noiseType'">
+              <el-select
+                size="small"
+                v-model="group.formData[param.paramName]"
+                :placeholder="param.paramDescription"
+                clearable
+              >
+                <el-option
+                  v-for="dict in dict.type.noise_type"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                />
+              </el-select>
+            </template>
+            <!-- 下拉选择类型 -->
+            <template v-else-if="param.paramType === 'select' && param.paramName==='noiseModel'">
               <el-select
                 size="small"
                 v-model="group.formData[param.paramName]"
@@ -104,10 +142,10 @@
                 clearable
               >
                 <el-option
-                  v-for="option in parseOptions(param.paramOptions)"
-                  :key="option.value"
-                  :label="option.label"
-                  :value="option.value"
+                  v-for="item in modelOptions"
+                  :key="item.modelId"
+                  :label="item.modelName"
+                  :value="item.modelId"
                 />
               </el-select>
             </template>
@@ -155,8 +193,11 @@
 </template>
 
 <script>
+import { getFaultPhysicalOptions } from "@/api/model/faultPhysical";
 export default {
+
   name: 'DynamicParamForm',
+  dicts: ["biz_model_type","noise_type"],
   props: {
     // 基础参数配置(必填)
     configData: {
@@ -164,6 +205,10 @@ export default {
       required: true,
       default: () => []
     },
+    modelTypedisbale:{
+      type:Boolean,
+      default:false
+    },
     // 初始参数组数据(可选)
     initialGroups: {
       type: Array,
@@ -172,12 +217,17 @@ export default {
   },
   data() {
     return {
+      disabledString:false,
       paramGroups: [], // 存储所有参数组
-      isSubmitting: false // 提交加载状态
+      isSubmitting: false, // 提交加载状态
+      modelOptions:[]
     };
   },
+
   mounted() {
     this.initParamGroups();
+    this.parseOptions('2')
+    console.log('type', this.modelTypedisbale);
   },
   methods: {
     // 初始化参数组
@@ -213,6 +263,7 @@ export default {
 
     // 新增参数组
     addParamGroup() {
+      this.disabledString=!this.modelTypedisbale;
       this.paramGroups.push({
         configData: this.configData,
         formData: this.configData.reduce((acc, param) => {
@@ -249,15 +300,9 @@ export default {
 
     // 解析下拉选项
     parseOptions(optionsStr) {
-      if (!optionsStr) return [];
-      try {
-        return JSON.parse(optionsStr);
-      } catch (e) {
-        return optionsStr.split(',').map(item => {
-          const [value, label] = item.split(':');
-          return { value: value.trim(), label: label?.trim() || value.trim() };
-        });
-      }
+      getFaultPhysicalOptions(optionsStr).then(resp => {
+        this.modelOptions=  resp.data || [];
+      });
     },
 
     // 提交所有表单

+ 6 - 4
fdapfe-ui/src/views/dataGen/form.vue

@@ -31,8 +31,8 @@
           </el-select>
         </el-form-item>
       </el-row>
-        <el-form-item v-if="formData.modelId" label="模型参数">
-            <dynamic-parameter-form  :config-data="initialData" @submit="handleSubmitDataList" />
+        <el-form-item v-if="formData.modelId && modelType" label="模型参数">
+            <dynamic-parameter-form :model-typedisbale="modelType==='0'" :config-data="initialData" @submit="handleSubmitDataList" />
         </el-form-item>
       <el-row>
         <el-form-item v-if="formData.modelType === '2'" label="数据生成名称" prop="dataGenName">
@@ -111,6 +111,7 @@ export default {
   data() {
     return {
       initialData:[],
+      modelType: null,
       modelDataParams: [], // 视图层显示的参数组数组
       dataOptions: [],
       faultPhysicalOptions: [],
@@ -170,7 +171,7 @@ export default {
       });
 
       // 加载模型选项
-      getFaultPhysicalOptions(0).then(resp => {
+      getFaultPhysicalOptions().then(resp => {
         this.faultPhysicalOptions = resp.data || [];
       });
     },
@@ -189,8 +190,9 @@ export default {
       //获取模型参数详情
       getFaultPhysical(modelId).then(rest => {
         this.initialData  = rest.data.configData;
+        this.modelType=rest.data.modelAttribution;
         this.formData.modelId = rest.data.modelId;
-        console.log('modelDataParams',this.initialData)
+        console.log('modelDataParams',rest.data.modelAttribution)
       });
     },
 

+ 191 - 0
fdapfe-ui/src/views/model/faultPhysical/configDataService.js

@@ -0,0 +1,191 @@
+// configDataService.js
+export const ConfigDataService = {
+  // 初始化配置数据
+  initConfigData() {
+    return [
+      {
+        createBy: null,
+        createTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        updateBy: null,
+        updateTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        remark: null,
+        paramId: this.generateUniqueId(),
+        modelId: "",
+        paramName: "inputPath",
+        paramChineseName: "输入文件地址",
+        paramType: "String",
+        paramSort: "1",
+        paramDefaultValue: "",
+        paramDescription: "",
+        isRequired: true
+      },
+      {
+        createBy: null,
+        createTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        updateBy: null,
+        updateTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        remark: null,
+        paramId: this.generateUniqueId(),
+        modelId: "",
+        paramName: "outputPath",
+        paramChineseName: "输出文件地址",
+        paramType: "String",
+        paramSort: "2",
+        paramDefaultValue: "",
+        paramDescription: "",
+        isRequired: true
+      },
+      {
+        createBy: null,
+        createTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        updateBy: null,
+        updateTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        remark: null,
+        paramId: this.generateUniqueId(),
+        modelId: "",
+        paramName: "exePath",
+        paramChineseName: "模型地址",
+        paramType: "String",
+        paramSort: "3",
+        paramDefaultValue: "",
+        paramDescription: "",
+        isRequired: true
+      },
+      {
+        createBy: null,
+        createTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        updateBy: null,
+        updateTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        remark: null,
+        paramId: this.generateUniqueId(),
+        modelId: "",
+        paramName: "modelData",
+        paramChineseName: "输入参数",
+        paramType: "txt",
+        paramSort: "4",
+        paramDefaultValue: "",
+        paramDescription: "",
+        isRequired: false
+      },
+      {
+        createBy: null,
+        createTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        updateBy: null,
+        updateTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        remark: null,
+        paramId: this.generateUniqueId(),
+        modelId: "",
+        paramName: "modelData",
+        paramChineseName: "输入参数",
+        paramType: "txt",
+        paramSort: "4",
+        paramDefaultValue: "",
+        paramDescription: "",
+        isRequired: false
+      },
+      {
+        createBy: null,
+        createTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        updateBy: null,
+        updateTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        remark: null,
+        paramId: this.generateUniqueId(),
+        modelId: "",
+        paramName: "modelData",
+        paramChineseName: "输入参数",
+        paramType: "txt",
+        paramSort: "4",
+        paramDefaultValue: "",
+        paramDescription: "",
+        isRequired: false
+      },
+      {
+        createBy: null,
+        createTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        updateBy: null,
+        updateTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        remark: null,
+        paramId: this.generateUniqueId(),
+        modelId: "",
+        paramName: "isNoise",
+        paramChineseName: "是否加噪",
+        paramType: "Boolean",
+        paramSort: "5",
+        paramDefaultValue: false,
+        paramDescription: "",
+        isRequired: false
+      },
+      {
+        createBy: null,
+        createTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        updateBy: null,
+        updateTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        remark: null,
+        paramId: this.generateUniqueId(),
+        modelId: "",
+        paramName: "noiseType",
+        paramChineseName: "噪声类型",
+        paramType: "select",
+        paramSort: "6",
+        paramDefaultValue: "",
+        paramDescription: "",
+        isRequired: false
+      },
+      {
+        createBy: null,
+        createTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        updateBy: null,
+        updateTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+        remark: null,
+        paramId: this.generateUniqueId(),
+        modelId: "",
+        paramName: "noiseModel",
+        paramChineseName: "噪声模型",
+        paramType: "select",
+        paramSort: "7",
+        paramDefaultValue: "",
+        paramDescription: "",
+        isRequired: false
+      }
+    ];
+  },
+
+  // 生成唯一ID
+  generateUniqueId() {
+    return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+      const r = Math.random() * 16 | 0;
+      const v = c === 'x' ? r : (r & 0x3 | 0x8);
+      return v.toString(16);
+    });
+  },
+
+  // 克隆配置数据
+  cloneConfigData(configData) {
+    if (!Array.isArray(configData)) {
+      return this.initConfigData();
+    }
+
+    return configData.map(item => ({
+      ...item,
+      paramId: this.generateUniqueId(),
+      createTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+      updateTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
+      createBy: null,
+      updateBy: null
+    }));
+  },
+
+  // 创建新的配置项
+  createNewConfigItem() {
+    return {
+      modelId: '',
+      paramName: '',
+      paramChineseName: '',
+      paramType: '',
+      paramSort: '',
+      paramDefaultValue: '',
+      paramDescription: '',
+      isRequired: false
+    };
+  }
+};

+ 42 - 22
fdapfe-ui/src/views/model/faultPhysical/form.vue

@@ -8,13 +8,13 @@
     @close="handleCancel"
   >
     <el-form ref="formData" :model="formData" :rules="rules" label-width="130px">
-      <el-form-item label="故障模型名称" prop="modelName">
-        <el-input v-model="formData.modelName" placeholder="请输入故障模型名称"/>
+      <el-form-item label="模型名称" prop="modelName">
+        <el-input v-model="formData.modelName" placeholder="请输入模型名称"/>
       </el-form-item>
       <el-form-item label="模型类型" prop="type">
         <el-select
           v-model="formData.modelType"
-          placeholder="请选择故障模型类型"
+          placeholder="请选择模型类型"
           clearable
         >
           <el-option
@@ -25,8 +25,8 @@
           />
         </el-select>
       </el-form-item>
-      <el-form-item  label="模型接口地址" prop="modelPath">
-        <el-input v-model="formData.modelPath" placeholder="请输入故障模型接口地址"/>
+      <el-form-item v-if="!disable"  label="模型接口地址" prop="modelPath">
+        <el-input v-model="formData.modelPath" placeholder="请输入模型接口地址"/>
       </el-form-item>
       <el-form-item label="备注" prop="remark">
         <el-input
@@ -44,17 +44,17 @@
         <el-table :data="formData.configData">
           <el-table-column prop="paramName" label="字段名称" min-width="60" header-align="center" align="center">
             <template slot-scope="scope">
-              <el-input v-model="scope.row.paramName" placeholder="字段名称"></el-input>
+              <el-input  v-model="scope.row.paramName" placeholder="字段名称"></el-input>
             </template>
           </el-table-column>
           <el-table-column prop="paramChineseName" label="中文名称" min-width="60" align="center">
             <template slot-scope="scope">
-              <el-input v-model="scope.row.paramChineseName" placeholder="中文名称"></el-input>
+              <el-input  v-model="scope.row.paramChineseName" placeholder="中文名称"></el-input>
             </template>
           </el-table-column>
           <el-table-column prop="paramType" label="参数类型" header-align="center" align="center">
             <template slot-scope="scope">
-              <el-select v-model="scope.row.paramType" placeholder="参数类型" >
+              <el-select  v-model="scope.row.paramType" placeholder="参数类型" >
                 <el-option
                   v-for="dict in dict.type.param_type"
                   :key="dict.value"
@@ -66,7 +66,15 @@
           </el-table-column>
           <el-table-column prop="paramDefaultValue" label="默认值" min-width="60" header-align="center" align="center">
             <template slot-scope="scope">
-              <el-input v-model="scope.row.paramDefaultValue" placeholder="默认值"></el-input>
+              <el-input  v-if="scope.row.paramType==='txt'" type="textarea" v-model="scope.row.paramDefaultValue" placeholder="默认值"></el-input>
+              <el-switch
+                v-else-if="scope.row.paramType==='Boolean'"
+                v-model="scope.row.paramDefaultValue"
+                active-color="#13ce66"
+                inactive-color="#ff4949">
+              </el-switch>
+              <el-input v-else v-model="scope.row.paramDefaultValue" placeholder="默认值"></el-input>
+
             </template>
           </el-table-column>
           <el-table-column prop="isRequired" label="是否必填" min-width="50" header-align="center" align="center">
@@ -105,6 +113,7 @@ import {
   updateFaultPhysical,
   getFaultPhysical
 } from "@/api/model/faultPhysical";
+import { ConfigDataService } from './configDataService.js';
 export default {
   props: {
     value: {
@@ -174,6 +183,9 @@ export default {
     modelAtrtibution() {
       return this.$route.query.modelAttribution;
     },
+    disable(){
+     return this.$route.query.modelAttribution==='0'
+    },
     title() {
       if (this.options === 'add'&& this.$route.query.modelAttribution==='0') {
         return '添加故障物理模型管理';
@@ -181,34 +193,42 @@ export default {
       if (this.options === 'add'&& this.$route.query.modelAttribution==='1') {
         return '添加诊断模型管理';
       }
+      if (this.options === 'add'&& this.$route.query.modelAttribution==='2') {
+        return '添加噪声模型管理';
+      }
       if (this.options === 'edit'&& this.$route.query.modelAttribution==='0') {
         return '编辑故障物理模型管理';
       }
       if (this.options === 'edit'&& this.$route.query.modelAttribution==='1') {
         return '编辑诊断模型管理';
       }
+      if (this.options === 'edit'&& this.$route.query.modelAttribution==='1') {
+        return '编辑噪声模型管理';
+      }
       if (this.options === 'info'&& this.$route.query.modelAttribution==='0') {
         return '查看故障物理模型详情';
       }
       if (this.options === 'info'&& this.$route.query.modelAttribution==='1') {
         return '查看诊断模型详情';
       }
+      if (this.options === 'info'&& this.$route.query.modelAttribution==='1') {
+        return '查看噪声模型详情';
+      }
+    }
+  },
+  created() {
+    if (this.options === 'add' && this.$route.query.modelAttribution === '0') {
+      // 克隆现有配置数据并添加到数组
+      const clonedData = ConfigDataService.initConfigData();
+      this.formData.configData = [...clonedData];
+      console.log('克隆后的配置数据:', clonedData);
     }
   },
   methods: {
-    openDialog(){
-      this.formData.configData.push(
-        {
-          modelId:'',
-          paramName:'',
-          paramChineseName:'',
-          paramType:'',
-          paramSort:'',
-          paramDefaultValue:'',
-          paramDescription:'',
-          isRequired:false
-        }
-      )
+    openDialog() {
+      console.log('当前配置数据:', this.formData.configData);
+        this.formData.configData.push(ConfigDataService.createNewConfigItem());
+        console.log('添加新配置项后:', this.formData.configData)
     },
     initData() {
       this.formData.modelAttribution= this.modelAtrtibution;

+ 4 - 4
fdapfe-ui/src/views/model/faultPhysical/index.vue

@@ -8,18 +8,18 @@
       v-show="showSearch"
       label-width="100px"
     >
-      <el-form-item label="故障模型名称" prop="name">
+      <el-form-item label="模型名称" prop="name">
         <el-input
           v-model="queryParams.modelName"
-          placeholder="请输入故障模型名称"
+          placeholder="请输入模型名称"
           clearable
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="故障模型类型" prop="type">
+      <el-form-item label="模型类型" prop="type">
         <el-select
           v-model="queryParams.modelType"
-          placeholder="请选择故障模型类型"
+          placeholder="请选择模型类型"
           clearable
         >
           <el-option