huangxingxing 3 mēneši atpakaļ
vecāks
revīzija
cdabb52f75

+ 4 - 4
src/main/java/com/miniframe/bisiness/es/ES0002Service.java

@@ -49,10 +49,10 @@ public class ES0002Service extends ES0002BaseModel implements ExecProcessFlow {
 			pdao.insert(p);
 			//创建文件路径
 			XIFileUtils.mkdir(XIFileUtils.getRootPathStr());
-			XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/"+p.getPid());
-			XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/"+p.getPid()+"/Calculate");
-			XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/"+p.getPid()+"/Calculate/Geometry");//几何路径
-			XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/"+p.getPid()+"/LinearModel");
+			XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/es");
+			XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/es/"+p.getPid());
+			XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/es/"+p.getPid()+"/Calculate");
+			XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/es/"+p.getPid()+"/Calculate/Geometry");//几何路径
 
 			//添加模拟数据组件
 			pid = p.getPid();

+ 64 - 2
src/main/java/com/miniframe/bisiness/es/ES0013Service.java

@@ -1,8 +1,18 @@
 package com.miniframe.bisiness.es;
 
+import java.io.File;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+import com.github.dockerjava.api.async.ResultCallback;
+import com.github.dockerjava.api.model.Frame;
 import com.miniframe.core.ExecProcessFlow;
+import com.miniframe.core.ext.UtilTools;
 import com.miniframe.generate.business.es.model.ES0013BaseModel;
+import com.miniframe.tools.XIFileUtils;
+import com.miniframe.tools.docker.DockerExe;
+import es.service.LogService;
+import es.template.TemplateGenerator;
 
 /**
  * 无锡发动机,“项目求解”逻辑处理(重新生成不覆盖)。
@@ -15,9 +25,61 @@ public class ES0013Service extends ES0013BaseModel implements ExecProcessFlow {
 	 * 无锡发动机,“项目求解”业务核心处理
  	 */
 	public void transExecute() throws Exception {
-	
+		String pid = this.getA_es0013().getPid();
+		XIFileUtils.mkdir(XIFileUtils.getRootPathStr());
+		XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/es");
+		XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/es/"+pid);
+		XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/es/"+pid+"/Calculate");
+		XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/es/"+pid+"/Calculate/Geometry");//几何路径
+		TemplateGenerator.createPipenetXml(pid);
+		DockerExe.run(pid);
+	}
+	private void run(String pid) throws Exception {
+		LogService.addLog(pid,"求解——————————————————开始");
+		DockerExe.stopDocker(pid);
+		DockerExe.run(pid);
+		final int[] con = {0};
+		final String[] line = {""};
+		CompletableFuture<Void> cf = CompletableFuture.supplyAsync(()-> {try {
+			DockerExe.getDockerLogs(pid,new ResultCallback.Adapter<Frame>() {
+				@Override
+				public void onNext(Frame frame) {
+					if(con[0] <100){
+						line[0]+=new String(frame.getPayload());
+						con[0]++;
+					}else{
+						LogService.addLog(pid, line[0]);
+						line[0]="";
+						con[0] =0;
+					}
+					LogService.addLog(pid, new String(frame.getPayload()));
+					System.out.print(new String(frame.getPayload()));
+					super.onNext(frame);
+				}
+				@Override
+				public void onError(Throwable throwable) {
+					System.err.println("日志获取失败");
+					LogService.addLog(pid, line[0]);
+					throwable.printStackTrace();
+					DockerExe.stopDocker(pid);
+					super.onError(throwable);
+				}
+				@Override
+				public void onComplete() {
+					System.out.println("日志获取完成");
+					LogService.addLog(pid, line[0]);
+					DockerExe.stopDocker(pid);
+					super.onComplete();
+				}
+			});
+			LogService.addLog(pid,"求解——————————————————成功");
+		} catch (Exception e) {
+			LogService.addLog(pid,"求解——————————————————失败");
+			e.printStackTrace();
+		}
+			return null;
+		});
 	}
-	
 	/**
 	 * 无锡发动机,“项目求解”业务前处理
  	 */

+ 81 - 1
src/main/java/com/miniframe/mappers/es/dao/EsMapper.java

@@ -52,7 +52,7 @@ public interface EsMapper extends MiniserviceBaseDao {
 
 
     /**
-     * 级联查询  项目组件属性值数据
+     *  项目组件属性值数据
      * @param pcId
      * @return
      */
@@ -68,4 +68,84 @@ public interface EsMapper extends MiniserviceBaseDao {
             "from es_pro_com_att a,es_att b where a.att_id=b.att_id and pc_id=#{pcId} ORDER BY ser asc;")
     List<ProComAttDto> selectPrComAttList(String pcId);
 
+
+
+    /**
+     *  项目组件属性值数据 排除数列数据
+     * @param pcId
+     * @return
+     */
+    @Select("select a.pca_id as pcaId," +
+            "a.value as value," +
+            "a.unit as unit," +
+            "b.unit_type as unitType," +
+            "b.name as name," +
+            "b.code as code," +
+            "b.value_def as valueDef," +
+            "b.value_type as valueType, " +
+            "(select max(c.type) from es_data as c where c.cd_id = b.value_def) as dataType " +
+            "from es_pro_com_att a,es_att b " +
+            "where a.att_id=b.att_id " +
+            "and value_type in(0,1,2) " +
+            "and pc_id=#{pcId} " +
+            "ORDER BY ser asc;")
+    List<ProComAttDto> selectPrComAttListNoData(String pcId);
+
+    /**
+     * 项目组件属性值数据查询
+     * @param pcId 项目组件ID
+     * @return
+     */
+    @Select("select DISTINCT cd_id from es_pro_com_att_data where pc_id = #{pcId}")
+    List<String> selectAttDataCdIds(String pcId);
+
+
+    /**
+     *  项目组件属性值数据查询
+     * @param pcId
+     * @return
+     */
+    @Select("select  a.value as value, " +
+            "a.unit as unit, " +
+            "b.unit_type as unitType, " +
+            "b.name as name, " +
+            "b.code as code, " +
+            "b.value_def as valueDef, " +
+            "b.value_type as valueType,0 as dataType  " +
+            "from es_pro_com_att_data a,es_data_att b " +
+            "where a.cdv_id = b.cdv_id and a.pc_id= #{pcId} " +
+            "and a.cd_id=#{cdId}  " +
+            "ORDER BY b.ser asc;")
+    List<ProComAttDto> selectPrComAttDataList(String pcId,String cdId);
+
+
+    /**
+     *  获取组件连接的节点IdCode+Ser 如:N1 N2
+     * @param pcId
+     * @return
+     */
+    @Select("select DISTINCT concat(a.id_code,a.ser) from es_pro_com a ,es_pro_com_con b where a.pc_id = b.npc_id and b.pc_id =#{pcId}")
+    List<String> selectComconNodeIdcodeSer(String pcId);
+
+    /**
+     *  模拟属性查询
+     * @param pcId
+     * @return
+     */
+    @Select("select a.pca_id as pcaId," +
+            "a.value as value," +
+            "a.unit as unit," +
+            "b.unit_type as unitType," +
+            "b.name as name," +
+            "b.code as code," +
+            "b.value_def as valueDef," +
+            "b.value_type as valueType, " +
+            "0 as dataType " +
+            "from es_pro_com_att a,es_att b " +
+            "where a.att_id=b.att_id " +
+            "and a.com_id='-1' " +
+            "and pid=#{pcId} ORDER BY ser asc;")
+    List<ProComAttDto> selectSimulationsPrComAttDataList(String pcId);
+
+
 }

+ 5 - 260
src/main/java/com/miniframe/tools/docker/DockerExe.java

@@ -94,72 +94,8 @@ public class DockerExe {
         // 使用 ResultCallback.Adapter 处理日志
         logContainerCmd.exec(logsexe).awaitCompletion();
     }
-    public static void runMdo(String pid) {
-        DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
-                .withDockerHost(DOCKERHOST) // 设置 Docker 主机地址
-                .withDockerTlsVerify(false) // 启用 TLS 验证
-                .withApiVersion(APIVERSION) // 设置 API 版本
-                .build();
-        DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
-                .dockerHost(config.getDockerHost())
-                .sslConfig(config.getSSLConfig())
-                .build();
-        DockerClient dockerClient = DockerClientBuilder.getInstance(config)
-                .withDockerHttpClient(httpClient)
-                .build();
-
-        Mount cephfsVMount = new Mount()
-                .withType(MountType.BIND)
-                .withSource("/cephfs/mdo/")
-                .withTarget("/cephfs/mdo/")
-                .withReadOnly(false);
-        Mount sitePackages = new Mount()
-                .withType(MountType.BIND)
-                .withSource("/home/xgd/site-packages/")
-                .withTarget("/opt/miniconda3/envs/surromdao/lib/python3.10/site-packages/")
-                .withReadOnly(false);
-        Mount outMount = new Mount()
-                .withType(MountType.BIND)
-                .withSource("/cephfs/mdo/"+pid +"/out/")
-                .withTarget("/workspace/outdata/")
-                .withReadOnly(false);
-        Mount runMount = new Mount()
-                .withType(MountType.BIND)
-                .withSource("/cephfs/mdo/"+pid +"/in/run.py")
-                .withTarget("/workspace/run.py")
-                .withReadOnly(false);
-        Mount nsga2_history1 = new Mount()
-                .withType(MountType.BIND)
-                .withSource("/cephfs/mdo/"+pid +"/out/nsga2_history1.txt")
-                .withTarget("/workspace/nsga2_history1.txt")
-                .withReadOnly(false);
-        Mount nsga2_history2 = new Mount()
-                .withType(MountType.BIND)
-                .withSource("/cephfs/mdo/"+pid +"/out/nsga2_history2.txt")
-                .withTarget("/workspace/nsga2_history2.txt")
-                .withReadOnly(false);
-
-        List<Mount> am =new ArrayList<>();
-        am.add(cephfsVMount);
-        am.add(sitePackages);
-        am.add(outMount);
-        am.add(runMount);
-        am.add(nsga2_history1);
-        am.add(nsga2_history2);
-        //创建容器
-        CreateContainerResponse container = dockerClient
-                .createContainerCmd("xgd:2.0")//镜像名称
-                .withName(pid)//容器名称
-                .withHostConfig(
-                        HostConfig.newHostConfig()
-                                .withMounts(am)
-                ).exec();
-        dockerClient.startContainerCmd(container.getId()).exec();
-        System.out.println("容器启动成功,ID: " + container.getId());
-    }
-
 
-    public static void runMdo3(String pid) {
+    public static void run(String pid) {
         DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
                 .withDockerHost(DOCKERHOST) // 设置 Docker 主机地址
                 .withDockerTlsVerify(false) // 启用 TLS 验证
@@ -175,216 +111,25 @@ public class DockerExe {
 
         Mount wokerMount = new Mount()
                 .withType(MountType.BIND)
-                .withSource("/cephfs/mdo/"+pid+"/in/")
-                .withTarget("/cephfs/mdo/"+pid+"/in/")
+                .withSource("/cephfs/es/"+pid)
+                .withTarget("/cephfs/es/"+pid)
                 .withReadOnly(false);
         List<Mount> am =new ArrayList<>();
         am.add(wokerMount);
 
         //创建容器
         CreateContainerResponse container = dockerClient
-                .createContainerCmd("surromdao:2.0")//镜像名称
+                .createContainerCmd("es:1.0")//镜像名称
                 .withName(pid)//容器名称
                 .withHostConfig(
                         HostConfig.newHostConfig()
                                 .withMounts(am)
-                ).withCmd("bash", "-c", "source /home/mdo/aeroelastic.sh && cd /cephfs/mdo/"+pid+"/in && conda activate surromdao && mpiexec -n 3 python run.py")
+                ).withCmd("bash", "-c", "export LD_LIBRARY_PATH=/home/es/bin:$LD_LIBRARY_PATH && pipenet /cephfs/es/"+pid+"/Calculate")
                 .exec();
         dockerClient.startContainerCmd(container.getId()).exec();
         System.out.println("容器启动成功,ID: " + container.getId());
     }
 
-    public static void runMdo2(String pid) {
-        DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
-                .withDockerHost(DOCKERHOST) // 设置 Docker 主机地址
-                .withDockerTlsVerify(false) // 启用 TLS 验证
-                .withApiVersion(APIVERSION) // 设置 API 版本
-                .build();
-        DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
-                .dockerHost(config.getDockerHost())
-                .sslConfig(config.getSSLConfig())
-                .build();
-        DockerClient dockerClient = DockerClientBuilder.getInstance(config)
-                .withDockerHttpClient(httpClient)
-                .build();
-
-        Mount wokerMount = new Mount()
-                .withType(MountType.BIND)
-                .withSource("/cephfs/mdo/"+pid+"/in/")
-                .withTarget("/cephfs/mdo/"+pid+"/in/")
-                .withReadOnly(false);
-        List<Mount> am =new ArrayList<>();
-        am.add(wokerMount);
 
-        //创建容器
-        CreateContainerResponse container = dockerClient
-                .createContainerCmd("surromdao:1.0")//镜像名称
-                .withName(pid)//容器名称
-                .withHostConfig(
-                        HostConfig.newHostConfig()
-                                .withMounts(am)
-                ).withCmd("bash", "-c", "source /home/mdo/aeroelastic.sh && cd /cephfs/mdo/"+pid+"/in && mpiexec -n 1 python run.py")
-                .exec();
-        dockerClient.startContainerCmd(container.getId()).exec();
-        System.out.println("容器启动成功,ID: " + container.getId());
-    }
-
-
-    public static void cgnsToJson(SysFile file) throws Exception {
-        DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
-                .withDockerHost(DOCKERHOST) // 设置 Docker 主机地址
-                .withDockerTlsVerify(false) // 启用 TLS 验证
-                .withApiVersion(APIVERSION) // 设置 API 版本
-                .build();
-        DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
-                .dockerHost(config.getDockerHost())
-                .sslConfig(config.getSSLConfig())
-                .build();
-        DockerClient dockerClient = DockerClientBuilder.getInstance(config)
-                .withDockerHttpClient(httpClient)
-                .build();
 
-        Path path = Paths.get(XIFileUtils.getRootPathStr()+"/"+file.getFilepath());
-        // 获取文件夹路径
-        String directory = path.getParent().toString();
-        Mount wokerMount = new Mount()
-                .withType(MountType.BIND)
-                .withSource(directory)
-                .withTarget(directory)
-                .withReadOnly(false);
-        List<Mount> am =new ArrayList<>();
-        am.add(wokerMount);
-        String hdfFile =directory+"/"+file.getFilename().replace(".cgns","_hdf5.cgns");
-        File hdf =new File(hdfFile);
-        if(!hdf.exists()){
-            hdf.createNewFile();
-        }
-        String jsonFile =directory+"/"+file.getFilename().replace(".cgns","_data.json");
-        File json =new File(jsonFile);
-        if(!json.exists()){
-            json.createNewFile();
-        }
-        XIFileUtils.saveUploadFiles(hdfFile, "uid","hdf5",file.getId());
-        XIFileUtils.saveUploadFiles(jsonFile, "uid","json",file.getId());
-        //创建容器
-        CreateContainerResponse container = dockerClient
-                .createContainerCmd("cgnsconver:1.0")//镜像名称
-                .withName(file.getId())//容器名称
-                .withHostConfig(
-                        HostConfig.newHostConfig()
-                                .withMounts(am)
-                ).withCmd("bash", "-c", "source /root/miniconda3/etc/profile.d/conda.sh" +
-                        " && conda activate pycgns-env" +
-                        " && cd /home/python/mdo/" +
-                        " && python cgnsConver.py" +
-                        " "+XIFileUtils.getRootPathStr()+"/"+file.getFilepath() +
-                        " " +hdfFile+
-                        " " +jsonFile)
-                .exec();
-        dockerClient.startContainerCmd(container.getId()).exec();
-        System.out.println("容器启动成功,ID: " + container.getId());
-    }
-
-    public static void bdfToJson(SysFile file) throws Exception {
-        DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
-                .withDockerHost(DOCKERHOST) // 设置 Docker 主机地址
-                .withDockerTlsVerify(false) // 启用 TLS 验证
-                .withApiVersion(APIVERSION) // 设置 API 版本
-                .build();
-        DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
-                .dockerHost(config.getDockerHost())
-                .sslConfig(config.getSSLConfig())
-                .build();
-        DockerClient dockerClient = DockerClientBuilder.getInstance(config)
-                .withDockerHttpClient(httpClient)
-                .build();
-
-        Path path = Paths.get(XIFileUtils.getRootPathStr()+"/"+file.getFilepath());
-        // 获取文件夹路径
-        String directory = path.getParent().toString();
-        Mount wokerMount = new Mount()
-                .withType(MountType.BIND)
-                .withSource(directory)
-                .withTarget(directory)
-                .withReadOnly(false);
-        List<Mount> am =new ArrayList<>();
-        am.add(wokerMount);
-
-        String jsonFile =directory+"/"+file.getFilename().replace(".bdf","_data.json");
-        File json =new File(jsonFile);
-        if(!json.exists()){
-            json.createNewFile();
-        }
-        XIFileUtils.saveUploadFiles(jsonFile, "uid","json",file.getId());
-        //创建容器
-        CreateContainerResponse container = dockerClient
-                .createContainerCmd("cgnsconver:1.0")//镜像名称
-                .withName(file.getId())//容器名称
-                .withHostConfig(
-                        HostConfig.newHostConfig()
-                                .withMounts(am)
-                ).withCmd("bash", "-c", "source /root/miniconda3/etc/profile.d/conda.sh" +
-                        " && conda activate pycgns-env" +
-                        " && cd /home/python/mdo/" +
-                        " && python bdfConver.py" +
-                        " "+XIFileUtils.getRootPathStr()+"/"+file.getFilepath() +
-                        " " +jsonFile)
-                .exec();
-        dockerClient.startContainerCmd(container.getId()).exec();
-        System.out.println("容器启动成功,ID: " + container.getId());
-    }
-
-    public static void main(String[] args) {
-        stopDocker("6cb37eea2845457ca17ba6441804af43");
-        runMdo2("6cb37eea2845457ca17ba6441804af43");
-    }
-
-    public static void pltToJson(SysFile file) throws Exception {
-        DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
-                .withDockerHost(DOCKERHOST) // 设置 Docker 主机地址
-                .withDockerTlsVerify(false) // 启用 TLS 验证
-                .withApiVersion(APIVERSION) // 设置 API 版本
-                .build();
-        DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
-                .dockerHost(config.getDockerHost())
-                .sslConfig(config.getSSLConfig())
-                .build();
-        DockerClient dockerClient = DockerClientBuilder.getInstance(config)
-                .withDockerHttpClient(httpClient)
-                .build();
-
-        Path path = Paths.get(XIFileUtils.getRootPathStr()+"/"+file.getFilepath());
-        // 获取文件夹路径
-        String directory = path.getParent().toString();
-        Mount wokerMount = new Mount()
-                .withType(MountType.BIND)
-                .withSource(directory)
-                .withTarget(directory)
-                .withReadOnly(false);
-        List<Mount> am =new ArrayList<>();
-        am.add(wokerMount);
-
-        String plth5File =directory+"/"+file.getFilename().replace(".plt","plt_data.h5");
-        File json =new File(plth5File);
-        if(!json.exists()){
-            json.createNewFile();
-        }
-        XIFileUtils.saveUploadFiles(plth5File, "uid","hdf5",file.getId());
-        //创建容器
-        CreateContainerResponse container = dockerClient
-                .createContainerCmd("cgnsconver:1.0")//镜像名称
-                .withName(file.getId())//容器名称
-                .withHostConfig(
-                        HostConfig.newHostConfig()
-                                .withMounts(am)
-                ).withCmd("bash", "-c", "source /root/miniconda3/etc/profile.d/conda.sh" +
-                        " && conda activate pycgns-env" +
-                        " && cd /home/python/mdo/" +
-                        " && python pltConver.py" +
-                        " "+XIFileUtils.getRootPathStr()+"/"+file.getFilepath() +
-                        " " +plth5File)
-                .exec();
-        dockerClient.startContainerCmd(container.getId()).exec();
-        System.out.println("容器启动成功,ID: " + container.getId());
-    }
 }

+ 73 - 0
src/main/java/es/service/LogService.java

@@ -0,0 +1,73 @@
+package es.service;
+
+import com.miniframe.core.ext.UtilTools;
+import com.miniframe.tools.XIFileUtils;
+import com.miniframe.websocket.WebsocketEndPoint;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * 日志存储
+ */
+public class LogService {
+    public static final String BPATH = "/cephfs/es";
+    /**
+     * 创建文件
+     * @param pid
+     * @return
+     */
+    public static File createLog(String pid){
+        String filePath =LogService.BPATH+"/"+pid+"/log.txt";
+        XIFileUtils.mkdir(LogService.BPATH);
+        XIFileUtils.mkdir(LogService.BPATH+"/"+pid);
+        File file =new File(filePath);
+        return file;
+    }
+
+    /**
+     * 清空文件
+     * @param
+     */
+    public static void clearLog(String pid){
+        String filePath =LogService.BPATH+"/"+pid+"/log.txt";
+        FileWriter writer = null;
+        try {
+            writer = new FileWriter(filePath);
+            writer.write("");  // 将内容设置为空字符串即可清空文件
+            writer.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 文件内容追加
+     * @param
+     */
+    public static void addLog(String pid,String log){
+        String filePath =LogService.BPATH+"/"+pid+"/log.txt";
+        FileWriter writer = null;
+        try {
+            writer = new FileWriter(filePath,true);
+            BufferedWriter bwriter = new BufferedWriter(writer);
+            bwriter.write(log);  // 将内容写入文件末尾
+            bwriter.newLine();
+            bwriter.close();
+            writer.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        if(log.indexOf("求解")>=0){
+            CompletableFuture<Void> cf = CompletableFuture.supplyAsync(()->{
+                WebsocketEndPoint webs =  (WebsocketEndPoint) UtilTools.getBean("websocketEndPoint");
+                webs.sendMessageToUser(String.valueOf(pid),log);
+                return null;
+            });
+        }
+    }
+
+}

+ 39 - 0
src/main/java/es/template/TemplateGenerator.java

@@ -0,0 +1,39 @@
+package es.template;
+
+import com.miniframe.tools.XIFileUtils;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+public class TemplateGenerator {
+    /**
+     * 配置文件pipenet.xml
+     * @param pid
+     * @throws IOException
+     * @throws TemplateException
+     */
+    public static void createPipenetXml(String pid) throws IOException, TemplateException {
+        Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);
+        // 设置模板所在目录
+        cfg.setClassForTemplateLoading(TemplateGenerator.class, "/templates");
+        // 获取模板对象
+        Template template = cfg.getTemplate("pipenet.ftl");
+        // 定义数据模型(Map)
+        Map<String, Object> dataModel = new HashMap<>();
+        dataModel.put("nodes",TemplateServer.findNodes(pid));
+        dataModel.put("coms",TemplateServer.findComs(pid));
+        dataModel.put("sim",TemplateServer.findSimulations(pid));
+        // 将数据模型传入模板进行处理
+        StringWriter writer = new StringWriter();
+        template.process(dataModel, writer);
+        FileWriter fileWriter = new FileWriter(XIFileUtils.getRootPathStr()+"/es/"+pid+"/Calculate/pipenet.xml");
+        fileWriter.write(writer.toString());
+        fileWriter.close();
+    }
+}

+ 98 - 0
src/main/java/es/template/TemplateServer.java

@@ -0,0 +1,98 @@
+package es.template;
+
+import com.miniframe.core.ext.UtilTools;
+import com.miniframe.mappers.es.dao.EsMapper;
+import com.miniframe.mappers.es.model.ProComAttDto;
+import com.miniframe.model.es.*;
+import com.miniframe.model.es.dao.*;
+import es.template.pipenet.Component;
+import es.template.pipenet.ComponetData;
+import es.template.pipenet.Node;
+import es.template.pipenet.Simulations;
+
+import javax.rmi.CORBA.Util;
+import java.util.ArrayList;
+import java.util.List;
+
+public class TemplateServer {
+
+    public static List<Node> findNodes(String pid ){
+        List<Node> nodes = new ArrayList<>();
+        EsProComMapper cdao = UtilTools.getBean(EsProComMapper.class);
+        EsProComSQLBuilder csb = new EsProComSQLBuilder();
+        EsProComSQLBuilder.Criteria csc = csb.createCriteria();
+        csc.andPidEqualTo(pid);
+        csc.andComIdEqualTo("3");//节点
+        csb.setOrderByClause("ser asc");
+        List<EsProCom> cs =cdao.selectByExample(csb);
+        for (EsProCom c:cs) {
+            Node n =new Node();
+            n.setNode(c);
+            EsMapper esdao = UtilTools.getBean(EsMapper.class);
+            List<ProComAttDto> atts = esdao.selectPrComAttList(c.getPcId());
+            n.setAtts(atts);
+            nodes.add(n);
+        }
+        return  nodes;
+    }
+    public static List<Component> findComs(String pid ){
+        List<Component> coms = new ArrayList<>();
+        EsMapper esdao = UtilTools.getBean(EsMapper.class);
+        EsProComMapper cdao = UtilTools.getBean(EsProComMapper.class);
+
+        EsProComSQLBuilder csb = new EsProComSQLBuilder();
+        EsProComSQLBuilder.Criteria csc = csb.createCriteria();
+        csc.andPidEqualTo(pid);
+        csc.andComIdNotEqualTo("3");//非节点
+        csc.andComIdNotEqualTo("-1");//非模拟数据
+        csb.setOrderByClause("ser asc");
+        List<EsProCom> cs =cdao.selectByExample(csb);
+        for (EsProCom c:cs) {
+            EsComMapper comdao =UtilTools.getBean(EsComMapper.class);
+            EsCom  cm= comdao.selectByPrimaryKey(c.getComId());
+            Component com = new Component();
+            com.setCom(cm);
+            com.setPcom(c);
+            //获取非下拉值数据
+            List<ProComAttDto> atts =esdao.selectPrComAttListNoData(c.getPcId());
+            com.setAtts(atts);
+
+            //获取下拉值数据
+            List<ComponetData> datas = new ArrayList<>();
+            List<String> cdIds = esdao.selectAttDataCdIds(c.getPcId());
+            for (String cdId:cdIds) {
+                EsDataMapper ddao = UtilTools.getBean(EsDataMapper.class);
+                EsData d = ddao.selectByPrimaryKey(cdId);
+                List<ProComAttDto> datts =esdao.selectPrComAttDataList(c.getPcId(),cdId);
+                ComponetData data = new ComponetData();
+                data.setCode(d.getCode());
+                data.setAtts(datts);
+                datas.add(data);
+            }
+            com.setDatas(datas);
+
+            //获取链接数据
+            List<String> nIds =esdao.selectComconNodeIdcodeSer(c.getPcId());
+            com.setNodeIds(nIds);
+
+            coms.add(com);
+        }
+        return  coms;
+    }
+
+    /**
+     * 获取模拟数据
+     * @param pid
+     * @return
+     */
+    public static Simulations findSimulations(String pid ){
+        Simulations sim =new Simulations();
+        EsMapper esdao = UtilTools.getBean(EsMapper.class);
+        List<ProComAttDto> comatt = esdao.selectSimulationsPrComAttDataList(pid);
+        sim.setType( comatt.get(0).getValue());//仿真类型
+        comatt.remove(0);
+        sim.setAtts(comatt);
+        return sim;
+    }
+
+}

+ 18 - 0
src/main/java/es/template/pipenet/Component.java

@@ -0,0 +1,18 @@
+package es.template.pipenet;
+
+import com.miniframe.mappers.es.model.ProComAttDto;
+import com.miniframe.model.es.EsCom;
+import com.miniframe.model.es.EsProCom;
+import com.miniframe.model.es.EsProComCon;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class Component {
+    private EsProCom pcom;
+    private EsCom com;
+    private List<ProComAttDto> atts;//排除value 为3 的数据
+    private List<ComponetData> datas;
+    private List<String> nodeIds;//链接节点数据
+}

+ 11 - 0
src/main/java/es/template/pipenet/ComponetData.java

@@ -0,0 +1,11 @@
+package es.template.pipenet;
+
+import com.miniframe.mappers.es.model.ProComAttDto;
+import lombok.Data;
+
+import java.util.List;
+@Data
+public class ComponetData {
+    private String code;
+    private List<ProComAttDto> atts;
+}

+ 14 - 0
src/main/java/es/template/pipenet/Node.java

@@ -0,0 +1,14 @@
+package es.template.pipenet;
+
+import com.miniframe.mappers.es.model.ProComAttDto;
+import com.miniframe.model.es.EsProCom;
+import com.miniframe.model.es.EsProComAtt;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class Node {
+    private EsProCom node;
+    private List<ProComAttDto> atts;
+}

+ 15 - 0
src/main/java/es/template/pipenet/Simulations.java

@@ -0,0 +1,15 @@
+package es.template.pipenet;
+
+import com.miniframe.mappers.es.model.ProComAttDto;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 模拟数据
+ */
+@Data
+public class Simulations {
+    private String type ;
+    private List<ProComAttDto> atts;
+}

+ 0 - 395
src/main/resources/templates/cpacs.ftl

@@ -1,395 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<cpacs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../schema/cpacs_schema.xsd">
-    <header>
-        <name>${vo.header.name}</name>
-        <creator>SurroMDAO</creator>
-        <timestamp>${vo.header.timestamp}</timestamp>
-        <version>1.0</version>
-        <cpacsVersion>3.3</cpacsVersion>
-    </header>
-    <vehicles>
-        <#if vo.cst??>
-        <profiles>
-            <wingAirfoils>
-                <wingAirfoil uID="foil1">
-                    <name>foil1</name>
-                    <description>airfoil</description>
-                    <cst2D mapType="complex">
-                        <N>${vo.cst.cstn}</N>
-                        <lowerB mapType="vector">${vo.cst.lowerb?replace( ",", ";")}</lowerB>
-                        <lowerN1 mapType="double">${vo.cst.lowern1}</lowerN1>
-                        <lowerN2 mapType="double">${vo.cst.lowern2}</lowerN2>
-                        <upperB mapType="vector">${vo.cst.upperb?replace(",", ";")}</upperB>
-                        <upperN1 mapType="double">${vo.cst.uppern1}</upperN1>
-                        <upperN2 mapType="double">${vo.cst.uppern2}</upperN2>
-                        <trailingEdgeThickness mapType="double">0</trailingEdgeThickness>
-                    </cst2D>
-                </wingAirfoil>
-            </wingAirfoils>
-        </profiles>
-        <#else>
-        </#if>
-        <#if vo.adflow??>
-        <aircraft>
-            <model uID="wing">
-                <name>wing</name>
-                <reference mapType="complex">
-                    <area mapType="double">${vo.adflow.area}</area>
-                    <length mapType="double">${vo.adflow.length}</length>
-                    <point mapType="complex">
-                        <x mapType="double">${vo.adflow.momx}</x>
-                        <y mapType="double">${vo.adflow.momy}</y>
-                        <z mapType="double">${vo.adflow.momz}</z>
-                    </point>
-                </reference>
-                    <#if vo.fsi??>
-                     <wings>
-                              <wing uID="wing1">
-                                <name>main wing</name>
-                                <transformation/>
-                                <sections>
-                                  <section uID="wing1section1">
-                                    <name>root section</name>
-                                    <transformation>
-                                      <rotation>
-                                        <x>0.0</x>
-                                        <y>0.0</y>
-                                        <z>0.0</z>
-                                      </rotation>
-                                      <scaling>
-                                        <x>1</x>
-                                        <y>1</y>
-                                        <z>1</z>
-                                      </scaling>
-                                      <translation>
-                                        <x>0.0</x>
-                                        <y>0.0</y>
-                                        <z>0.0</z>
-                                      </translation>
-                                    </transformation>
-                                    <elements>
-                                      <element uID="wing1section1element1">
-                                        <name>wing root element</name>
-                                        <airfoilUID>foil1</airfoilUID>
-                                        <transformation>
-                                          <rotation>
-                                            <x>0.0</x>
-                                            <y>0.0</y>
-                                            <z>0.0</z>
-                                          </rotation>
-                                          <scaling>
-                                            <x>1</x>
-                                            <y>1</y>
-                                            <z>1</z>
-                                          </scaling>
-                                          <translation>
-                                            <x>0.0</x>
-                                            <y>0.0</y>
-                                            <z>0.0</z>
-                                          </translation>
-                                        </transformation>
-                                      </element>
-                                    </elements>
-                                  </section>
-                                  <section uID="wing1section2">
-                                    <name>tip section</name>
-                                    <transformation>
-                                      <rotation>
-                                        <x>0.0</x>
-                                        <y>0.0</y>
-                                        <z>0.0</z>
-                                      </rotation>
-                                      <scaling>
-                                        <x>1</x>
-                                        <y>1</y>
-                                        <z>1</z>
-                                      </scaling>
-                                      <translation>
-                                        <x>0</x>
-                                        <y>0</y>
-                                        <z>0</z>
-                                      </translation>
-                                    </transformation>
-                                    <elements>
-                                      <element uID="wing1section2element1">
-                                        <name>wing tip element</name>
-                                        <airfoilUID>foil1</airfoilUID>
-                                        <transformation>
-                                          <rotation>
-                                            <x>0.0</x>
-                                            <y>0.0</y>
-                                            <z>0.0</z>
-                                          </rotation>
-                                          <scaling>
-                                            <x>1</x>
-                                            <y>1</y>
-                                            <z>1</z>
-                                          </scaling>
-                                          <translation>
-                                            <x>0.0</x>
-                                            <y>0.0</y>
-                                            <z>0.0</z>
-                                          </translation>
-                                        </transformation>
-                                      </element>
-                                    </elements>
-                                  </section>
-                                </sections>
-                                <positionings>
-                                  <positioning uID="W1_Pos1">
-                                    <name>Wing_Position1</name>
-                                    <length>0</length>
-                                    <sweepAngle>0</sweepAngle>
-                                    <dihedralAngle>0.0</dihedralAngle>
-                                    <toSectionUID isLink="True">wing1section1</toSectionUID>
-                                  </positioning>
-                                  <positioning uID="W1_Pos2">
-                                    <name>Wing_Position2</name>
-                                    <length>1</length>
-                                    <sweepAngle>0</sweepAngle>
-                                    <dihedralAngle>0.0</dihedralAngle>
-                                    <fromSectionUID isLink="True">wing1section1</fromSectionUID>
-                                    <toSectionUID isLink="True">wing1section2</toSectionUID>
-                                  </positioning>
-                                </positionings>
-                                <segments>
-                                  <segment uID="wing1segment1">
-                                    <name>wing segment</name>
-                                    <fromElementUID>wing1section1element1</fromElementUID>
-                                    <toElementUID>wing1section2element1</toElementUID>
-                                  </segment>
-                                </segments>
-                              </wing>
-                            </wings>
-                    <#else>
-                    </#if>
-
-            </model>
-        </aircraft>
-        <#else>
-        </#if>
-    </vehicles>
-    <toolspecific>
-         <CFD>
-         <#if vo.xfoil??>
-            <XFOIL mapType="complex" uID="xfoil">
-                <proName>CRM</proName>
-                <analyzed mapType="boolean">1</analyzed>
-                <options mapType="complex">
-                    <pacc>${vo.xfoil.pacc}</pacc>
-                    <cpwr>${vo.xfoil.cpwr}</cpwr>
-                    <iter mapType="integer">${vo.xfoil.iter}</iter>
-                    <ppar mapType="integer">${vo.xfoil.ppar}</ppar>
-                     <pparT mapType="double">0.15</pparT>
-                    <xtr mapType="vector">0.001;0.001</xtr>
-                    <Ncrit mapType="double">9.0</Ncrit>
-                </options>
-                <condition mapType="complex">
-                    <alpha mapType="double">${vo.xinvo.alpha}</alpha>
-                    <mach mapType="double">${vo.xinvo.mach}</mach>
-                    <reynolds mapType="double">${vo.xinvo.reynolds}</reynolds>
-                </condition>
-                <evalFuncs mapType="complex">
-                    <cl mapType="double">${vo.xoutvo.cl}</cl>
-                    <cd mapType="double">${vo.xoutvo.cd}</cd>
-                    <cdp mapType="double">${vo.xoutvo.cdp}</cdp>
-                    <cm mapType="double">${vo.xoutvo.cm}</cm>
-                    <xtr_upper mapType="double">${vo.xoutvo.xtr_upper}</xtr_upper>
-                    <xtr_lower mapType="double">${vo.xoutvo.xtr_lower}</xtr_lower>
-                    <maxThickness mapType="double">0.119989</maxThickness>
-                </evalFuncs>
-            </XFOIL>
-         <#else>
-         </#if>
-         <#if vo.adflow??>
-             <ADflow mapType="complex" uID="ADflow">
-             <switch mapType="boolean">1</switch>
-             <proName>${vo.adflow.proname}</proName>
-             <analyzed mapType="boolean">0</analyzed>
-             <isAirfoil mapType="boolean">${vo.adflow.isairfoil}</isAirfoil>
-             <num_process mapType="integer">1</num_process>
-             <options mapType="complex">
-                 <gridFile>${vo.adflow.gridfile}</gridFile>
-                 <writeTecplotSurfaceSolution mapType="boolean">${vo.adflow.writetecplotsurfacesolution}</writeTecplotSurfaceSolution>
-                 <#if vo.adflow.writeslicesolution==1>
-                     <spanDirection>${vo.adflow.spandirection}</spanDirection>
-                     <slices mapType="vector">${vo.adflow.slices}</slices>
-                  <#else>
-                  </#if>
-                 <equationType>${vo.adflow.equationtype}</equationType>
-                 <smoother>DADI</smoother>
-                 <MGCycle>${vo.adflow.mgcycle}</MGCycle>
-                 <nCycles mapType="integer">${vo.adflow.ncycles}</nCycles>
-                 <monitorvariables mapType="complex">
-                    <monitorvariable1>resrho</monitorvariable1>
-                    <monitorvariable2>cl</monitorvariable2>
-                    <monitorvariable3>cd</monitorvariable3>
-                    <monitorvariable4>cmz</monitorvariable4>
-                 </monitorvariables>
-                 <useNKSolver mapType="boolean">0</useNKSolver>
-                 <useanksolver mapType="boolean">0</useanksolver>
-                 <nsubiterturb mapType="integer">5</nsubiterturb>
-                 <liftIndex mapType="integer">${vo.adflow.liftindex}</liftIndex>
-                 <infchangecorrection mapType="boolean">1</infchangecorrection>
-                 <L2Convergence mapType="double">${vo.adflow.l2convergence}</L2Convergence>
-                 <L2ConvergenceCoarse mapType="double">${vo.adflow.l2convergencecoarse}</L2ConvergenceCoarse>
-                 <NKSwitchTol mapType="double">1e-8</NKSwitchTol>
-                 <ANKSwitchTol mapType="double">1e-1</ANKSwitchTol>
-                 <L2ConvergenceRel mapType="double">1e-3</L2ConvergenceRel>
-             </options>
-             <condition mapType="complex">
-                 <mode mapType="integer">2</mode>
-                 <alpha mapType="double">${vo.adinvo.alpha}</alpha>
-                 <mach mapType="double">${vo.adinvo.mach}</mach>
-                 <reynolds mapType="double">${vo.adinvo.reynolds}</reynolds>
-                 <temperature mapType="double">${vo.adflow.temperature}</temperature>
-                 <reynoldsLength mapType="double">7.00532</reynoldsLength>
-             </condition>
-             <evalFuncs mapType="complex">
-                 <force mapType="complex">
-                    <#if vo.adoutvo.iscl>
-                        <cl mapType="double">${vo.adoutvo.cl}</cl>
-                    <#else>
-                    </#if>
-                    <#if vo.adoutvo.iscd>
-                       <cd mapType="double">${vo.adoutvo.cd}</cd>
-                    <#else>
-                    </#if>
-                    <#if vo.adoutvo.iscmz>
-                       <cmz mapType="double">${vo.adoutvo.cmz}</cmz>
-                    <#else>
-                    </#if>
-                    <#if vo.adoutvo.iscmy>
-                       <cmy mapType="double">${vo.adoutvo.cmy}</cmy>
-                    <#else>
-                    </#if>
-                 </force>
-                 <#if (vo.adflow??&&!vo.fsi??)>
-                 <geometry mapType="complex">
-                        <volume mapType="complex">
-                            <switch mapType="boolean">0</switch>
-                            <regionFile>leteList_V.dat</regionFile>
-                            <value mapType="double">0.0</value>
-                        </volume>
-                        <thickness mapType="complex">
-                            <switch mapType="boolean">0</switch>
-                            <regionFile>leteList_T.dat</regionFile>
-                            <value mapType="vector">1.0;1.0</value>
-                        </thickness>
-                 </geometry>
-                <#else>
-                </#if>
-                <#if (vo.adflow??&&vo.fsi??)>
-               <geometry mapType="complex">
-                 <volume mapType="complex">
-                   <switch mapType="boolean">0</switch>
-                   <regionFile>leteList_V.dat</regionFile>
-                   <value mapType="double">1.0157941664348846</value>
-                 </volume>
-                 <thickness mapType="complex">
-                   <switch mapType="boolean">0</switch>
-                   <regionFile>leteList_T.dat</regionFile>
-                   <value mapType="vector">1.0156529841678492;1.0459817270378342;0.982228728144094;1.0100950922390721;0.9719116093300137;0.9874376676002637;1.0191616929171468;1.0676555041542097</value>
-                 </thickness>
-               </geometry>
-                <#else>
-                </#if>
-             </evalFuncs>
-         </ADflow>
-         <#else>
-         </#if>
-        </CFD>
-         <#if vo.tacs??>
-             <CSD>
-               <TACS mapType="complex" uID="TACS">
-                 <switch mapType="boolean">1</switch>
-                 <proName>${vo.tacs.proname}</proName>
-                 <analyzed mapType="boolean">1</analyzed>
-                 <bdfFile>${vo.tacs.fname}</bdfFile>
-                 <bdfFully mapType="boolean">0</bdfFully>
-                 <useFFD mapType="boolean">${vo.tacs.useffd}</useFFD>
-                 <options mapType="complex">
-                   <writeSolution mapType="boolean">1</writeSolution>
-                   <L2Convergence mapType="double">${vo.tacs.l2convergence}</L2Convergence>
-                   <L2ConvergenceRel mapType="double">${vo.tacs.l2convergencerel}</L2ConvergenceRel>
-                   <nRestarts mapType="integer">15</nRestarts>
-                 </options>
-                 <material mapType="complex">
-                   <rho mapType="double">${vo.tacs.rho}</rho>
-                   <E mapType="double">${vo.tacs.e}</E>
-                   <nu mapType="double">${vo.tacs.nu}</nu>
-                   <ys mapType="double">${vo.tacs.ys}</ys>
-                   <thickness mapType="vector">${vo.tacs.thickness}</thickness>
-                 </material>
-                 <evalFuncs mapType="complex">
-                 <#if vo.tacsoutvo.ismass>
-                    <mass mapType="double">${vo.tacsoutvo.mass}</mass>
-                 <#else>
-                 </#if>
-                 <#if vo.tacsoutvo.ismaxdeform>
-                    <maxdeform mapType="double">${vo.tacsoutvo.maxdeform}</maxdeform>
-                 <#else>
-                 </#if>
-                 <#if vo.tacsoutvo.isks_vmfailure>
-                    <ks_vmfailure mapType="double">${vo.tacsoutvo.ks_vmfailure}</ks_vmfailure>
-                 <#else>
-                 </#if>
-                 </evalFuncs>
-               </TACS>
-             </CSD>
-          <#else>
-            <CSD/>
-          </#if>
-
-            <#if vo.fsi??>
-            <aeroelastic mapType="complex" uID="aeroelastic">
-                <stepMax mapType="integer">${vo.fsi.stepmax}</stepMax>
-                <outputSteps mapType="boolean">${vo.fsi.outputsteps}</outputSteps>
-                <datatransfer mapType="complex">
-                <method>${vo.fsi.method}</method>
-                <couplingGrid mapType="complex">
-                    <aeroGroup mapType="complex">
-                    <allWalls mapType="boolean">1</allWalls>
-                    </aeroGroup>
-                    <structGroup mapType="complex">
-                        <skin mapType="boolean">${vo.fsi.skin}</skin>
-                        <spar mapType="boolean">${vo.fsi.spar}</spar>
-                    </structGroup>
-                </couplingGrid>
-                </datatransfer>
-            </aeroelastic>
-            <#else>
-            </#if>
-
-
-        <#if vo.mathfunc??>
-        <mathematical>
-          <mathFunc mapType="complex" uID="mathFunc1">
-            <cd_mass mapType="double">${vo.mathfuncVo.cd_mass}</cd_mass>
-          </mathFunc>
-        </mathematical>
-         <#else>
-        </#if>
-
-        <#if vo.ffd??>
-         <FFD mapType="complex" uID="FFD">
-                <switch mapType="boolean">1</switch>
-                <FFDFile>${vo.ffd.fname}</FFDFile>
-                <order mapType="integer">2</order>
-                <Controlpoints mapType="complex">
-                    <Nx mapType="integer">${vo.ffd.nx}</Nx>
-                    <Ny mapType="integer">${vo.ffd.ny}</Ny>
-                    <Nz mapType="integer">${vo.ffd.nz}</Nz>
-                </Controlpoints>
-                <vars mapType="complex">
-                    <sample mapType="vector">${vo.ffd.vars?replace( ",", ";")}</sample>
-                    <local_shape_dv mapType="boolean">1</local_shape_dv>
-                </vars>
-         </FFD>
-          <#else>
-          </#if>
-
-
-
-    </toolspecific>
-</cpacs>

+ 0 - 76
src/main/resources/templates/mail_script.html

@@ -1,76 +0,0 @@
-
-<html lang="zh-CN">
-<head>
-    <meta charset="UTF-8">
-    
-    
-    <title>您的民用飞机多学科联合设计优化软件注册验证码</title>
-    <style>
-        body {
-            font-family: "Arial", "Helvetica Neue", "Helvetica", sans-serif;
-            line-height: 1.6;
-            color: #333333;
-            background-color: #f4f4f4;
-            margin: 0;
-            padding: 0;
-        }
-        .container {
-            max-width: 600px;
-            margin: 20px auto;
-            background-color: #ffffff;
-            padding: 20px 30px;
-            border-radius: 8px;
-            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-        }
-        h1 {
-            color: #333333;
-            font-size: 24px;
-            margin-bottom: 20px;
-            text-align: center;
-        }
-        p {
-            margin-bottom: 15px;
-        }
-        .verification-code {
-            display: block;
-            width: fit-content;
-            margin: 25px auto;
-            padding: 15px 25px;
-            font-size: 28px;
-            font-weight: bold;
-            color: #007bff; /* 可以根据您的品牌色调整 */
-            background-color: #e9ecef; /* 可以根据您的品牌色调整 */
-            border-radius: 4px;
-            text-align: center;
-            letter-spacing: 2px; /* 增加字母间距方便阅读 */
-        }
-        .note {
-            font-size: 14px;
-            color: #666666;
-        }
-        .footer {
-            margin-top: 30px;
-            padding-top: 20px;
-            border-top: 1px solid #eeeeee;
-            font-size: 12px;
-            color: #999999;
-            text-align: center;
-        }
-    </style>
-</head>
-<body>
-    <div class="container">
-        <h1>您的民用飞机多学科联合设计优化软件注册验证码</h1>
-        <p>尊敬的{{username}}:</p>
-        <p>感谢您注册民用飞机多学科联合设计优化软件!您正在进行账号注册的邮箱验证操作。为了保障您的账户安全,请使用以下验证码完成验证。</p>
-        <p style="text-align: center;">您的验证码是:</p>
-        <div class="verification-code">{{verification_code}}</div>
-        <p>请在5分钟内输入此验证码进行验证。请妥善保管此验证码,切勿透露给任何人,包括气动与多学科优化设计研究所的客服人员。</p>
-        <p class="note">如果您没有进行注册操作,请忽略此邮件。这可能是他人误输入了您的邮箱地址。</p>
-        <div class="footer">
-            这是系统自动发送的邮件,请勿直接回复。<br>
-            气动与多学科优化设计研究所团队
-        </div>
-    </div>
-</body>
-</html>

+ 33 - 0
src/main/resources/templates/pipenet.ftl

@@ -0,0 +1,33 @@
+<Nodes>
+ <#list nodes as n>
+    <Node ID = "${n.node.idCode}${n.node.ser}">
+    <#list n.atts as att>
+        <${att.code}>${att.value!""}</${att.code}>
+    </#list>
+    </Node>
+ </#list>
+</Nodes>
+<Components>
+ <#list coms as c>
+    <${c.com.code} type="${c.com.type}" ID="${c.pcom.idCode}${c.pcom.ser}">
+      <#list c.atts as a>
+        <${a.code} <#if a.unitType??&&a.unitType!="无">unit="${a.unit!""}"<#else></#if>>${a.value!""}</${a.code}>
+      </#list>
+       <#list c.datas as d>
+        <${d.code}>
+            <#list d.atts as a>
+            <${a.code}>${a.value!""}</${a.code}>
+            </#list>
+        </${d.code}>
+       </#list>
+        <#list c.nodeIds as nid>
+        <Arm>${nid}</Arm>
+        </#list>
+     </${c.com.code}>
+ </#list>
+</Components>
+<Simulations type = "${sim.type!""}">
+ <#list sim.atts as a>
+     <${a.code} <#if a.unitType??&&a.unitType!="无">unit="${a.unit!""}"<#else></#if>>${a.value!""}</${a.code}>
+ </#list>
+</Simulations>

+ 0 - 119
src/main/resources/templates/problem.ftl

@@ -1,119 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<surromdaoProblem>
-  <header>
-    <name>${vo.header.name}</name>
-    <creator>SurroMDAO</creator>
-    <timestamp>${vo.header.timestamp}</timestamp>
-    <fileversion>1.0</fileversion>
-    <surromdaoVersion>V1.1</surromdaoVersion>
-  </header>
-  <problem>
-    <designVariables>
-      <#list vo.designVariables as b>
-      <designVariable uID="${b.uID}">
-        <name>${b.name}</name>
-        <value>${b.value}</value>
-        <lowerbound>${b.lowerbound}</lowerbound>
-        <upperbound>${b.upperbound}</upperbound>
-      </designVariable>
-      </#list>
-    </designVariables>
-     <constraints>
-          <#list vo.constraints as b>
-          <constraint uID="${b.uID}">
-                <name>${b.name}</name>
-                <value>${b.value}</value>
-                <lower>${b.lower}</lower>
-                <upper>${b.upper}</upper>
-          </constraint>
-          </#list>
-        </constraints>
-    <objectives>
-      <#list vo.objectives as b>
-      <objective uID="${b.uID}">
-        <name>${b.name}</name>
-        <value>${b.value}</value>
-        <weight>${b.weight}</weight>
-        <flag>${b.flag}</flag>
-      </objective>
-      </#list>
-    </objectives>
-  </problem>
-  <optimizers>
-    <optimizer uID="optimizer3">
-      <#if vo.evolution??>
-      <name>${vo.evolution.algorithm}</name>
-      <configFile/>
-      <configuration>
-        <maxgen>${vo.evolution.epoch}</maxgen>
-        <ipopsize>${vo.evolution.popsize}</ipopsize>
-        <pc>${vo.evolution.probcrossover}</pc>
-        <pm>${vo.evolution.probmut}</pm>
-      </configuration>
-      <#else>
-      </#if>
-      <#if vo.surro??>
-        <name>${vo.surro.algorithm}</name>
-        <configuration>
-            <irestart>${vo.surro.irestart}</irestart>
-            <ndoe>${vo.surro.ndoe}</ndoe>
-            <ns>${vo.surro.ns}</ns>
-            <nsmax>${vo.surro.nsmax}</nsmax>
-            <x_tol>${vo.surro.xTol}</x_tol>
-            <feasibility_tol_real>${vo.surro.feasibilityTolReal}</feasibility_tol_real>
-            <feasibility_tol_surro>${vo.surro.feasibilityTolSurro}</feasibility_tol_surro>
-            <nsurro>${vo.surro.nsurro}</nsurro>
-            <n_kriging>${vo.surro.nKriging}</n_kriging>
-            <corr>${vo.surro.corr}</corr>
-            <const_theta>${vo.surro.constTheta}</const_theta>
-            <porder>${vo.surro.porder}</porder>
-            <dcmp>${vo.surro.dcmp}</dcmp>
-            <paraopt>${vo.surro.paraopt}</paraopt>
-            <regular>${vo.surro.regular}</regular>
-            <infill>${vo.surro.infill}</infill>
-            <nparallel>${vo.surro.nparallel}</nparallel>
-            <iopt>${vo.surro.iopt}</iopt>
-            <icstr>${vo.surro.icstr}</icstr>
-            <ipopsize>${vo.surro.ipopsize}</ipopsize>
-            <maxgen>${vo.surro.maxgen}</maxgen>
-            <pc>${vo.surro.pc}</pc>
-            <pm>${vo.surro.pm}</pm>
-            <myid_number>1</myid_number>
-        </configuration>
-      <#else>
-      </#if>
-      <#if vo.grad??>
-        <name>${vo.grad.algorithm?lower_case}</name>
-        <configuration>
-            <major_iterations_limit>${vo.grad.majorIterationsLimit}</major_iterations_limit>                     <!--最大外迭代步数 -->
-            <major_print_level>${vo.grad.majorPrintLevel}</major_print_level> 		    				     <!--输出精度等级-->
-            <linear_feasibility_tolerance>${vo.grad.linearFeasibilityTolerance}</linear_feasibility_tolerance>        <!--线性约束容差 -->
-            <nonlinear_feasibility_tolerance>${vo.grad.nonlinearFeasibilityTolerance}</nonlinear_feasibility_tolerance>  <!--非线性约束容差-->
-            <optimality_tolerance>${vo.grad.optimalityTolerance}</optimality_tolerance>    	                 <!--最优性度量(KKT 条件)容差-->
-            <verify_level>${vo.grad.verifyLevel}</verify_level> 		    					             <!--梯度验证级别 -1:不验证 0:简单验证 1-3:详细验证(1目标-2约束-3目标+约束)-->
-        </configuration>
-      <#else>
-      </#if>
-    </optimizer>
-  </optimizers>
-  <solvers>
-    <#list vo.solvers as b>
-    <solver>
-       <#if b.cpacsPath??>
-        <cpacsPath>${b.cpacsPath}</cpacsPath>
-       <#else>
-        <cpacsPath/>
-       </#if>
-       <#if b.workflowPath??>
-         <workflowPath>${b.workflowPath}</workflowPath>
-       <#else>
-         <workflowPath/>
-       </#if>
-       <#if b.pythonPath??>
-        <pythonPath name="${b.stype}">${b.pythonPath}</pythonPath>
-       <#else>
-       </#if>
-    </solver>
-    </#list>
-  </solvers>
-</surromdaoProblem>

+ 0 - 7
src/main/resources/templates/run.ftl

@@ -1,7 +0,0 @@
-from surromdao.utils import *
-prob = Problem.load_problem_from_xml('${problemPath}')
-opt = OptTask(prob, "tz")
-opt.run()
-history = opt.get_history()
-history.save_history_to_txt(file_path="./nsga2_history1.txt")
-history.save_best_obj_history_to_txt(file_path="./nsga2_history2.txt")

+ 0 - 7
src/main/resources/templates/run2.ftl

@@ -1,7 +0,0 @@
-from surromdao.utils import *
-prob = Problem.load_problem_from_xml('${problemPath}')
-opt = OptTask(prob, "tz")
-opt.run()
-history = opt.get_history()
-history.save_history_to_txt(file_path="history_all.txt")
-history.save_best_obj_history_to_txt(file_path="history_optimum.txt")

+ 0 - 81
src/main/resources/templates/workflow.ftl

@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<opcs>
-    <header>
-        <name>${vo.header.name}</name>
-        <creator>SurroMDAO</creator>
-        <timestamp>${vo.header.timestamp}</timestamp>
-        <version>0.1</version>
-        <opcsVersion>1.0</opcsVersion>
-    </header>
-    <schema>
-        <solvers>
-            <component uID="xfoil">
-                <name>pyXFoil</name>
-                <input>
-                    <parameterUID>/cpacs/vehicles/profiles/wingAirfoils/wingAirfoil/cst2D/lowerB</parameterUID>
-                </input>
-                <input>
-                    <parameterUID>/cpacs/vehicles/profiles/wingAirfoils/wingAirfoil/cst2D/upperB</parameterUID>
-                </input>
-                <output>
-                    <parameterUID>/cpacs/toolspecific/CFD/XFOIL/evalFuncs/cd</parameterUID>
-                </output>
-                <output>
-                    <parameterUID>/cpacs/toolspecific/CFD/XFOIL/evalFuncs/cl</parameterUID>
-                </output>
-                <execute tpye="component">execute</execute>
-            </component>
-        </solvers>
-        <executeOrder>
-            <componentUID position="1">xfoil</componentUID>
-        </executeOrder>
-        <segments>
-            <process>
-                <segment uID="Seg0">
-                    <fromComponentUID>Problem</fromComponentUID>
-                    <toComponentUID>optimizer3</toComponentUID>
-                </segment>
-                <segment uID="Seg1">
-                    <fromComponentUID>optimizer3</fromComponentUID>
-                    <toComponentUID>CST</toComponentUID>
-                </segment>
-                <segment uID="Seg2">
-                    <fromComponentUID>CST</fromComponentUID>
-                    <toComponentUID>Xfoil</toComponentUID>
-                </segment>
-                <segment uID="Seg3">
-                    <fromComponentUID>Xfoil</fromComponentUID>
-                    <toComponentUID>optimizer3</toComponentUID>
-                </segment>
-            </process>
-            <data>
-                <segment uID="Seg0">
-                    <fromComponentUID>optimizer3</fromComponentUID>
-                    <toComponentUID>CST</toComponentUID>
-                </segment>
-                <segment uID="Seg1">
-                    <fromComponentUID>CST</fromComponentUID>
-                    <toComponentUID>Xfoil</toComponentUID>
-                </segment>
-                <segment uID="Seg2">
-                    <fromComponentUID>Xfoil</fromComponentUID>
-                    <toComponentUID>optimizer3</toComponentUID>
-                </segment>
-            </data>
-        </segments>
-        <parameters>
-            <parameter uID="/cpacs/vehicles/profiles/wingAirfoils/wingAirfoil/cst2D/upperB">
-                <label>upperB</label>
-            </parameter>
-            <parameter uID="/cpacs/vehicles/profiles/wingAirfoils/wingAirfoil/cst2D/lowerB">
-                <label>lowerB</label>
-            </parameter>
-            <parameter uID="/cpacs/toolspecific/CFD/XFOIL/evalFuncs/cd">
-                <label>cd</label>
-            </parameter>
-            <parameter uID="/cpacs/toolspecific/CFD/XFOIL/evalFuncs/cl">
-                <label>cl</label>
-            </parameter>
-        </parameters>
-    </schema>
-</opcs>

+ 0 - 81
src/main/resources/templates/workflow2.ftl

@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<opcs>
-    <header>
-        <name>${vo.header.name}</name>
-        <creator>SurroMDAO</creator>
-        <timestamp>${vo.header.timestamp}</timestamp>
-        <version>0.1</version>
-        <opcsVersion>1.0</opcsVersion>
-    </header>
-    <schema>
-            <solvers>
-                <component uID="ADflow">
-                    <name>pyADflow</name>
-                    <input>
-                        <parameterUID>/cpacs/toolspecific/FFD/vars/sample</parameterUID>
-                    </input>
-                    <output>
-                        <parameterUID>/cpacs/toolspecific/CFD/ADflow/evalFuncs/force/cd</parameterUID>
-                    </output>
-                    <output>
-                        <parameterUID>/cpacs/toolspecific/CFD/ADflow/evalFuncs/force/cl</parameterUID>
-                    </output>
-                    <output>
-                        <parameterUID>/cpacs/toolspecific/CFD/ADflow/evalFuncs/force/cmz</parameterUID>
-                    </output>
-                    <execute tpye="component">execute</execute>
-                </component>
-            </solvers>
-            <executeOrder>
-                <componentUID position="1">ADflow</componentUID>
-            </executeOrder>
-            <segments>
-                <process>
-                    <segment uID="Seg0">
-                        <fromComponentUID>Project</fromComponentUID>
-                        <toComponentUID>optimizer3</toComponentUID>
-                    </segment>
-                    <segment uID="Seg1">
-                        <fromComponentUID>optimizer3</fromComponentUID>
-                        <toComponentUID>FFD</toComponentUID>
-                    </segment>
-                    <segment uID="Seg2">
-                        <fromComponentUID>FFD</fromComponentUID>
-                        <toComponentUID>ADflow</toComponentUID>
-                    </segment>
-                    <segment uID="Seg3">
-                        <fromComponentUID>ADflow</fromComponentUID>
-                        <toComponentUID>optimizer3</toComponentUID>
-                    </segment>
-                </process>
-                <data>
-                    <segment uID="Seg0">
-                        <fromComponentUID>optimizer3</fromComponentUID>
-                        <toComponentUID>FFD</toComponentUID>
-                    </segment>
-                    <segment uID="Seg1">
-                        <fromComponentUID>FFD</fromComponentUID>
-                        <toComponentUID>ADflow</toComponentUID>
-                    </segment>
-                    <segment uID="Seg2">
-                        <fromComponentUID>ADflow</fromComponentUID>
-                        <toComponentUID>optimizer3</toComponentUID>
-                    </segment>
-                </data>
-            </segments>
-            <parameters>
-                <parameter uID="/cpacs/toolspecific/FFD/vars/sample">
-                    <label>localFFD</label>
-                </parameter>
-                <parameter uID="/cpacs/toolspecific/CFD/ADflow/evalFuncs/force/cd">
-                    <label>cd</label>
-                </parameter>
-                <parameter uID="/cpacs/toolspecific/CFD/ADflow/evalFuncs/force/cl">
-                    <label>cl</label>
-                </parameter>
-                <parameter uID="/cpacs/toolspecific/CFD/ADflow/evalFuncs/force/cmz">
-                    <label>cmz</label>
-                </parameter>
-            </parameters>
-        </schema>
-</opcs>

+ 0 - 95
src/main/resources/templates/workflow3.ftl

@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<opcs>
-    <header>
-        <name>SurroMDAO</name>
-        <creator>NWPU</creator>
-        <timestamp>2024-10-17T14:35:00</timestamp>
-        <version>0.1</version>
-        <opcsVersion>1.0</opcsVersion>
-    </header>
-	<schema>
-		<solvers>
-			<component uID="aeroelastic">
-				<name>pyAeroelasticADJ</name>
-				<input>
-					<parameterUID>/cpacs/toolspecific/FFD/vars/sample</parameterUID>
-				</input>
-				<input>
-					<parameterUID>/cpacs/toolspecific/CSD/TACS/material/thickness</parameterUID>
-				</input>
-				<output>
-					<parameterUID>/cpacs/toolspecific/CFD/ADflow/evalFuncs/force/cl</parameterUID>
-				</output>
-				<output>
-					<parameterUID>/cpacs/toolspecific/CFD/ADflow/evalFuncs/force/cd</parameterUID>
-				</output>
-				<output>
-					<parameterUID>/cpacs/toolspecific/CFD/ADflow/evalFuncs/force/cmy</parameterUID>
-				</output>
-				<output>
-					<parameterUID>/cpacs/toolspecific/CSD/TACS/evalFuncs/mass</parameterUID>
-				</output>
-				<output>
-					<parameterUID>/cpacs/toolspecific/CSD/TACS/evalFuncs/ks_vmfailure</parameterUID>
-				</output>
-				<execute tpye='component'>execute</execute>
-			</component>
-			<component uID="mathFunc1">
-				<name>MathFunc</name>
-				<execute tpye='component'>MathFunc</execute>
-				<input>
-					<parameterUID>/cpacs/toolspecific/CFD/ADflow/evalFuncs/force/cd</parameterUID>
-					<equationLabel>x1</equationLabel>
-				</input>
-				<input>
-					<parameterUID>/cpacs/toolspecific/CSD/TACS/evalFuncs/mass</parameterUID>
-					<equationLabel>x2</equationLabel>
-				</input>
-				<output>
-					<parameterUID>/cpacs/toolspecific/mathematical/mathFunc/cd_mass</parameterUID>
-					<equation language="Python">0.8*(x1-2.928702752230008186e-02)/2e-3+0.2*(x2-2.374579978214482253e+03)/600</equation>
-				</output>
-			</component>
-		</solvers>
-		<executeOrder>
-			<componentUID position="1">aeroelastic</componentUID>
-			<componentUID position="2">mathFunc1</componentUID>
-		</executeOrder>
-		<segments>
-            <segment uID="Seg1">
-                <fromParameterUID>/cpacs/toolspecific/FFD/vars/sample</fromParameterUID>
-                <toComponentUID>ADflow</toComponentUID>
-            </segment>
-            <segment uID="Seg2">
-                <fromComponentUID>ADflow</fromComponentUID>
-                <toParameterUID>/cpacs/toolspecific/CFD/ADflow/evalFuncs/cd</toParameterUID>
-            </segment>
-        </segments>
-        <parameters>
-            <parameter uID="/cpacs/toolspecific/FFD/vars/sample">
-                <label>FFD</label>
-            </parameter>
-			<parameter uID="/cpacs/toolspecific/CFD/ADflow/evalFuncs/force/cd">
-                <label>cd</label>
-            </parameter>
-            <parameter uID="/cpacs/toolspecific/CFD/ADflow/evalFuncs/force/cl">
-                <label>cl</label>
-            </parameter>
-			<parameter uID="/cpacs/toolspecific/CFD/ADflow/evalFuncs/force/cmy">
-                <label>cmy</label>
-            </parameter>
-			<parameter uID="/cpacs/toolspecific/CSD/TACS/evalFuncs/mass">
-                <label>mass</label>
-            </parameter>
-			<parameter uID="/cpacs/toolspecific/CSD/TACS/material/thickness">
-                <label>Thickness</label>
-            </parameter>
-			<parameter uID="/cpacs/toolspecific/CSD/TACS/evalFuncs/ks_vmfailure">
-                <label>ks_vmfailure</label>
-            </parameter>
-			<parameter uID="/cpacs/toolspecific/mathematical/mathFunc/cd_mass">
-                <label>cd_mass</label>
-            </parameter>
-        </parameters>
-	</schema>
-</opcs>

+ 15 - 0
src/test/java/com/miniframe/ApplicationTests.java

@@ -2,7 +2,9 @@ package com.miniframe;
 
 import com.miniframe.core.ext.UtilTools;
 
+import com.miniframe.tools.XIFileUtils;
 import com.miniframe.utils.MFServiceUtils;
+import es.template.TemplateGenerator;
 import freemarker.template.TemplateException;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -27,6 +29,19 @@ class ApplicationTests {
     void httpTest() throws Exception {
     }
 
+    @Test
+    void pipentXmlTest() throws Exception {
+        String pid ="2d10f389f5c04fa686eac74289180d3d";
+        XIFileUtils.mkdir(XIFileUtils.getRootPathStr());
+        XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/es");
+        XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/es/"+pid);
+        XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/es/"+pid+"/Calculate");
+        XIFileUtils.mkdir(XIFileUtils.getRootPathStr()+"/es/"+pid+"/Calculate/Geometry");//几何路径
+
+
+        TemplateGenerator.createPipenetXml(pid);
+
+    }
 
 
 }