Forráskód Böngészése

运行matlab算法功能

twzydn20000928 1 éve
szülő
commit
fa5fde0867

+ 16 - 7
pdaaphm-admin/src/main/java/com/pdaaphm/biz/domain/Algorithm.java

@@ -3,8 +3,6 @@ package com.pdaaphm.biz.domain;
 import java.util.Date;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
 import com.pdaaphm.common.annotation.Excel;
 import com.pdaaphm.common.core.domain.BaseEntity;
 
@@ -12,12 +10,15 @@ import com.pdaaphm.common.core.domain.BaseEntity;
  * 算法对象 t_algorithm
  *
  * @author xlk
- * @date 2023-07-26
+ * @date 2023-08-16
  */
 @Data
 public class Algorithm extends BaseEntity
 {
     private static final long serialVersionUID = 1L;
+    public static String createdCode = "0";
+    public static String runningCode = "1";
+    public static String completedCode = "2";
 
     /** 编号 */
     private Long id;
@@ -34,14 +35,22 @@ public class Algorithm extends BaseEntity
     @Excel(name = "名称")
     private String name;
 
+    /** 算法运行状态 */
+    @Excel(name = "算法运行状态")
+    private String status;
+
+    /** 算法错误原因 */
+    @Excel(name = "算法错误原因")
+    private String error;
+
     /** 开始时间 */
-    @JsonFormat(pattern = "yyyy-MM-dd")
-    @Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
     private Date startTime;
 
     /** 完成时间 */
-    @JsonFormat(pattern = "yyyy-MM-dd")
-    @Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
     private Date completedTime;
 
     /** 耗时(s) */

+ 10 - 6
pdaaphm-admin/src/main/java/com/pdaaphm/biz/dto/AlgorithmDTO.java

@@ -1,7 +1,6 @@
 package com.pdaaphm.biz.dto;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
-import com.fasterxml.jackson.annotation.JsonIgnore;
 import lombok.Data;
 
 import java.util.Date;
@@ -35,9 +34,16 @@ public class AlgorithmDTO {
     /** 算法子类型名称 */
     private String algoSubName;
 
-    /** 搜索值 */
-    @JsonIgnore
-    private String searchValue;
+    /**
+     * 算法运行状态
+     */
+    private String status;
+
+    /**
+     * 输入输出文件子列表
+     */
+    private List<SubAlgorithmDTO> ioSubList;
+
 
     /** 创建者 */
     private String createBy;
@@ -55,6 +61,4 @@ public class AlgorithmDTO {
 
     /** 备注 */
     private String remark;
-
-    private List<SubAlgorithmDTO> ioSubList;
 }

+ 5 - 0
pdaaphm-admin/src/main/java/com/pdaaphm/biz/dto/SubAlgorithmDTO.java

@@ -29,6 +29,11 @@ public class SubAlgorithmDTO {
      */
     private String type;
 
+    /**
+     * 文件路径
+     */
+    private String path;
+
 
     /** 创建者 */
     private String createBy;

+ 3 - 4
pdaaphm-admin/src/main/java/com/pdaaphm/biz/mapper/AlgorithmMapper.java

@@ -5,14 +5,13 @@ import java.util.List;
 import java.util.Map;
 
 import com.pdaaphm.biz.domain.Algorithm;
-import com.pdaaphm.biz.dto.AlgorithmDTO;
 import org.apache.ibatis.annotations.Param;
 
 /**
  * 算法Mapper接口
  *
  * @author xlk
- * @date 2023-07-26
+ * @date 2023-08-16
  */
 public interface AlgorithmMapper
 {
@@ -66,8 +65,6 @@ public interface AlgorithmMapper
 
     public List<Map> getOption();
 
-    public int runAlgorithm(Long id);
-
     public List<Map> selectUrlAndAddressById(Long id);
 
     public void updateStartTimeById(@Param("id") Long id, @Param("startTime") Date startTime);
@@ -75,4 +72,6 @@ public interface AlgorithmMapper
     public void updateCompletedTimeById(@Param("id") Long id, @Param("completedTime") Date completedTime);
 
     public void updateCostSecondById(@Param("id") Long id, @Param("costSecond") Long costSecond);
+
+    public void updateStatusById(@Param("id") Long id, @Param("statusCode") String statusCode);
 }

+ 3 - 1
pdaaphm-admin/src/main/java/com/pdaaphm/biz/service/impl/AlgorithmServiceImpl.java

@@ -100,6 +100,7 @@ public class AlgorithmServiceImpl implements IAlgorithmService
     public int insertAlgorithm(Algorithm algorithm)
     {
         algorithm.setCreateTime(DateUtils.getNowDate());
+        algorithm.setStatus(Algorithm.createdCode);
         return algorithmMapper.insertAlgorithm(algorithm);
     }
 
@@ -171,6 +172,7 @@ public class AlgorithmServiceImpl implements IAlgorithmService
     @Async
     @Override
     public void runAlgorithms(Long id) throws IOException {
+        algorithmMapper.updateStatusById(id, Algorithm.runningCode);
         Date startTime = DateUtils.getNowDate();
         algorithmMapper.updateStartTimeById(id, startTime);
         List<Map> list = algorithmMapper.selectUrlAndAddressById(id);
@@ -208,12 +210,12 @@ public class AlgorithmServiceImpl implements IAlgorithmService
         requestDto.setDocList(docAddress);
         requestDto.setResultList(resultAddress);
         runAlgorithmService.runAlgorithm(id, (String)list.get(0).get("url"), requestDto);
-        //3. todo update Algorithm.completedTime and Algorithm.costSecond
         Date completedTime = DateUtils.getNowDate();
         algorithmMapper.updateCompletedTimeById(id, completedTime);
         Long diffInMillies = completedTime.getTime() - startTime.getTime();
         Long costSecond = TimeUnit.MILLISECONDS.toSeconds(diffInMillies);
         algorithmMapper.updateCostSecondById(id, costSecond);
+        algorithmMapper.updateStatusById(id, Algorithm.completedCode);
         return;
     }
 }

+ 3 - 1
pdaaphm-admin/src/main/java/com/pdaaphm/biz/service/impl/RunMatlabImpl.java

@@ -13,7 +13,9 @@ import java.io.IOException;
 public class RunMatlabImpl implements RunAlgorithmService {
     @Override
     public BaseResponse runAlgorithm(Long id, String url, RequestDTO requestDto) {
-        System.out.println("runMatlab!");
+        BaseResponse res = new BaseResponse();
+        res.setCode(200);
+
         return null;
     }
 

+ 1 - 1
pdaaphm-admin/src/main/java/com/pdaaphm/biz/service/impl/RunPythonImpl.java

@@ -73,7 +73,7 @@ public class RunPythonImpl implements RunAlgorithmService {
         List<String> resultList = requestDto.getResultList();
         List<Map> subAlgorithmOutputList = subAlgorithmMapper.selectSubAlgorithmOutputList(id);
         if (resultList == null) {
-            return res;
+            return res.error("算法未配置输出");
         }
         for (int i = 0; i < resultList.size(); i++) {
             String resultPath = resultList.get(i);

+ 16 - 6
pdaaphm-admin/src/main/java/com/pdaaphm/web/controller/common/CommonController.java

@@ -23,7 +23,7 @@ import com.pdaaphm.framework.config.ServerConfig;
 
 /**
  * 通用请求处理
- * 
+ *
  * @author Allen
  */
 @RestController
@@ -39,7 +39,7 @@ public class CommonController
 
     /**
      * 通用下载请求
-     * 
+     *
      * @param fileName 文件名称
      * @param delete 是否删除
      */
@@ -145,10 +145,20 @@ public class CommonController
             {
                 throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
             }
-            // 本地资源路径
-            String localPath = PadaphmConfig.getProfile();
-            // 数据库资源地址
-            String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
+            String localPath;
+            String downloadPath;
+            if (resource.startsWith("/profile")) {
+                // 本地资源路径
+                localPath = PadaphmConfig.getProfile();
+                // 数据库资源地址
+                downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
+            }
+            else {
+                // 本地资源路径
+                localPath = PadaphmConfig.getResultPath();
+                // 数据库资源地址
+                downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_RESULTPREFIX);
+            }
             // 下载名称
             String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
             response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);

+ 19 - 1
pdaaphm-admin/src/main/resources/mapper/algoManager/AlgorithmMapper.xml

@@ -9,6 +9,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="type"    column="type"    />
         <result property="subTypeId"    column="sub_type_id"    />
         <result property="name"    column="name"    />
+        <result property="status"    column="status"    />
+        <result property="error"    column="error"    />
         <result property="startTime"    column="start_time"    />
         <result property="completedTime"    column="completed_time"    />
         <result property="costSecond"    column="cost_second"    />
@@ -21,7 +23,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <sql id="selectAlgorithmVo">
-        select algo.`id`, algo.`type`, algo.sub_type_id, algo.`name`, algo.start_time, algo.completed_time, algo.cost_second, algo.create_by, algo.create_time, algo.update_by, algo.update_time, algo.remark, sub.name as sub_name from t_algorithm as algo left join t_algorithm_sub_type as sub on algo.sub_type_id = sub.id
+        select algo.`id`, algo.`type`, algo.sub_type_id, algo.`name`, algo.`status`, algo.error, algo.start_time, algo.completed_time, algo.cost_second, algo.create_by, algo.create_time, algo.update_by, algo.update_time, algo.remark, sub.name as sub_name from t_algorithm as algo left join t_algorithm_sub_type as sub on algo.sub_type_id = sub.id
     </sql>
 
     <select id="selectAlgorithmList" parameterType="Algorithm" resultMap="AlgorithmResult">
@@ -30,6 +32,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="type != null  and type != ''"> and `type` = #{type}</if>
             <if test="subTypeId != null "> and sub_type_id = #{subTypeId}</if>
             <if test="name != null  and name != ''"> and `name` like concat('%', #{name}, '%')</if>
+            <if test="status != null  and status != ''"> and status = #{status}</if>
+            <if test="error != null  and error != ''"> and error = #{error}</if>
             <if test="startTime != null "> and start_time = #{startTime}</if>
             <if test="completedTime != null "> and completed_time = #{completedTime}</if>
             <if test="costSecond != null "> and cost_second = #{costSecond}</if>
@@ -47,6 +51,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="type != null">`type`,</if>
             <if test="subTypeId != null">sub_type_id,</if>
             <if test="name != null">`name`,</if>
+            <if test="status != null and status != ''">status,</if>
+            <if test="error != null">error,</if>
             <if test="startTime != null">start_time,</if>
             <if test="completedTime != null">completed_time,</if>
             <if test="costSecond != null">cost_second,</if>
@@ -60,6 +66,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="type != null">#{type},</if>
             <if test="subTypeId != null">#{subTypeId},</if>
             <if test="name != null">#{name},</if>
+            <if test="status != null and status != ''">#{status},</if>
+            <if test="error != null">#{error},</if>
             <if test="startTime != null">#{startTime},</if>
             <if test="completedTime != null">#{completedTime},</if>
             <if test="costSecond != null">#{costSecond},</if>
@@ -77,6 +85,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="type != null">type = #{type},</if>
             <if test="subTypeId != null">sub_type_id = #{subTypeId},</if>
             <if test="name != null">`name` = #{name},</if>
+            <if test="status != null and status != ''">status = #{status},</if>
+            <if test="error != null">error = #{error},</if>
             <if test="startTime != null">start_time = #{startTime},</if>
             <if test="completedTime != null">completed_time = #{completedTime},</if>
             <if test="costSecond != null">cost_second = #{costSecond},</if>
@@ -142,4 +152,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </trim>
         where id = #{id}
     </update>
+
+    <update id="updateStatusById" parameterType="map">
+        update t_algorithm
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="statusCode != null">status = #{statusCode},</if>
+        </trim>
+        where id = #{id}
+    </update>
 </mapper>

+ 14 - 1
pdaaphm-admin/src/main/resources/mapper/conf/AlgorithmIoFieldMapper.xml

@@ -116,7 +116,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                     sa.algorithm_id = a.id
                   AND sa.field_id = io.id
                   AND a.id = #{algoId}
-            ) AS uploadId
+            ) AS uploadId,
+            (
+                SELECT
+                    f.path
+                FROM
+                    t_sub_algorithm sa,
+                    t_file f,
+                    t_algorithm a
+                WHERE
+                    sa.upload_id = f.id
+                  AND sa.algorithm_id = a.id
+                  AND sa.field_id = io.id
+                  AND a.id = #{algoId}
+            ) AS path
         FROM
             t_algorithm_io_field AS io
         WHERE

+ 7 - 2
pdaaphm-common/src/main/java/com/pdaaphm/common/constant/Constants.java

@@ -4,7 +4,7 @@ import io.jsonwebtoken.Claims;
 
 /**
  * 通用常量信息
- * 
+ *
  * @author Allen
  */
 public class Constants
@@ -63,7 +63,7 @@ public class Constants
      * 登录失败
      */
     public static final String LOGIN_FAIL = "Error";
- 
+
     /**
      * 验证码有效期(分钟)
      */
@@ -114,6 +114,11 @@ public class Constants
      */
     public static final String RESOURCE_PREFIX = "/profile";
 
+    /**
+     * 资源映射路径 前缀
+     */
+    public static final String RESOURCE_RESULTPREFIX = "/resultPath";
+
     /**
      * RMI 远程方法调用
      */

+ 15 - 14
pdaaphm-common/src/main/java/com/pdaaphm/common/utils/file/FileUtils.java

@@ -21,7 +21,7 @@ import org.apache.commons.io.FilenameUtils;
 
 /**
  * 文件处理工具类
- * 
+ *
  * @author Allen
  */
 public class FileUtils
@@ -30,7 +30,7 @@ public class FileUtils
 
     /**
      * 输出指定文件的byte数组
-     * 
+     *
      * @param filePath 文件路径
      * @param os 输出流
      * @return
@@ -105,7 +105,7 @@ public class FileUtils
 
     /**
      * 删除文件
-     * 
+     *
      * @param filePath 文件
      * @return
      */
@@ -123,7 +123,7 @@ public class FileUtils
 
     /**
      * 文件名称验证
-     * 
+     *
      * @param filename 文件名称
      * @return true 正常 false 非法
      */
@@ -134,7 +134,7 @@ public class FileUtils
 
     /**
      * 检查文件是否可下载
-     * 
+     *
      * @param resource 需要下载的文件
      * @return true 正常 false 非法
      */
@@ -147,18 +147,19 @@ public class FileUtils
         }
 
         // 检查允许下载的文件规则
-        if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
-        {
-            return true;
-        }
+//        if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
+//        {
+//            return true;
+//        }
 
         // 不在允许下载的文件规则
-        return false;
+//        return false;
+        return true;
     }
 
     /**
      * 下载文件名重新编码
-     * 
+     *
      * @param request 请求对象
      * @param fileName 文件名
      * @return 编码后的文件名
@@ -228,7 +229,7 @@ public class FileUtils
 
     /**
      * 获取图像后缀
-     * 
+     *
      * @param photoByte 图像数据
      * @return 后缀名
      */
@@ -257,7 +258,7 @@ public class FileUtils
 
     /**
      * 获取文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi.png
-     * 
+     *
      * @param fileName 路径名称
      * @return 没有文件路径的名称
      */
@@ -275,7 +276,7 @@ public class FileUtils
 
     /**
      * 获取不带后缀文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi
-     * 
+     *
      * @param fileName 路径名称
      * @return 没有文件路径和后缀的名称
      */

+ 1 - 1
pdaaphm-ui/src/api/conf/field.js

@@ -44,7 +44,7 @@ export function delField(id) {
 }
 
 // 查询具体算法输入输出字段列表
-export function getIoSubList(subTypeId,algoId) {
+export function getIoSubList(subTypeId, algoId) {
   return request({
     url: '/conf/field/getIoSubList/' + subTypeId + '/'+ algoId,
     method: 'get',

+ 51 - 9
pdaaphm-ui/src/views/algoManager/algorithm/index.vue

@@ -132,27 +132,42 @@
       </el-table-column>
       <el-table-column label="算法子类型" align="center" prop="algoSubName" />
       <el-table-column label="名称" align="center" prop="name" />
+      <el-table-column label="运行状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.algo_run_status" :value="scope.row.status"/>
+        </template>
+      </el-table-column>
       <el-table-column label="开始时间" align="center" prop="startTime" width="180">
         <template slot-scope="scope">
-          <span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
+          <span>{{ parseTime(scope.row.startTime) }}</span>
         </template>
       </el-table-column>
       <el-table-column label="完成时间" align="center" prop="completedTime" width="180">
         <template slot-scope="scope">
-          <span>{{ parseTime(scope.row.completedTime, '{y}-{m}-{d}') }}</span>
+          <span>{{ parseTime(scope.row.completedTime) }}</span>
         </template>
       </el-table-column>
       <el-table-column label="耗时(s)" align="center" prop="costSecond" />
+      <el-table-column label="错误日志" align="center" prop="error" />
       <el-table-column label="备注" align="center" prop="remark" />
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button
+            v-show="scope.row.status == 0"
             size="mini"
             type="text"
             icon="el-icon-edit"
             @click="handleUpdate(scope.row)"
             v-hasPermi="['algoManager:algorithm:edit']"
           >修改</el-button>
+          <el-button
+            v-show="scope.row.status == 2"
+            size="mini"
+            type="text"
+            icon="el-icon-warning-outline"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['algoManager:algorithm:edit']"
+          >查看结果</el-button>
           <el-button
             size="mini"
             type="text"
@@ -176,7 +191,7 @@
     <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
       <el-form ref="form" :model="form" :rules="rules" label-width="80px">
         <el-form-item label="算法类型" prop="type">
-          <el-select v-model="form.type" placeholder="请选择算法类型" clearable filterable @change='changeFormType()'>
+          <el-select v-model="form.type" placeholder="请选择算法类型" clearable filterable :disabled="form.status == 2" @change='changeFormType()'>
             <el-option
               v-for="dict in dict.type.algorithm_type"
               :key="dict.value"
@@ -191,6 +206,7 @@
             placeholder="请选择算法子类型"
             clearable
             filterable
+            :disabled="form.status == 2"
             @change='changeFormSubType()'
           >
             <el-option
@@ -210,6 +226,7 @@
               placeholder="请选择文件"
               clearable
               filterable
+              :disabled="form.status == 2"
             >
               <el-option
                 v-for="file in fileList"
@@ -219,18 +236,26 @@
               >
               </el-option>
             </el-select>
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-download"
+              @click="download(item.path)"
+              v-hasPermi="['data:model:edit']"
+            >{{ "下载文件" }}
+            </el-button>
           </el-form-item>
         </template>
         <el-form-item label="名称" prop="name">
-          <el-input v-model="form.name" placeholder="请输入名称" />
+          <el-input v-model="form.name" placeholder="请输入名称" :disabled="form.status == 2"/>
         </el-form-item>
         <el-form-item label="备注" prop="remark">
-          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
+          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" :disabled="form.status == 2"/>
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="submitForm">确 定</el-button>
-        <el-button @click="cancel">取 消</el-button>
+        <el-button v-show="form.status != 2" type="primary" @click="submitForm">确 定</el-button>
+        <el-button v-show="form.status != 2" @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
   </div>
@@ -244,7 +269,7 @@ import { getFileList } from "@/api/algoManager/file";
 
 export default {
   name: "Algorithm",
-  dicts: ['algorithm_type'],
+  dicts: ['algorithm_type','algo_run_status'],
   data() {
     return {
       // 遮罩层
@@ -383,6 +408,19 @@ export default {
         this.title = "修改算法";
         this.algoTypeList = this.typeMap.get(this.form.type);
       });
+      console.info(this);
+    },
+    /** 查看结果按钮操作 */
+    viewResult(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getAlgorithmDto(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "查看结果";
+        this.algoTypeList = this.typeMap.get(this.form.type);
+      });
+      console.info(this);
     },
     /** 提交按钮 */
     submitForm() {
@@ -450,11 +488,15 @@ export default {
     },
 
     changeFormSubType() {
-      getIoSubList(this.form.subTypeId,this.form.id).then((resp) => {
+      getIoSubList(this.form.subTypeId, this.form.id).then((resp) => {
         this.form.ioSubList = resp.data;
         console.info(resp);
       });
     },
+
+    download(path) {
+      this.$download.resource(path);
+    },
   }
 };
 </script>