Sfoglia il codice sorgente

Merge branch 'master' of http://39.98.38.2:13000/dumingliang/sh-model-platform

nanjingliujinyu 4 mesi fa
parent
commit
55f2dc1aa5
39 ha cambiato i file con 1868 aggiunte e 1258 eliminazioni
  1. 65 17
      ruoyi-admin/src/test/java/com/ruoyi/TinyflowTest.java
  2. 9 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/GatewayRoutesController.java
  3. 19 21
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/PtAppController.java
  4. 24 2
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/PtServiceMonitorController.java
  5. 8 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/PtApp.java
  6. 4 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/PtServiceLog.java
  7. 2 16
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/mapper/PtAppMapper.java
  8. 6 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/mapper/PtServiceMonitorMapper.java
  9. 7 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/IPtServiceMonitorService.java
  10. 2 20
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/PtAppService.java
  11. 0 13
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/PtServiceService.java
  12. 2 2
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/InterfaceAuthServiceImpl.java
  13. 1 1
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/InterfaceTokenServiceImpl.java
  14. 9 64
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/PtAppServiceImpl.java
  15. 4 4
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/PtServiceApplyServiceImpl.java
  16. 35 2
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/PtServiceMonitorServiceImpl.java
  17. 19 34
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/PtServiceServiceImpl.java
  18. 1 1
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/ServiceDataViewServiceImpl.java
  19. 1 1
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/TokenServiceImpl.java
  20. 1 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/snailJob/TestJob.java
  21. 34 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/snailJob/flowJob.java
  22. 14 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/TinyflowUtil.java
  23. 15 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/node/PrintNode.java
  24. 76 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/node/ServiceNode.java
  25. 22 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/parser/ServiceNodeParser.java
  26. 0 247
      ruoyi-api-patform/src/main/resources/mapper/interfaces/PtAppMapper.xml
  27. 59 10
      ruoyi-api-patform/src/main/resources/mapper/interfaces/PtServiceMonitorMapper.xml
  28. 1 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java
  29. 0 18
      ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java
  30. 1 1
      ruoyi-ui/.env.development
  31. 2 0
      ruoyi-ui/package.json
  32. 10 1
      ruoyi-ui/src/api/gateway/gatewayRouters.js
  33. 23 1
      ruoyi-ui/src/api/monitor/server.js
  34. 55 0
      ruoyi-ui/src/api/service/app.js
  35. 362 97
      ruoyi-ui/src/views/monitor/service/index.vue
  36. 220 0
      ruoyi-ui/src/views/service/app/index.vue
  37. 4 4
      ruoyi-ui/src/views/service/gateway/index.vue
  38. 734 679
      ruoyi-ui/src/views/service/info/editModel.vue
  39. 17 2
      ruoyi-ui/src/views/service/log/index.vue

+ 65 - 17
ruoyi-admin/src/test/java/com/ruoyi/TinyflowTest.java

@@ -11,6 +11,7 @@ import com.agentsflex.core.chain.listener.ChainEventListener;
 import com.agentsflex.core.chain.listener.ChainOutputListener;
 import com.agentsflex.llm.openai.OpenAILlm;
 import com.ruoyi.interfaces.tinyflow.parser.PrintNodeParser;
+import com.ruoyi.interfaces.tinyflow.parser.ServiceNodeParser;
 import dev.tinyflow.core.Tinyflow;
 
 import java.util.HashMap;
@@ -31,7 +32,7 @@ public class TinyflowTest {
             "                \"expand\": true,\n" +
             "                \"parameters\": [\n" +
             "                    {\n" +
-            "                        \"name\": \"inputParam1\",\n" +
+            "                        \"name\": \"year\",\n" +
             "                        \"dataType\": \"String\",\n" +
             "                        \"refType\": \"input\",\n" +
             "                        \"required\": true,\n" +
@@ -60,25 +61,71 @@ public class TinyflowTest {
             "        {\n" +
             "            \"id\": \"2\",\n" +
             "            \"data\": {\n" +
-            "                \"title\": \"打印节点\",\n" +
+            "                \"title\": \"服务节点\",\n" +
             "                \"parameters\": [\n" +
             "                    {\n" +
-            "                        \"name\": \"message\",\n" +
-            "                        \"value\": \"Hello value\",\n" +
+            "                        \"name\": \"year\",\n" +
             "                        \"dataType\": \"String\",\n" +
-            "                        \"defaultValue\": \"Hello defaultValue\",\n" +
-            "                        \"refType\": \"fixed\"\n" +
-            "                    },\n" +
-            "                    {\n" +
-            "                        \"name\": \"input1\",\n" +
-            "                        \"dataType\": \"String\",\n" +
-            "                        \"defaultValue\": \"Hello defaultValue\",\n" +
-            "                        \"ref\": \"1.inputParam1\",\n" +
+            "                        \"ref\": \"1.year\",\n" +
             "                        \"refType\": \"ref\"\n" +
             "                    }\n" +
-            "                ]\n" +
+            "                ],\n" +
+            "                \"service\": {\n" +
+            "                    \"srvId\": \"634ae1e0ee78e00bd609b85514961373\",\n" +
+            "                    \"mdid\": \"e4dc50dd-c4a9-4639-b43e-62e48314a7e0\",\n" +
+            "                    \"cateCode\": \"S\",\n" +
+            "                    \"name\": \"获取台风信息列表\",\n" +
+            "                    \"intro\": \"获取有台风的编号及名称\",\n" +
+            "                    \"serviceSource\": null,\n" +
+            "                    \"serviceDept\": null,\n" +
+            "                    \"manageName\": null,\n" +
+            "                    \"developUnit\": null,\n" +
+            "                    \"developContacter\": null,\n" +
+            "                    \"maintainUnit\": null,\n" +
+            "                    \"maintainContacer\": null,\n" +
+            "                    \"upCycl\": null,\n" +
+            "                    \"openCndtn\": null,\n" +
+            "                    \"adName\": null,\n" +
+            "                    \"dataField\": null,\n" +
+            "                    \"dataRange\": null,\n" +
+            "                    \"userId\": null,\n" +
+            "                    \"status\": null,\n" +
+            "                    \"note\": null,\n" +
+            "                    \"type\": \"HTTP\",\n" +
+            "                    \"url\": \"http://49.4.2.185:2111/RiverStrongAPI2.0/StormSurgeForecast/Typhoon/GetInfos\",\n" +
+            "                    \"rqtype\": \"POST\",\n" +
+            "                    \"rptype\": \"1\",\n" +
+            "                    \"rpcontent\": \"{\\n  \\\"data\\\": [\\n        {\\n            \\\"typhoonId\\\": \\\"202317\\\",\\n            \\\"typhoonName\\\": \\\"杰拉华\\\",\\n           \\\"test\\\": \\\"1123\\\"\\n        },\\n        {\\n            \\\"typhoonId\\\": \\\"202316\\\",\\n            \\\"typhoonName\\\": \\\"三巴\\\",\\n           \\\"test\\\": \\\"1123\\\"\\n           \\n        }\\n    ],\\n    \\\"succeeded\\\": true,\\n    \\\"statusCode\\\": 200,\\n    \\\"remark\\\": \\\"获取该年台风信息成功\\\"\\n}\",\n" +
+            "                    \"proxyAddress\": null,\n" +
+            "                    \"proxyPath\": null,\n" +
+            "                    \"example\": \"\",\n" +
+            "                    \"cnt\": null,\n" +
+            "                    \"viewNum\": 0,\n" +
+            "                    \"applyNum\": null,\n" +
+            "                    \"dataNum\": null,\n" +
+            "                    \"tm\": null,\n" +
+            "                    \"uptm\": null,\n" +
+            "                    \"rlstm\": null,\n" +
+            "                    \"releaseTime\": null,\n" +
+            "                    \"attentionId\": null,\n" +
+            "                    \"params\": [\n" +
+            "                        {\n" +
+            "                            \"srvId\": \"634ae1e0ee78e00bd609b85514961373\",\n" +
+            "                            \"paramCode\": \"year\",\n" +
+            "                            \"paramName\": \"年份\",\n" +
+            "                            \"paramType\": \"int\",\n" +
+            "                            \"paramValue\": \"2023\",\n" +
+            "                            \"paramFormat\": null,\n" +
+            "                            \"paramNote\": \"\",\n" +
+            "                            \"sort\": 0,\n" +
+            "                            \"paramObject\": 2023\n" +
+            "                        }\n" +
+            "                    ],\n" +
+            "                    \"sort\": null,\n" +
+            "                    \"audit\": null\n" +
+            "                }\n" +
             "            },\n" +
-            "            \"type\": \"printNode\",\n" +
+            "            \"type\": \"serviceNode\",\n" +
             "            \"position\": {\n" +
             "                \"x\": 600,\n" +
             "                \"y\": 50\n" +
@@ -99,8 +146,8 @@ public class TinyflowTest {
             "                \"outputDefs\": [\n" +
             "                    {\n" +
             "                        \"name\": \"data\",\n" +
-            "                        \"dataType\": \"String\",\n" +
-            "                        \"ref\": \"2.msg\",\n" +
+            "                        \"dataType\": \"Object\",\n" +
+            "                        \"ref\": \"2.result\",\n" +
             "                        \"refType\": \"ref\"\n" +
             "                    }\n" +
             "                ]\n" +
@@ -150,10 +197,11 @@ public class TinyflowTest {
         System.out.println(data1);
         Tinyflow tinyflow = new Tinyflow(data1);
         tinyflow.getChainParser().addNodeParser("printNode",new PrintNodeParser());
+        tinyflow.getChainParser().addNodeParser("serviceNode",new ServiceNodeParser());
 //        tinyflow.setLlmProvider(id -> OpenAILlm.of(""));
 
         Map<String, Object> variables = new HashMap<>();
-        variables.put("inputParam1", "开始节点引入1");
+        variables.put("year", "2024");
         variables.put("inputParam2", 2);
 
         Chain chain = tinyflow.toChain();

+ 9 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/GatewayRoutesController.java

@@ -62,4 +62,13 @@ public class GatewayRoutesController extends BaseController {
         return getDataTable(list);
     }
 
+    @ApiOperation("获取所有可用路由数据")
+    @GetMapping(value = "/list")
+    public AjaxResult list(GatewayRoutes gatewayRoutes) {
+        QueryWrapper<GatewayRoutes> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("status", "0")
+                .like(StringUtils.isNotBlank(gatewayRoutes.getServiceName()), "service_name", gatewayRoutes.getServiceName());
+        return AjaxResult.success(gatewayRoutesService.list(queryWrapper));
+    }
+
 }

+ 19 - 21
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/PtAppController.java

@@ -1,17 +1,17 @@
 package com.ruoyi.interfaces.controller;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.interfaces.core.page.Page;
-import com.ruoyi.interfaces.core.page.PageParam;
+import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.interfaces.domain.PtApp;
 import com.ruoyi.interfaces.service.PtAppService;
 import io.swagger.annotations.ApiOperation;
 import org.apache.commons.lang3.StringUtils;
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.Arrays;
 import java.util.Optional;
 
 @RestController
@@ -25,41 +25,39 @@ public class PtAppController extends BaseController {
     @PostMapping(value = "/add")
     public AjaxResult add(@RequestBody PtApp ptApp) {
         ptApp.setUserId(String.valueOf(getUserId()));
-        return AjaxResult.check(ptAppService.insert(ptApp) > 0);
+        return AjaxResult.check(ptAppService.save(ptApp));
     }
 
     @ApiOperation("修改应用")
     @PostMapping(value = "/update")
     public AjaxResult update(@RequestBody PtApp ptApp) {
-        return AjaxResult.check(ptAppService.update(ptApp) > 0);
+        return AjaxResult.check(ptAppService.updateById(ptApp));
     }
 
     @ApiOperation("删除应用")
     @GetMapping(value = "/delete")
     public AjaxResult deletes(String keys) {
-        return AjaxResult.check(ptAppService.del(keys));
+        return AjaxResult.check(ptAppService.removeBatchByIds(Arrays.asList(keys.split(","))));
     }
 
     @ApiOperation("查询所有应用")
-    @PostMapping(value = "/list")
-    public Page list(@RequestBody PageParam<PtApp> ptAppPageParam) {
-        ptAppPageParam.setData(Optional.of(ptAppPageParam).map(PageParam::getData).orElse(new PtApp()));
-        ptAppPageParam.getData().setUserId(String.valueOf(getUserId()));
-        Optional.of(ptAppPageParam.getData())
-                .map(PtApp::getAppName)
-                .filter(StringUtils::isNotBlank)
-                .ifPresent(appName -> ptAppPageParam.getData().setAppName(appName.trim()));
-        return ptAppService.listOfPage(ptAppPageParam);
+    @GetMapping(value = "/list")
+    public TableDataInfo list(PtApp ptApp) {
+        QueryWrapper<PtApp> queryWrapper = new QueryWrapper<>();
+        queryWrapper
+                .eq("user_id", getUserId())
+                .like(StringUtils.isNotBlank(ptApp.getAppName()), "app_name", ptApp.getAppName());
+        startPage();
+        return getDataTable(ptAppService.list(queryWrapper));
     }
 
     @ApiOperation("查询所有应用")
     @PostMapping(value = "/lists")
     public AjaxResult lists(PtApp ptApp) {
-        ptApp.setUserId(String.valueOf(getUserId()));
-        Optional.of(ptApp)
-                .map(PtApp::getAppName)
-                .filter(StringUtils::isNotBlank)
-                .ifPresent(appName -> ptApp.setAppName(appName.trim()));
-        return AjaxResult.success(ptAppService.list(ptApp));
+        QueryWrapper<PtApp> queryWrapper = new QueryWrapper<>();
+        queryWrapper
+                .eq("user_id", getUserId())
+                .like(StringUtils.isNotBlank(ptApp.getAppName()), "app_name", ptApp.getAppName());
+        return AjaxResult.success(ptAppService.list(queryWrapper));
     }
 }

+ 24 - 2
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/PtServiceMonitorController.java

@@ -79,8 +79,30 @@ public class PtServiceMonitorController extends BaseController {
      * 模型类型服务调度次数
      */
     @GetMapping("/getModelTypeCallCount")
-    public AjaxResult getModelTypeCallCount() {
-        return AjaxResult.success(monitorService.getModelTypeCallCount(null));
+    public AjaxResult getModelTypeCallCount(String startTime, String endTime) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("startTime", startTime);
+        params.put("endTime", endTime);
+        return AjaxResult.success(monitorService.getModelTypeCallCount(params));
+    }
+
+    /**
+     * 模型服务统计
+     */
+    @GetMapping("/getModelServiceCount")
+    public AjaxResult getModelServiceCount() {
+        return AjaxResult.success(monitorService.getModelServiceCount());
+    }
+
+/**
+     * 模型服务统计
+     */
+    @GetMapping("/getModelServiceSuccessCount")
+    public AjaxResult getModelServiceSuccessCount(String startTime, String endTime) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("startTime", startTime);
+        params.put("endTime", endTime);
+        return AjaxResult.success(monitorService.getModelServiceSuccessCount(params));
     }
 
 }

+ 8 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/PtApp.java

@@ -1,5 +1,8 @@
 package com.ruoyi.interfaces.domain;
 
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -8,8 +11,11 @@ import java.io.Serializable;
 import java.util.Date;
 
 @Data
+@TableName
 public class PtApp implements Serializable {
+
     @ApiModelProperty("appId")
+    @TableId
     private String appId;
     @ApiModelProperty("应用名称")
     private String appName;
@@ -18,6 +24,7 @@ public class PtApp implements Serializable {
     @ApiModelProperty("应用地址")
     private String appUrl;
     @ApiModelProperty("应用方法")
+    @TableField(exist = false)
     private String appMethod;
     @ApiModelProperty("应用开发商")
     private String appDeveloper;
@@ -38,6 +45,7 @@ public class PtApp implements Serializable {
     private String appToken;
     @ApiModelProperty("用户ID")
     private String userId;
+    @TableField(exist = false)
     @ApiModelProperty("时效时间")
     private Long expireTime;
     @ApiModelProperty("应用类型")

+ 4 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/PtServiceLog.java

@@ -44,6 +44,10 @@ public class PtServiceLog extends BaseEntity
     @Excel(name = "请求时间戳", width = 30, dateFormat = "yyyy-MM-dd hh:mm:ss")
     private Date tm;
 
+    /** 请求地址 */
+    @Excel(name = "请求地址")
+    private String url;
+
     /** 请求信息 */
     @Excel(name = "请求信息")
     private String senText;

+ 2 - 16
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/mapper/PtAppMapper.java

@@ -1,6 +1,7 @@
 package com.ruoyi.interfaces.mapper;
 
 
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.ruoyi.interfaces.domain.PtApp;
 import org.apache.ibatis.annotations.Param;
 import org.springframework.stereotype.Repository;
@@ -8,21 +9,6 @@ import org.springframework.stereotype.Repository;
 import java.util.List;
 
 @Repository
-public interface PtAppMapper {
+public interface PtAppMapper extends BaseMapper<PtApp> {
 
-    int deleteByPrimaryKey(String appId);
-
-    int insert(PtApp record);
-
-    int insertSelective(PtApp record);
-
-    PtApp selectByPrimaryKey(String appId);
-
-    int updateByPrimaryKeySelective(PtApp record);
-
-    int updateByPrimaryKey(PtApp record);
-
-    List<PtApp> selectAll(PtApp ptApp);
-
-    List<PtApp> listByIds(@Param("ids") String[] ids);
 }

+ 6 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/mapper/PtServiceMonitorMapper.java

@@ -13,4 +13,10 @@ public interface PtServiceMonitorMapper {
 
     List<Map<String, Object>> getModelTypeCallCount(Map<String, Object> params);
 
+    List<Map<String, Object>> getMonthModelCallMaxCount();
+
+    List<Map<String, Object>> getModelServiceCount();
+
+    List<Map<String, Object>> getModelServiceSuccessCount(Map<String, Object> params);
+
 }

+ 7 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/IPtServiceMonitorService.java

@@ -22,4 +22,11 @@ public interface IPtServiceMonitorService {
 
     List<Map<String, Object>> getModelTypeCallCount(Map<String, Object> params);
 
+    List<Map<String, Object>> getMonthModelCallMaxCount();
+
+
+    List<Map<String, Object>> getModelServiceCount();
+
+    List<Map<String, Object>> getModelServiceSuccessCount(Map<String, Object> params);
+
 }

+ 2 - 20
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/PtAppService.java

@@ -1,5 +1,6 @@
 package com.ruoyi.interfaces.service;
 
+import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.interfaces.core.page.Page;
 import com.ruoyi.interfaces.core.page.PageParam;
 import com.ruoyi.interfaces.domain.PtApp;
@@ -10,25 +11,6 @@ import java.util.List;
  * @author LinQiLong
  * @date 2022/1/7 10:20
  */
-public interface PtAppService {
+public interface PtAppService extends IService<PtApp> {
 
-    int insert(PtApp ptApp);
-
-    int update(PtApp ptApp);
-
-    boolean del(String keys);
-
-    PtApp get(String key);
-
-    Page listOfPage(PageParam<PtApp> ptAppPageParam);
-
-    List<PtApp> list(PtApp ptApp);
-
-    /**
-     * 筛选 ID 数组获取 PtApp
-     *
-     * @param ids 应用ID
-     * @return 应用列表
-     */
-    List<PtApp> listByIds(String[] ids);
 }

+ 0 - 13
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/PtServiceService.java

@@ -15,17 +15,6 @@ import java.util.Map;
  */
 public interface PtServiceService extends IService<PtService> {
 
-    /**
-     * 保存服务信息
-     * @param ptService 服务信息
-     * @return 服务
-     */
-//    PtService save(PtService ptService);
-
-    PtService insert(PtService ptService);
-
-    PtService update(PtService ptService);
-
     /**
      * @return 申请数量Top10的数据
      */
@@ -46,8 +35,6 @@ public interface PtServiceService extends IService<PtService> {
      */
     Map<String, List<PtService>> getRankingList();
 
-    PtService get(String srvId);
-
     MdModelInfoVo modelService(MdModelInfoVo par);
 
     List<PtService> selectAllColumns(PtService ptService);

+ 2 - 2
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/InterfaceAuthServiceImpl.java

@@ -37,7 +37,7 @@ public class InterfaceAuthServiceImpl implements InterfaceAuthService {
     @Override
     public Map<String, Object> authCheck(String srvId, String token) {
         Map<String, Object> ret = new HashMap<>(3);
-        PtService ptService = ptServiceService.get(srvId);
+        PtService ptService = ptServiceService.getById(srvId);
         if (ptService == null) {
             ret.put("status", false);
             ret.put("code", 4001);
@@ -121,7 +121,7 @@ public class InterfaceAuthServiceImpl implements InterfaceAuthService {
         PtService service = new PtService();
         service.setSrvId(ptService.getSrvId());
         service.setCnt(ptService.getCnt() + 1);
-        ptServiceService.update(service);
+        ptServiceService.updateById(service);
     }
 
     /**

+ 1 - 1
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/InterfaceTokenServiceImpl.java

@@ -67,7 +67,7 @@ public class InterfaceTokenServiceImpl implements InterfaceTokenService {
 
     @Override
     public Map<String, Object> token(String grantType, String appId, String secret) {
-        PtApp ptApp = ptAppService.get(appId);
+        PtApp ptApp = ptAppService.getById(appId);
         if (ptApp == null) {
             return failResponse(TokenError.APPID_ERR);
         } else if (!Optional.of(ptApp).map(PtApp::getAppSecret).isPresent() ||

+ 9 - 64
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/PtAppServiceImpl.java

@@ -1,85 +1,30 @@
 package com.ruoyi.interfaces.service.impl;
 
-import com.github.pagehelper.PageHelper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.utils.CheckUtils;
-import com.ruoyi.interfaces.core.page.Page;
-import com.ruoyi.interfaces.core.page.PageParam;
-import com.ruoyi.interfaces.core.page.PageUtils;
+import com.ruoyi.common.utils.uuid.UUID;
 import com.ruoyi.interfaces.domain.PtApp;
 import com.ruoyi.interfaces.mapper.PtAppMapper;
 import com.ruoyi.interfaces.service.PtAppService;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 
-import java.util.Date;
-import java.util.List;
-import java.util.UUID;
-
 /**
  * @author LinQiLong
  * @date 2022/1/7 10:20
  */
 @Service
-public class PtAppServiceImpl implements PtAppService {
-
-    private final PtAppMapper ptAppMapper;
-
-    public PtAppServiceImpl(PtAppMapper ptAppMapper) {
-        this.ptAppMapper = ptAppMapper;
-    }
-
-    @Override
-    public int insert(PtApp ptApp) {
-//        ptApp.setAppId(UuidUtil.uuid());
-//        ptApp.setAppSecret(UUID.randomUUID().toString().replace("-", ""));
-//        Date date = new Date();
-//        ptApp.setAppPublish(date);
-//        ptApp.setAuditTime(date);
-//        ptApp.setRqTime(date);
-        return ptAppMapper.insert(ptApp);
-    }
-
-    @Override
-    public int update(PtApp ptApp) {
-        CheckUtils.notEmpty(ptApp.getAppId(), "appId.no");
-        return ptAppMapper.updateByPrimaryKeySelective(ptApp);
-    }
+public class PtAppServiceImpl extends ServiceImpl<PtAppMapper, PtApp> implements PtAppService {
 
     @Override
-    public boolean del(String keys) {
-        if (StringUtils.isBlank(keys)) {
-            return false;
-        }
-        String[] strs = keys.split(",");
-        int deletes = 0;
-        for (String str : strs) {
-            deletes += ptAppMapper.deleteByPrimaryKey(str);
-        }
-        return deletes == strs.length;
+    public boolean save(PtApp entity) {
+        entity.setAppSecret(UUID.randomUUID().toString());
+        return super.save(entity);
     }
 
     @Override
-    public PtApp get(String key) {
-        return ptAppMapper.selectByPrimaryKey(key);
+    public boolean updateById(PtApp entity) {
+        CheckUtils.notEmpty(entity.getAppId(), "appId.no");
+        return super.updateById(entity);
     }
 
-    @Override
-    public Page listOfPage(PageParam<PtApp> ptAppPageParam) {
-        PageHelper.startPage(ptAppPageParam);
-        List<PtApp> list = list(ptAppPageParam.getData());
-        return PageUtils.convert(list);
-    }
-
-    @Override
-    public List<PtApp> list(PtApp ptApp) {
-        return ptAppMapper.selectAll(ptApp);
-    }
-
-    @Override
-    public List<PtApp> listByIds(String[] ids) {
-        if (ids == null || ids.length == 0) {
-            return null;
-        }
-        return ptAppMapper.listByIds(ids);
-    }
 }

+ 4 - 4
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/PtServiceApplyServiceImpl.java

@@ -84,12 +84,12 @@ public class PtServiceApplyServiceImpl implements PtServiceApplyService {
      * @param srvId 服务ID
      */
     private void updateApplyNum(String srvId) {
-        PtService service = ptSrvService.get(srvId);
+        PtService service = ptSrvService.getById(srvId);
         Optional.ofNullable(service).ifPresent(s -> {
             PtService ptService = new PtService();
             ptService.setSrvId(s.getSrvId());
             ptService.setApplyNum(s.getApplyNum() + 1);
-            ptSrvService.update(ptService);
+            ptSrvService.updateById(ptService);
         });
 
     }
@@ -121,7 +121,7 @@ public class PtServiceApplyServiceImpl implements PtServiceApplyService {
             BeanUtils.copyProperties(apply, vo);
             Optional.of(apply).map(PtServiceApply::getAppId).ifPresent(appId -> {
                 vo.setAppIdArray(appId.split(","));
-                List<PtApp> appList = ptAppService.listByIds(vo.getAppIdArray());
+                List<PtApp> appList = ptAppService.listByIds(Arrays.asList(vo.getAppIdArray()));
                 if (CollectionUtils.isNotEmpty(appList)) {
                     vo.setAppName(
                             appList.stream()
@@ -175,7 +175,7 @@ public class PtServiceApplyServiceImpl implements PtServiceApplyService {
         BeanUtils.copyProperties(apply, vo);
         Optional.of(apply).map(PtServiceApply::getAppId).ifPresent(appId -> {
             vo.setAppIdArray(appId.split(","));
-            List<PtApp> appList = ptAppService.listByIds(vo.getAppIdArray());
+            List<PtApp> appList = ptAppService.listByIds(Arrays.asList(vo.getAppIdArray()));
             if (CollectionUtils.isNotEmpty(appList)) {
                 vo.setAppName(
                         appList.stream()

+ 35 - 2
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/PtServiceMonitorServiceImpl.java

@@ -3,6 +3,7 @@ package com.ruoyi.interfaces.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.ruoyi.common.core.builder.MapBuilder;
 import com.ruoyi.interfaces.domain.PtService;
+import com.ruoyi.interfaces.domain.PtServiceLog;
 import com.ruoyi.interfaces.mapper.PtServiceMonitorMapper;
 import com.ruoyi.interfaces.service.IPtServiceLogService;
 import com.ruoyi.interfaces.service.IPtServiceMonitorService;
@@ -17,6 +18,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Service
@@ -43,9 +45,24 @@ public class PtServiceMonitorServiceImpl implements IPtServiceMonitorService {
         BigDecimal result = new BigDecimal(count).multiply(new BigDecimal(100)).divide(new BigDecimal(total), 2, RoundingMode.HALF_UP);
         statisticData.add(MapBuilder.of("name", "服务在线比率", "value", result.setScale(1, RoundingMode.HALF_UP) + "%", "color", "#40B0D7"));
         // TODO: 模型服务支撑健康指数
-        statisticData.add(MapBuilder.of("name", "模型服务支撑健康指数", "value", "良", "color", "#2DBEA2"));
+        QueryWrapper<PtServiceLog> logWrapper = new QueryWrapper<>();
+        logWrapper.eq("status_code", "200");
+        long goodCount = ptServiceLogService.count(logWrapper);
+        long logTotal = ptServiceLogService.count();
+        BigDecimal logResult = new BigDecimal(goodCount).multiply(new BigDecimal(100)).divide(new BigDecimal(logTotal), 2, RoundingMode.HALF_UP);
+        String index = "优";
+        if (logResult.compareTo(new BigDecimal(90)) < 0) {
+            index = "差";
+        } else if (logResult.compareTo(new BigDecimal(95)) < 0) {
+            index = "良";
+        } else {
+            index = "优";
+        }
+        statisticData.add(MapBuilder.of("name", "模型服务支撑健康指数", "value", index, "color", "#2DBEA2"));
         // TODO: 当月热点服务
-        statisticData.add(MapBuilder.of("name", "当月热点服务", "value", "新安江模型", "color", "#487ACF"));
+        List<Map<String, Object>> monthModelCallMaxCount = getMonthModelCallMaxCount();
+        String monthModelCallMaxCountName = monthModelCallMaxCount.stream().map(item -> (String) item.get("NAME")).collect(Collectors.joining(","));
+        statisticData.add(MapBuilder.of("name", "当月热点服务", "value", monthModelCallMaxCountName, "color", "#487ACF"));
         long totalLogCount = ptServiceLogService.count();
         statisticData.add(MapBuilder.of("name", "累计调用次数", "value", totalLogCount, "color", "#4BBA9B"));
         return statisticData;
@@ -72,5 +89,21 @@ public class PtServiceMonitorServiceImpl implements IPtServiceMonitorService {
         return ptServiceMonitorMapper.getModelTypeCallCount(params);
     }
 
+    @Override
+    public List<Map<String, Object>> getMonthModelCallMaxCount() {
+        return ptServiceMonitorMapper.getMonthModelCallMaxCount();
+    }
+
+    @Override
+    public List<Map<String, Object>> getModelServiceCount() {
+        return ptServiceMonitorMapper.getModelServiceCount();
+    }
+
+
+@Override
+    public List<Map<String, Object>> getModelServiceSuccessCount(Map<String, Object> params) {
+        return ptServiceMonitorMapper.getModelServiceSuccessCount(params);
+    }
+
 
 }

+ 19 - 34
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/PtServiceServiceImpl.java

@@ -36,6 +36,7 @@ public class PtServiceServiceImpl extends ServiceImpl<PtServiceMapper, PtService
     private final PtServiceMapper ptServiceMapper;
 
     private final RedisOperator redisOperator;
+
     @Autowired
     private IMdModelInfoService mdModelInfoService;
 
@@ -48,40 +49,30 @@ public class PtServiceServiceImpl extends ServiceImpl<PtServiceMapper, PtService
     }
 
     @Override
-    public PtService insert(PtService ptService) {
-        ptService.setSrvId(IdUtils.simpleUUID());
-        ptService.setUserId(String.valueOf(SecurityUtils.getUserId()));
+    public boolean save(PtService entity) {
+        entity.setSrvId(IdUtils.simpleUUID());
+        entity.setUserId(String.valueOf(SecurityUtils.getUserId()));
         int initNumber = 0;
-        ptService.setCnt(initNumber);
-        ptService.setViewNum(initNumber);
-        ptService.setDataNum(initNumber);
-        ptService.setApplyNum(initNumber);
+        entity.setCnt(initNumber);
+        entity.setViewNum(initNumber);
+        entity.setDataNum(initNumber);
+        entity.setApplyNum(initNumber);
         Date now = DateUtils.getNowDate();
-        ptService.setTm(now);
-        ptService.setRlstm(now);
-        ptService.setReleaseTime(now);
-        ptService.setUptm(now);
-        ptServiceMapper.insert(ptService);
-        if (CollectionUtils.isNotEmpty(ptService.getParams())) {
-            ptService.getParams().forEach(ptServiceParamMapper::insert);
+        entity.setTm(now);
+        entity.setRlstm(now);
+        entity.setReleaseTime(now);
+        entity.setUptm(now);
+        boolean  ret = super.save(entity);
+        if (CollectionUtils.isNotEmpty(entity.getParams())) {
+            entity.getParams().forEach(ptServiceParamMapper::insert);
         }
-        return ptService;
-    }
-
-    @Override
-    public PtService update(PtService ptService) {
-        ptServiceMapper.updateByPrimaryKeySelective(ptService);
-        return ptServiceMapper.selectByPrimaryKey(ptService.getSrvId());
+        return ret;
     }
 
     @Override
-    public boolean saveOrUpdate(PtService ptService) {
-        if (StringUtils.isNotBlank(ptService.getSrvId())) {
-            update(ptService);
-            return true;
-        }
-        insert(ptService);
-        return true;
+    public boolean updateById(PtService entity) {
+        entity.setUptm(DateUtils.getNowDate());
+        return super.updateById(entity);
     }
 
     @Override
@@ -114,11 +105,6 @@ public class PtServiceServiceImpl extends ServiceImpl<PtServiceMapper, PtService
         return ret;
     }
 
-    @Override
-    public PtService get(String srvId) {
-        return ptServiceMapper.selectByPrimaryKey(srvId);
-    }
-
     /**
      * 获取模型关联服务
      *
@@ -127,7 +113,6 @@ public class PtServiceServiceImpl extends ServiceImpl<PtServiceMapper, PtService
      */
     @Override
     public MdModelInfoVo modelService(MdModelInfoVo par) {
-
         return ptServiceMapper.selectModelService(par);
     }
 

+ 1 - 1
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/ServiceDataViewServiceImpl.java

@@ -40,7 +40,7 @@ public class ServiceDataViewServiceImpl implements ServiceDataViewService {
     public Map<String, Object> getDataView(String srvId) {
         Map<String, Object> map = new HashMap<>(2);
 
-        PtService ptService = ptServiceService.get(srvId);
+        PtService ptService = ptServiceService.getById(srvId);
         Optional.ofNullable(ptService).orElseThrow(() -> new CheckException("url invalid"));
         List<PtServiceReturn> ptServiceReturnList = ptServiceReturnService.selectPtServiceReturnBySrvId(srvId);
 

+ 1 - 1
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/TokenServiceImpl.java

@@ -238,7 +238,7 @@ public class TokenServiceImpl implements TokenService {
 
     @Override
     public Map<String, Object> token(String grantType, String appId, String secret) {
-        PtApp ptApp = ptAppService.get(appId);
+        PtApp ptApp = ptAppService.getById(appId);
         if (ptApp == null) {
             return failResponse(TokenError.APPID_ERR);
         } else if (!Optional.of(ptApp).map(PtApp::getAppSecret).isPresent() ||

+ 1 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/snailJob/TestJob.java

@@ -10,6 +10,7 @@ import org.springframework.stereotype.Component;
 public class TestJob {
     @JobExecutor(name = "testJob")
     public ExecuteResult job(JobArgs jobArgs) {
+        System.out.println(jobArgs.toString());
         SnailJobLog.REMOTE.info("=======调用成功========");
         SnailJobLog.REMOTE.info("=======调用成功========");
         SnailJobLog.REMOTE.info("=======调用成功========");

+ 34 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/snailJob/flowJob.java

@@ -0,0 +1,34 @@
+package com.ruoyi.interfaces.snailJob;
+
+import com.agentsflex.core.chain.Chain;
+import com.aizuda.snailjob.client.job.core.annotation.JobExecutor;
+import com.aizuda.snailjob.client.job.core.dto.JobArgs;
+import com.aizuda.snailjob.model.dto.ExecuteResult;
+import com.ruoyi.common.utils.JsonUtils;
+import com.ruoyi.interfaces.domain.MdAppFlow;
+import com.ruoyi.interfaces.service.IMdAppFlowService;
+import com.ruoyi.interfaces.service.impl.MdAppFlowServiceImpl;
+import com.ruoyi.interfaces.tinyflow.TinyflowUtil;
+import dev.tinyflow.core.Tinyflow;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+@Component
+public class flowJob {
+    @Autowired
+    private IMdAppFlowService  mdAppFlowService;
+    @JobExecutor(name = "runFolwJob")
+    public ExecuteResult runJob(JobArgs jobArgs) {
+        System.out.println(jobArgs.getJobParams());
+        MdAppFlow flowPar = JsonUtils.jsonToPojo(jobArgs.getJobParams().toString(), MdAppFlow.class);
+        MdAppFlow mdAppFlow = mdAppFlowService.selectMdAppFlowByFlowId(flowPar.getFlowId());
+        Tinyflow tinyflow = TinyflowUtil.getTinyflow(mdAppFlow.getFlowGraph());
+        Chain chain = tinyflow.toChain();
+        Map<String, Object> stringObjectMap = chain.executeForResult(flowPar.getParams());
+        System.out.println(stringObjectMap);
+        //TinyflowUtil.getTinyflow()
+        return ExecuteResult.success(stringObjectMap);
+    }
+}

+ 14 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/TinyflowUtil.java

@@ -0,0 +1,14 @@
+package com.ruoyi.interfaces.tinyflow;
+
+import com.ruoyi.interfaces.tinyflow.parser.PrintNodeParser;
+import com.ruoyi.interfaces.tinyflow.parser.ServiceNodeParser;
+import dev.tinyflow.core.Tinyflow;
+
+public class TinyflowUtil {
+    public static Tinyflow  getTinyflow(String data) {
+        Tinyflow tinyflow = new Tinyflow(data);
+        tinyflow.getChainParser().addNodeParser("printNode",new PrintNodeParser());
+        tinyflow.getChainParser().addNodeParser("serviceNode",new ServiceNodeParser());
+        return tinyflow;
+    }
+}

+ 15 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/node/PrintNode.java

@@ -6,6 +6,7 @@ import com.agentsflex.core.chain.node.BaseNode;
 import com.ruoyi.common.utils.spring.SpringUtils;
 import com.ruoyi.interfaces.domain.PtService;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -85,7 +86,21 @@ public class PrintNode extends BaseNode {
         // 返回执行结果,可以为空,也可以包含输出数据
         Map<String, Object> result = new HashMap<>();
         //result.put("service", ptService);
+
+        ArrayList<Object> data = new ArrayList<>();
+        HashMap<String, String> dataMap = new HashMap<>();
+        HashMap<String, String> dataMap2 = new HashMap<>();
+        HashMap<String, String> dataMap3 = new HashMap<>();
+        dataMap.put("type","123");
+        dataMap2.put("type","456");
+        dataMap3.put("type","789");
+        data.add(dataMap);
+        data.add(dataMap2);
+        data.add(dataMap3);
         result.put("msg",input);
+        result.put("data",data);
+
+
 
         return result;
     }

+ 76 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/node/ServiceNode.java

@@ -0,0 +1,76 @@
+package com.ruoyi.interfaces.tinyflow.node;
+
+import com.agentsflex.core.chain.Chain;
+import com.agentsflex.core.chain.node.BaseNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.ruoyi.common.utils.JsonUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.http.HttpUtils;
+import com.ruoyi.interfaces.domain.PtService;
+import com.ruoyi.interfaces.domain.PtServiceParam;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ServiceNode extends BaseNode {
+    private PtService ptService;
+
+
+    public PtService getPtService() {
+        return ptService;
+    }
+
+    public void setPtService(PtService ptService) {
+        this.ptService = ptService;
+    }
+
+    @Override
+    protected Map<String, Object> execute(Chain chain) {
+        Map<String,Object> map = new HashMap<>();
+
+        Map<String, Object> parameterValues = chain.getParameterValues(this); //获取参数
+        List<PtServiceParam> params = ptService.getParams();
+
+
+
+        HashMap<String, String> headers = null;
+        if (StringUtils.isNotNull(parameterValues.get("headers")))
+            headers = (HashMap<String, String>) parameterValues.get("headers");
+        switch (ptService.getRqtype()) {
+            case "POST":
+                HashMap<String, Object> paramMap = new HashMap<>();
+                for (PtServiceParam serviceParam : params) {
+                    Object paramValue = parameterValues.get(serviceParam.getParamCode());
+                    if (StringUtils.isNotNull(paramValue)) {
+                        paramMap.put(serviceParam.getParamCode(), paramValue);
+                    }
+                }
+                try {
+                     map.put("result",JsonUtils.jsonToPojo(HttpUtils.sendBodyPost(ptService.getUrl(), paramMap, headers), Map.class));
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+                break;
+            case "GET":
+                String paramString ="";
+                for (PtServiceParam serviceParam : params) {
+                    Object paramValue = parameterValues.get(serviceParam.getParamCode());
+                    if (StringUtils.isNotNull(paramValue)) {
+                        paramString += (serviceParam.getParamCode() + "=" + paramValue) + "&";
+                    }
+                }
+                map.put("result",JsonUtils.jsonToPojo(HttpUtils.sendGet(ptService.getUrl(), paramString, headers), Map.class));
+                break;
+        }
+
+        /**
+         * 调用服务
+         */
+
+
+        return map;
+    }
+}

+ 22 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/parser/ServiceNodeParser.java

@@ -0,0 +1,22 @@
+package com.ruoyi.interfaces.tinyflow.parser;
+
+import com.agentsflex.core.chain.node.BaseNode;
+import com.alibaba.fastjson.JSONObject;
+import com.ruoyi.interfaces.domain.PtService;
+import com.ruoyi.interfaces.tinyflow.node.ServiceNode;
+import dev.tinyflow.core.Tinyflow;
+import dev.tinyflow.core.parser.BaseNodeParser;
+
+public class ServiceNodeParser extends BaseNodeParser {
+    @Override
+    protected BaseNode doParse(JSONObject root, JSONObject data, Tinyflow tinyflow) {
+        ServiceNode serviceNode = new ServiceNode();
+        if (data != null) {
+            serviceNode.setId(data.getString("id"));
+            serviceNode.setName(data.getString("name"));
+            serviceNode.setDescription(data.getString("description"));
+            serviceNode.setPtService(data.getObject("service", PtService.class));
+        }
+        return serviceNode;
+    }
+}

+ 0 - 247
ruoyi-api-patform/src/main/resources/mapper/interfaces/PtAppMapper.xml

@@ -1,247 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
-<mapper namespace="com.ruoyi.interfaces.mapper.PtAppMapper">
-    <resultMap id="BaseResultMap" type="com.ruoyi.interfaces.domain.PtApp">
-        <id column="APP_ID" jdbcType="VARCHAR" property="appId"/>
-        <result column="APP_NAME" jdbcType="VARCHAR" property="appName"/>
-        <result column="APP_URL" jdbcType="VARCHAR" property="appUrl"/>
-        <result column="APP_DEVELOPER" jdbcType="VARCHAR" property="appDeveloper"/>
-        <result column="APP_NOTE" jdbcType="VARCHAR" property="appNote"/>
-        <result column="APP_PUBLISH" jdbcType="TIMESTAMP" property="appPublish"/>
-        <result column="APP_STATE" jdbcType="VARCHAR" property="appState"/>
-        <result column="APP_CATE" jdbcType="VARCHAR" property="appCate"/>
-        <result column="APP_SECRET" jdbcType="VARCHAR" property="appSecret"/>
-        <result column="APP_TOKEN" jdbcType="VARCHAR" property="appToken"/>
-        <result column="AUDIT_USER" jdbcType="VARCHAR" property="auditUser"/>
-        <result column="AUDIT_TIME" jdbcType="TIMESTAMP" property="auditTime"/>
-        <result column="RQ_TIME" jdbcType="TIMESTAMP" property="rqTime"/>
-        <result column="RQ_TIME" jdbcType="TIMESTAMP" property="rqTime"/>
-        <result column="USER_ID" jdbcType="VARCHAR" property="userId"/>
-        <result column="APP_TYPE" jdbcType="VARCHAR" property="appType"/>
-        <result column="APP_FIELD" jdbcType="VARCHAR" property="appField"/>
-    </resultMap>
-    <sql id="Base_Column_List">
-        APP_ID
-        , APP_NAME, APP_URL, APP_DEVELOPER, APP_NOTE, APP_PUBLISH, APP_STATE, APP_CATE, APP_TYPE, APP_FIELD,
-    APP_SECRET, APP_TOKEN, AUDIT_USER, AUDIT_TIME, RQ_TIME, USER_ID
-    </sql>
-    <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
-        select
-        <include refid="Base_Column_List"/>
-        from PT_APP
-        where APP_ID = #{appId,jdbcType=VARCHAR}
-    </select>
-    <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
-        delete
-        from PT_APP
-        where APP_ID = #{appId,jdbcType=VARCHAR}
-    </delete>
-    <insert id="insert" parameterType="com.ruoyi.interfaces.domain.PtApp">
-        insert into PT_APP (APP_ID, APP_NAME, APP_URL,
-                            APP_DEVELOPER, APP_NOTE, APP_PUBLISH,
-                            APP_STATE, APP_CATE, APP_SECRET,
-                            APP_TOKEN, AUDIT_USER, AUDIT_TIME,
-                            RQ_TIME, USER_ID, APP_TYPE, APP_FIELD)
-        values (#{appId,jdbcType=VARCHAR}, #{appName,jdbcType=VARCHAR}, #{appUrl,jdbcType=VARCHAR},
-                #{appDeveloper,jdbcType=VARCHAR}, #{appNote,jdbcType=VARCHAR}, #{appPublish,jdbcType=TIMESTAMP},
-                #{appState,jdbcType=VARCHAR}, #{appCate,jdbcType=VARCHAR}, #{appSecret,jdbcType=VARCHAR},
-                #{appToken,jdbcType=VARCHAR}, #{auditUser,jdbcType=VARCHAR}, #{auditTime,jdbcType=TIMESTAMP},
-                #{rqTime,jdbcType=TIMESTAMP}, #{userId,jdbcType=VARCHAR},
-                #{appType,jdbcType=VARCHAR}, #{appField,jdbcType=VARCHAR})
-    </insert>
-    <insert id="insertSelective" parameterType="com.ruoyi.interfaces.domain.PtApp">
-        insert into PT_APP
-        <trim prefix="(" suffix=")" suffixOverrides=",">
-            <if test="appId != null">
-                APP_ID,
-            </if>
-            <if test="appName != null">
-                APP_NAME,
-            </if>
-            <if test="appUrl != null">
-                APP_URL,
-            </if>
-            <if test="appDeveloper != null">
-                APP_DEVELOPER,
-            </if>
-            <if test="appNote != null">
-                APP_NOTE,
-            </if>
-            <if test="appPublish != null">
-                APP_PUBLISH,
-            </if>
-            <if test="appState != null">
-                APP_STATE,
-            </if>
-            <if test="appCate != null">
-                APP_CATE,
-            </if>
-            <if test="appSecret != null">
-                APP_SECRET,
-            </if>
-            <if test="appToken != null">
-                APP_TOKEN,
-            </if>
-            <if test="auditUser != null">
-                AUDIT_USER,
-            </if>
-            <if test="auditTime != null">
-                AUDIT_TIME,
-            </if>
-            <if test="rqTime != null">
-                RQ_TIME,
-            </if>
-            <if test="userId != null">
-                USER_ID,
-            </if>
-            <if test="appType != null">
-                APP_TYPE,
-            </if>
-            <if test="appField != null">
-                APP_FIELD,
-            </if>
-        </trim>
-        <trim prefix="values (" suffix=")" suffixOverrides=",">
-            <if test="appId != null">
-                #{appId,jdbcType=VARCHAR},
-            </if>
-            <if test="appName != null">
-                #{appName,jdbcType=VARCHAR},
-            </if>
-            <if test="appUrl != null">
-                #{appUrl,jdbcType=VARCHAR},
-            </if>
-            <if test="appDeveloper != null">
-                #{appDeveloper,jdbcType=VARCHAR},
-            </if>
-            <if test="appNote != null">
-                #{appNote,jdbcType=VARCHAR},
-            </if>
-            <if test="appPublish != null">
-                #{appPublish,jdbcType=TIMESTAMP},
-            </if>
-            <if test="appState != null">
-                #{appState,jdbcType=VARCHAR},
-            </if>
-            <if test="appCate != null">
-                #{appCate,jdbcType=VARCHAR},
-            </if>
-            <if test="appSecret != null">
-                #{appSecret,jdbcType=VARCHAR},
-            </if>
-            <if test="appToken != null">
-                #{appToken,jdbcType=VARCHAR},
-            </if>
-            <if test="auditUser != null">
-                #{auditUser,jdbcType=VARCHAR},
-            </if>
-            <if test="auditTime != null">
-                #{auditTime,jdbcType=TIMESTAMP},
-            </if>
-            <if test="rqTime != null">
-                #{rqTime,jdbcType=TIMESTAMP},
-            </if>
-            <if test="userId != null">
-                #{userId,jdbcType=VARCHAR},
-            </if>
-            <if test="appType != null">
-                #{appType,jdbcType=VARCHAR},
-            </if>
-            <if test="appField != null">
-                #{appField,jdbcType=VARCHAR},
-            </if>
-        </trim>
-    </insert>
-    <update id="updateByPrimaryKeySelective" parameterType="com.ruoyi.interfaces.domain.PtApp">
-        update PT_APP
-        <set>
-            <if test="appName != null">
-                APP_NAME = #{appName,jdbcType=VARCHAR},
-            </if>
-            <if test="appUrl != null">
-                APP_URL = #{appUrl,jdbcType=VARCHAR},
-            </if>
-            <if test="appDeveloper != null">
-                APP_DEVELOPER = #{appDeveloper,jdbcType=VARCHAR},
-            </if>
-            <if test="appNote != null">
-                APP_NOTE = #{appNote,jdbcType=VARCHAR},
-            </if>
-            <if test="appPublish != null">
-                APP_PUBLISH = #{appPublish,jdbcType=TIMESTAMP},
-            </if>
-            <if test="appState != null">
-                APP_STATE = #{appState,jdbcType=VARCHAR},
-            </if>
-            <if test="appCate != null">
-                APP_CATE = #{appCate,jdbcType=VARCHAR},
-            </if>
-            <if test="appSecret != null">
-                APP_SECRET = #{appSecret,jdbcType=VARCHAR},
-            </if>
-            <if test="appToken != null">
-                APP_TOKEN = #{appToken,jdbcType=VARCHAR},
-            </if>
-            <if test="auditUser != null">
-                AUDIT_USER = #{auditUser,jdbcType=VARCHAR},
-            </if>
-            <if test="auditTime != null">
-                AUDIT_TIME = #{auditTime,jdbcType=TIMESTAMP},
-            </if>
-            <if test="rqTime != null">
-                RQ_TIME = #{rqTime,jdbcType=TIMESTAMP},
-            </if>
-            <if test="userId != null">
-                USER_ID = #{userId,jdbcType=VARCHAR},
-            </if>
-            <if test="appType != null">
-                APP_TYPE = #{appType,jdbcType=VARCHAR},
-            </if>
-            <if test="appField != null">
-                APP_FIELD = #{appField,jdbcType=VARCHAR},
-            </if>
-        </set>
-        where APP_ID = #{appId,jdbcType=VARCHAR}
-    </update>
-    <update id="updateByPrimaryKey" parameterType="com.ruoyi.interfaces.domain.PtApp">
-        update PT_APP
-        set APP_NAME      = #{appName,jdbcType=VARCHAR},
-            APP_URL       = #{appUrl,jdbcType=VARCHAR},
-            APP_DEVELOPER = #{appDeveloper,jdbcType=VARCHAR},
-            APP_NOTE      = #{appNote,jdbcType=VARCHAR},
-            APP_PUBLISH   = #{appPublish,jdbcType=TIMESTAMP},
-            APP_STATE     = #{appState,jdbcType=VARCHAR},
-            APP_CATE      = #{appCate,jdbcType=VARCHAR},
-            APP_SECRET    = #{appSecret,jdbcType=VARCHAR},
-            APP_TOKEN     = #{appToken,jdbcType=VARCHAR},
-            AUDIT_USER    = #{auditUser,jdbcType=VARCHAR},
-            AUDIT_TIME    = #{auditTime,jdbcType=TIMESTAMP},
-            RQ_TIME       = #{rqTime,jdbcType=TIMESTAMP},
-            USER_ID       = #{userId,jdbcType=VARCHAR},
-            APP_TYPE      = #{appType,jdbcType=VARCHAR},
-            APP_FIELD     = #{appField,jdbcType=VARCHAR}
-        where APP_ID = #{appId,jdbcType=VARCHAR}
-    </update>
-    <select id="selectAll" parameterType="com.ruoyi.interfaces.domain.PtApp" resultMap="BaseResultMap">
-        select
-        <include refid="Base_Column_List"/>
-        from PT_APP
-        <where>
-            <if test="appName != null and appName !=''">
-                APP_NAME like CONCAT('%', CONCAT(#{appName}, '%'))
-            </if>
-            <if test="userId != null and userId !=''">
-                AND USER_ID = #{userId}
-            </if>
-        </where>
-    </select>
-    <select id="listByIds" resultMap="BaseResultMap">
-        select
-        <include refid="Base_Column_List"/>
-        from PT_APP
-        where APP_ID IN
-        <foreach collection="ids" item="id" open="(" separator="," close=")">
-            #{id}
-        </foreach>
-    </select>
-</mapper>

+ 59 - 10
ruoyi-api-patform/src/main/resources/mapper/interfaces/PtServiceMonitorMapper.xml

@@ -9,24 +9,23 @@
     </select>
     <select id="getModelCallCount" resultType="java.util.Map">
         SELECT
-        a.user_id AS userId,
-        a.nick_name AS name,
+        a.app_id AS appId,
+        a.app_name AS appName,
         COUNT( * ) AS total
         FROM
-        sys_user a
-        JOIN pt_service_log b ON a.user_id = b.user_id
+        pt_service_log a
         <where>
             <if test="userId != null and userId != ''">
                 AND a.user_id = #{userId}
             </if>
             <if test="startTime != null and startTime != ''">
-                AND b.tm &gt;= #{startTime}
+                AND a.tm &gt;= #{startTime}
             </if>
             <if test="endTime != null and endTime != ''">
-                AND b.tm &lt; #{endTime}
+                AND a.tm &lt; #{endTime}
             </if>
         </where>
-        GROUP BY a.user_id, a.nick_name
+        GROUP BY a.app_id, a.app_name
     </select>
     <select id="getUserModelCallCount" resultType="java.util.Map">
         SELECT
@@ -48,11 +47,61 @@
         GROUP BY b.service_name
     </select>
     <select id="getModelTypeCallCount" resultType="java.util.Map">
-        SELECT a.type,
+        SELECT a.name,
                count(*) as total
         FROM md_model_info a
                  JOIN pt_service_log b ON a.MDID = b.md_id
-        GROUP BY a.type
+        <where>
+            <if test="startTime != null and startTime != ''">
+                AND b.tm &gt;= #{startTime}
+            </if>
+            <if test="endTime != null and endTime != ''">
+                AND b.tm &lt; #{endTime}
+            </if>
+        </where>
+        GROUP BY a.name
+    </select>
+    <select id="getMonthModelCallMaxCount" resultType="java.util.Map">
+        SELECT a.md_id,
+               b.`NAME`,
+               COUNT(*) AS call_count
+        FROM pt_service_log a
+                 JOIN md_model_info b ON a.md_id = b.MDID
+        WHERE DATE_FORMAT(a.tm, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m') -- 动态匹配当前年月
+        GROUP BY a.md_id, b.`NAME`
+        HAVING COUNT(*) = (SELECT COUNT(*) AS cnt
+                           FROM pt_service_log
+                           WHERE DATE_FORMAT(tm, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
+                           GROUP BY md_id
+                           ORDER BY cnt DESC
+            LIMIT 1 -- 获取最高调用次数
+            )
+        ORDER BY call_count DESC;
+    </select>
+    <select id="getModelServiceCount" resultType="java.util.Map">
+        SELECT a.NAME   name,
+               count(*) total
+        FROM md_model_info a
+                 JOIN pt_service b ON a.MDID = b.MDID
+        GROUP BY a.NAME
+    </select>
+    <select id="getModelServiceSuccessCount" resultType="java.util.Map">
+        SELECT
+            a.NAME AS name,
+            COUNT(*) AS total,
+            SUM(CASE WHEN b.status_code = 200 THEN 1 ELSE 0 END) AS success,
+            SUM(CASE WHEN b.status_code != 200 THEN 1 ELSE 0 END) AS fail
+        FROM
+            md_model_info a
+                JOIN pt_service_log b ON a.MDID = b.md_id
+        <where>
+            <if test="startTime != null and startTime != ''">
+                AND b.tm &gt;= #{startTime}
+            </if>
+            <if test="endTime != null and endTime != ''">
+                AND b.tm &lt; #{endTime}
+            </if>
+        </where>
+        GROUP BY a.NAME;
     </select>
-
 </mapper>

+ 1 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java

@@ -47,6 +47,7 @@ public class JsonUtils {
             T t = MAPPER.readValue(jsonData, beanType);
             return t;
         } catch (Exception e) {
+            System.out.println(ExceptionUtil.getRootErrorMessage(e));
             e.printStackTrace();
         }
         return null;

+ 0 - 18
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java

@@ -134,24 +134,6 @@ public class HttpUtils {
     }
 
     public static String sendGet(String url, String param, HashMap<String, String> headers) {
-        System.out.println("=======================");
-        System.out.println("=======================");
-        System.out.println("=======================");
-        System.out.println("=======================");
-        System.out.println(url);
-        System.out.println(param);
-        param = param.substring(0,1);
-        System.out.println(param);
-        for (String s : headers.keySet()) {
-            System.out.println(s+":"+headers.get(s));
-        }
-
-        System.out.println("=======================");
-        System.out.println("=======================");
-        System.out.println("=======================");
-        System.out.println("=======================");
-
-
 
         StringBuilder result = new StringBuilder();
         BufferedReader in = null;

+ 1 - 1
ruoyi-ui/.env.development

@@ -11,7 +11,7 @@ VITE_APP_BASE_Title = '/sh'
 VITE_APP_BASE_API = '/sh-api'
 
 VITE_DEV_PATH = 'http://localhost:8082'
-# VITE_DEV_PATH = 'http://39.98.38.2:18082/sh-api'
+#VITE_DEV_PATH = 'http://39.98.38.2:18082/sh-api'
 
 # 是否在打包时开启压缩,支持 gzip 和 brotli
 VITE_BUILD_COMPRESS = gzip

+ 2 - 0
ruoyi-ui/package.json

@@ -24,6 +24,7 @@
     "@vueup/vue-quill": "1.2.0",
     "@vueuse/core": "10.11.0",
     "axios": "0.28.1",
+    "clipboard": "^2.0.11",
     "codemirror": "^5.65.19",
     "codemirror-editor-vue3": "^2.8.0",
     "echarts": "^5.5.1",
@@ -41,6 +42,7 @@
     "pinyin": "^4.0.0",
     "sortablejs": "^1.15.6",
     "vue": "^3.5.13",
+    "vue-clipboard3": "^2.0.0",
     "vue-cropper": "1.1.1",
     "vue-draggable-plus": "^0.6.0",
     "vue-json-editor": "^1.4.3",

+ 10 - 1
ruoyi-ui/src/api/gateway/gatewayRouters.js

@@ -37,4 +37,13 @@ export function getGatewayRoutersList(data) {
     });
 }
 
-
+/**
+ * 查询选择器列表
+ * @param data
+ */
+export function getGatewayRouters() {
+    return request({
+        url: `/gateway/routes/list`,
+        method: "get",
+    });
+}

+ 23 - 1
ruoyi-ui/src/api/monitor/server.js

@@ -66,9 +66,31 @@ export function getUserModelCallCount(userId) {
 /**
  * 模型服务调度次数
  */
-export function getModelTypeCallCount() {
+export function getModelTypeCallCount(params) {
     return request({
         url: '/service/monitor/getModelTypeCallCount',
         method: 'get',
+        params
+    })
+}
+
+/**
+ * 模型服务统计
+ */
+export function getModelServiceCount() {
+    return request({
+        url: '/service/monitor/getModelServiceCount',
+        method: 'get',
+    })
+}
+
+/**
+ * 模型服务统计
+ */
+export function getModelServiceSuccessCount(params) {
+    return request({
+        url: '/service/monitor/getModelServiceSuccessCount',
+        method: 'get',
+        params
     })
 }

+ 55 - 0
ruoyi-ui/src/api/service/app.js

@@ -0,0 +1,55 @@
+import request from "@/utils/request";
+
+
+export function addApp(data) {
+    return request({
+        url: '/pt/app/add',
+        method: 'post',
+        data
+    })
+}
+
+// 修改App
+export function updateApp(data) {
+    return request({
+        url: '/pt/app/update',
+        method: 'post',
+        data
+    })
+}
+
+// 获取服务列表
+export function getServiceList(data) {
+    return request.post('/pt/service/publicList', data)
+}
+
+// 获取用户所有应用
+export function getPtApps() {
+    return request.post('/pt/app/lists')
+}
+
+// 获取用户应用(分页)
+export function getPtApp(data) {
+    return request({
+        url: '/pt/app/list',
+        method: 'get',
+        params: data
+    })
+}
+
+// 删除应用
+export function deletePtApp(keys) {
+    return request({
+        url: '/pt/app/delete',
+        method: 'get',
+        params: {keys}
+    })
+}
+
+/** 应用名称格式转换 */
+export function formatAppName(nameArr) {
+    if (nameArr == undefined || nameArr == null || nameArr.length == 0) {
+        return ''
+    }
+    return nameArr.join(',')
+}

+ 362 - 97
ruoyi-ui/src/views/monitor/service/index.vue

@@ -5,77 +5,138 @@
                     :color="item.color"></gw-statistic>
     </div>
     <div class="gw-statistic-row" style="height: 30vh;">
-      <gw-card style="width: 40%;">
+      <gw-card style="width: 60%;">
         <template v-slot:title>
-          <span>今日模型服务调度次数</span>
-          <span style="color: #79bbff;margin-left: 1%;">{{ todayModelCallCount }}</span>
-          <span style="margin-left: 1%;"> 次</span>
-        </template>
-        <div id="top1" class="chart_container"></div>
-      </gw-card>
-      <gw-card style="width: 30%;">
-        <template v-slot:title>
-          <div style="display: flex;align-items: center;font-weight: bold;width: 100%;">
-            <div style="">模型服务调用次数</div>
-            <div style="width: 50%;margin-left: 20%;">
-              <el-select v-model="userId" class="m-2" placeholder="选则用户" style="width: 100%;">
-                <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value"
-                           @change="initChartTop2"/>
-              </el-select>
+          <div style="display: flex;align-items: center;justify-content: space-between;">
+            <div>
+              <span>模型服务调度次数</span>
+              <span style="color: #79bbff;">&nbsp;{{ todayModelCallCount }}&nbsp;</span>
+              <span>次</span>
             </div>
+            <el-segmented v-model="dateType" :options="dateTypeOptions" @change="initChartTop1"/>
           </div>
         </template>
-        <gw-echart ref="top2Ref"></gw-echart>
+        <gw-echart ref="top1Ref"></gw-echart>
       </gw-card>
-      <gw-card style="width: 30%;">
+      <!--      <gw-card style="width: 30%;">-->
+      <!--        <template v-slot:title>-->
+      <!--          <div style="display: flex;align-items: center;font-weight: bold;width: 100%;">-->
+      <!--            <div style="">模型服务调用次数</div>-->
+      <!--            <div style="width: 50%;margin-left: 20%;">-->
+      <!--              <el-select v-model="userId" class="m-2" placeholder="选则用户" style="width: 100%;"-->
+      <!--                         @change="initChartTop2">-->
+      <!--                <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value"/>-->
+      <!--              </el-select>-->
+      <!--            </div>-->
+      <!--          </div>-->
+      <!--        </template>-->
+      <!--        <gw-echart ref="top2Ref"></gw-echart>-->
+      <!--      </gw-card>-->
+      <gw-card style="width: 40%;">
         <template v-slot:title>
-          <span style="">模型服务类型总数</span>
-          <span style="color: #79bbff;margin-left: 1%;"> {{ modelTypeCallCount }}</span>
-          <span style="margin-left: 1%;"> 次</span>
+          <div style="display: flex;align-items: center;justify-content: space-between;">
+            <div>模型调用次数统计</div>
+            <el-segmented v-model="dateType" :options="dateTypeOptions" @change="initChartTop3"/>
+          </div>
         </template>
         <gw-echart ref="top3Ref"></gw-echart>
       </gw-card>
     </div>
     <div class="gw-statistic-row" style="height: 30vh;">
-      <gw-card>
+      <gw-card style="width: 50%;">
         <template v-slot:title>
-          <div style="width: 100%;display: flex;justify-content: flex-end;">
-            <el-select
-                v-model="dateType"
-                class="m-2"
-                style="width: 20%;"
-                @change="initChartBottom1"
-            >
-              <el-option
-                  v-for="item in dateTypeOptions"
-                  :key="item.value"
-                  :label="item.label"
-                  :value="item.value"
-              />
-            </el-select>
+          <span>模型服务接口统计</span>
+        </template>
+        <gw-echart ref="top9Ref"></gw-echart>
+      </gw-card>
+<!--      <gw-card style="width: 33%;">-->
+<!--        <template v-slot:title>-->
+<!--          <span>模型计算结果统计</span>-->
+<!--        </template>-->
+<!--        <gw-echart ref="top10Ref"></gw-echart>-->
+<!--      </gw-card>-->
+      <gw-card style="width: 50%;">
+        <template v-slot:title>
+          <div style="display: flex;align-items: center;justify-content: space-between;">
+            <div>
+              <span>模型计算成功统计</span>
+            </div>
+            <el-segmented v-model="dateType" :options="dateTypeOptions" @change="initChartTop11"/>
           </div>
         </template>
-        <gw-echart ref="bt1Ref"></gw-echart>
+        <gw-echart ref="top11Ref"></gw-echart>
       </gw-card>
     </div>
-    <div class="gw-statistic-row" style="height: 40vh;">
-      <div class="gw-statistic-body">
-        <el-row :gutter="10" style="height: 100%;">
-          <el-col :span="15" style="height: 100%;position: relative;">
-            <div class="title">访问来源追溯</div>
-            <div style="height: calc(100% - 20px)">
-              <div id="visit_source_chart" class="chart_container"></div>
-            </div>
-          </el-col>
-          <el-col :span="9" class="visit_number" style="height: 100%;">
-            <div class="title">访问次数排行</div>
-            <div style="height: calc(100% - 20px)">
-              <div id="visit_number_chart" class="chart_container"></div>
+    <div class="gw-statistic-row" style="height: 30vh;">
+      <gw-card style="width: 60%;">
+        <template v-slot:title>
+          <div style="display: flex;align-items: center;justify-content: space-between;">
+            <div>
+              <span>任务统计</span>
             </div>
-          </el-col>
-        </el-row>
-      </div>
+            <el-segmented v-model="task" :options="taskOptions" @change="initChartTop5"/>
+          </div>
+        </template>
+        <gw-echart ref="top5Ref"></gw-echart>
+      </gw-card>
+      <gw-card style="width: 40%;">
+        <template v-slot:title>
+          <div style="display:flex;align-items: center;">
+            <span style="margin-right: 5px;">报警信息</span>
+            <el-tag type="danger" effect="dark" size="small">{{ alarmTableData.length }}</el-tag>
+          </div>
+        </template>
+        <el-table stripe :data="alarmTableData" size="small">
+          <el-table-column align="center" width="120" prop="tm" label="报警时间">
+            <template #default="scope">
+              <el-tag size="medium">{{ scope.row.tm }}</el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column align="center" width="100" prop="type" label="报警类型"/>
+          <el-table-column align="center" width="150" prop="modelName" label="模型名称"/>
+          <el-table-column align="center" prop="content" label="报警内容"/>
+        </el-table>
+      </gw-card>
     </div>
+    <!--    <div class="gw-statistic-row" style="height: 30vh;">-->
+    <!--      <gw-card>-->
+    <!--        <template v-slot:title>-->
+    <!--          <div style="width: 100%;display: flex;justify-content: flex-end;">-->
+    <!--            <el-select-->
+    <!--                v-model="dateType"-->
+    <!--                class="m-2"-->
+    <!--                style="width: 20%;"-->
+    <!--                @change="initChartBottom1"-->
+    <!--              <el-option-->
+    <!--                  v-for="item in dateTypeOptions"-->
+    <!--                  :key="item.value"-->
+    <!--                  :label="item.label"-->
+    <!--                  :value="item.value"-->
+    <!--              />-->
+    <!--            </el-select>-->
+    <!--          </div>-->
+    <!--        </template>-->
+    <!--        <gw-echart ref="bt1Ref"></gw-echart>-->
+    <!--      </gw-card>-->
+    <!--    </div>-->
+    <!--    <div class="gw-statistic-row" style="height: 40vh;">-->
+    <!--      <div class="gw-statistic-body">-->
+    <!--        <el-row :gutter="10" style="height: 100%;">-->
+    <!--          <el-col :span="15" style="height: 100%;position: relative;">-->
+    <!--            <div class="title">访问来源追溯</div>-->
+    <!--            <div style="height: calc(100% - 20px)">-->
+    <!--              <div id="visit_source_chart" class="chart_container"></div>-->
+    <!--            </div>-->
+    <!--          </el-col>-->
+    <!--          <el-col :span="9" class="visit_number" style="height: 100%;">-->
+    <!--            <div class="title">访问次数排行</div>-->
+    <!--            <div style="height: calc(100% - 20px)">-->
+    <!--              <div id="visit_number_chart" class="chart_container"></div>-->
+    <!--            </div>-->
+    <!--          </el-col>-->
+    <!--        </el-row>-->
+    <!--      </div>-->
+    <!--    </div>-->
   </div>
 </template>
 <script setup>
@@ -84,9 +145,10 @@ import * as echarts from 'echarts';
 import GwStatistic from "@/views/monitor/service/GwStatistic.vue";
 import {
   getModelCallCount,
+  getModelServiceCount,
+  getModelServiceSuccessCount,
   getModelTypeCallCount,
   getStatisticData,
-  getTodayModelCallCount,
   getUserModelCallCount,
   getViewNumByCity
 } from "@/api/monitor/server.js";
@@ -115,8 +177,13 @@ listUser().then(res => {
   })
 
 })
+const top1Ref = ref(null)
 const top2Ref = ref(null)
 const top3Ref = ref(null)
+const top5Ref = ref(null)
+const top9Ref = ref(null)
+const top10Ref = ref(null)
+const top11Ref = ref(null)
 const modelTypeCallCount = ref(0)
 
 const dateType = ref('5')
@@ -127,30 +194,71 @@ const dateTypeOptions = ref([
   {label: '近一个月', value: '4'},
   {label: '全部', value: '5'},
 ])
+const task = ref('1')
+const taskOptions = ref([
+  {label: '日执行量', value: '1'},
+  {label: '月执行量', value: '2'},
+])
 const bt1Ref = ref(null)
-
 const echartMapData = ref([])
+const alarmTableData = ref([
+  {tm: '09-12 11:12', type: '格式异常', modelName: '上海沿海风暴潮预报模型', content: '调用返回异常'},
+  {tm: '09-11 11:12', type: '请求异常', modelName: '上海沿海风暴潮预报模型', content: '模型连接失败'},
+  {tm: '09-10 11:12', type: '服务器未响应', modelName: '上海沿海风暴潮预报模型', content: '服务器报错'},
+])
 
-function inintChartTop1() {
-  getTodayModelCallCount().then(res => {
+function getTimes(dateType) {
+  let startTime = null, endTime = null
+  const date = new Date()
+  switch (dateType) {
+    case '1':
+      startTime = parseTime(new Date(), '{y}-{m}-{d}') + ' 00:00:00'
+      date.setDate(date.getDate() + 1)
+      endTime = parseTime(date, '{y}-{m}-{d}') + ' 00:00:00'
+      break;
+    case '2':
+      endTime = parseTime(new Date())
+      date.setDate(date.getDate() - 3)
+      startTime = parseTime(date)
+      break;
+    case '3':
+      endTime = parseTime(new Date())
+      date.setDate(date.getDate() - 7)
+      startTime = parseTime(date)
+      break;
+    case '4':
+      endTime = parseTime(new Date())
+      date.setDate(date.getDate() - 30)
+      startTime = parseTime(date)
+      break;
+    default:
+  }
+  return {startTime, endTime}
+}
+
+function initChartTop1() {
+  const params = {}
+  const {startTime, endTime} = getTimes(dateType.value)
+  params.startTime = startTime
+  params.endTime = endTime
+  getModelCallCount(params).then(res => {
     let chartData = res.data
     todayModelCallCount.value = chartData.map(item => item.total).reduce((acc, current) => acc + current, 0);
-    var chartDom = document.getElementById('top1');
-    var myChart = echarts.init(chartDom);
-    var option;
-
-    option = {
+    const option = {
       tooltip: {},
       grid: {
         left: '5%',
         right: '5%',
-        bottom: '10%',
-        top: '18%',
+        bottom: '0%',
+        top: '10%',
         containLabel: true
       },
       xAxis: {
         // splitLine: {show: false},
-        data: chartData.map(item => item.name),
+        axisLabel: {
+          rotate: 10 // 设置标签旋转45度
+        },
+        data: chartData.map(item => item.appName),
       },
       yAxis: {
         type: 'value',
@@ -168,12 +276,12 @@ function inintChartTop1() {
         }
       ]
     };
-    option && myChart.setOption(option);
+    top1Ref.value.loadChart(option);
   })
 }
 
 function initChartTop2() {
-  getUserModelCallCount().then(res => {
+  getUserModelCallCount(userId.value).then(res => {
     let chartData = res.data.map(item => {
       return {
         name: item.serviceName,
@@ -211,11 +319,15 @@ function initChartTop2() {
 }
 
 function initChartTop3() {
-  getModelTypeCallCount().then(res => {
+  const params = {}
+  const {startTime, endTime} = getTimes(dateType.value)
+  params.startTime = startTime
+  params.endTime = endTime
+  getModelTypeCallCount(params).then(res => {
     modelTypeCallCount.value = res.data.map(item => item.total).reduce((acc, current) => acc + current, 0);
     let chartData = res.data.map(item => {
       return {
-        name: item.type,
+        name: item.name,
         value: item.total
       }
     })
@@ -223,6 +335,13 @@ function initChartTop3() {
       tooltip: {
         trigger: 'item'
       },
+      grid: {
+        left: '5%',
+        right: '5%',
+        bottom: '0%',
+        top: '10%',
+        containLabel: true
+      },
       legend: {
         top: '90%',
         left: 'center'
@@ -249,32 +368,120 @@ function initChartTop3() {
   })
 }
 
+function initChartTop9() {
+  getModelServiceCount().then(res => {
+    modelTypeCallCount.value = res.data.map(item => item.total).reduce((acc, current) => acc + current, 0);
+    let chartData = res.data.map(item => {
+      return {
+        name: item.name,
+        value: item.total
+      }
+    })
+    const option = {
+      tooltip: {
+        trigger: 'item'
+      },
+      grid: {
+        left: '5%',
+        right: '5%',
+        bottom: '0%',
+        top: '10%',
+        containLabel: true
+      },
+      legend: {
+        top: '90%',
+        left: 'center'
+      },
+      series: [
+        {
+          type: 'pie',
+          radius: ['50%', '70%'],
+          avoidLabelOverlap: false,
+          label: {
+            show: true,
+            position: 'outside',
+            formatter: '{c}',
+          },
+          labelLine: {
+            show: true
+          },
+          color: ['#529b2e', '#95d475', '#b3e19d', '#d1edc4'],
+          data: chartData
+        }
+      ]
+    };
+    top9Ref.value.loadChart(option)
+  })
+}
+
+function initChartTop11() {
+  const params = {}
+  const {startTime, endTime} = getTimes(dateType.value)
+  params.startTime = startTime
+  params.endTime = endTime
+  getModelServiceSuccessCount(params).then(res => {
+    let rawData = [
+      res.data.map(item => item.success),
+      res.data.map(item => item.fail)
+    ]
+    const totalData = [];
+    for (let i = 0; i < rawData[0].length; ++i) {
+      let sum = 0;
+      for (let j = 0; j < rawData.length; ++j) {
+        sum += rawData[j][i];
+      }
+      totalData.push(sum);
+    }
+    const series = ['成功', '失败'].map((name, sid) => {
+      return {
+        name,
+        type: 'bar',
+        stack: 'total',
+        barWidth: '60%',
+        label: {
+          show: true,
+          formatter: (params) => Math.round(params.value * 1000) / 10 + '%'
+        },
+        data: rawData[sid].map((d, did) =>
+            totalData[did] <= 0 ? 0 : d / totalData[did]
+        )
+      };
+    });
+    const option = {
+      legend: {
+        selectedMode: false
+      },
+      tooltip: {
+        trigger: 'item'
+      },
+      grid: {
+        left: '5%',
+        right: '5%',
+        bottom: '0%',
+        top: '20%',
+        containLabel: true
+      },
+      yAxis: {
+        type: 'value'
+      },
+      xAxis: {
+        type: 'category',
+        axisLabel: {
+          rotate: 10 // 设置标签旋转45度
+        },
+        data: res.data.map(item => item.name)
+      },
+      series
+    };
+    top11Ref.value.loadChart(option)
+  })
+}
+
 function initChartBottom1() {
   const params = {}
-  const date = new Date()
-  switch (dateType.value) {
-    case '1':
-      params.startTime = parseTime(new Date(), '{y}-{m}-{d}') + ' 00:00:00'
-      date.setDate(date.getDate() + 1)
-      params.endTime = parseTime(date, '{y}-{m}-{d}') + ' 00:00:00'
-      break;
-    case '2':
-      params.endTime = parseTime(new Date())
-      date.setDate(date.getDate() - 3)
-      params.startTime  = parseTime(date)
-      break;
-    case '3':
-      params.endTime = parseTime(new Date())
-      date.setDate(date.getDate() - 7)
-      params.startTime = parseTime(date)
-      break;
-    case '4':
-      params.endTime = parseTime(new Date())
-      date.setDate(date.getDate() - 30)
-      params.startTime = parseTime(date)
-      break;
-    default:
-  }
+  const {startTime, endTime} = getTimes(dateType.value)
+  params.startTime = startTime
+  params.endTime = endTime
 
   getModelCallCount(params).then(res => {
     const chartData = res.data
@@ -348,6 +555,61 @@ function initChartBottom2() {
   option && myChart.setOption(option);
 }
 
+function initChartTop5() {
+  const option = {
+    legend: {},
+    grid: {
+      left: '5%',
+      right: '5%',
+      bottom: '10%',
+      top: '15%',
+      containLabel: true
+    },
+    tooltip: {
+      trigger: 'axis',
+      showContent: false
+    },
+    dataset: {
+      source: [
+        ['模型', '09-07', '09-08', '09-09', '09-10', '09-11', '09-12'],
+        ['上海沿海风暴潮预报模型', 56.5, 82.1, 88.7, 70.1, 53.4, 85.1],
+        ['马斯京根法', 51.1, 51.4, 55.1, 53.3, 73.8, 68.7],
+        ['三水源新安江产流模型', 40.1, 62.2, 69.5, 36.4, 45.2, 32.5],
+        ['上海市中心城区排水系统模型', 25.2, 37.1, 41.2, 18, 33.9, 49.1]
+      ]
+    },
+    xAxis: {type: 'category'},
+    yAxis: {gridIndex: 0},
+    series: [
+      {
+        type: 'line',
+        smooth: true,
+        seriesLayoutBy: 'row',
+        emphasis: {focus: 'series'}
+      },
+      {
+        type: 'line',
+        smooth: true,
+        seriesLayoutBy: 'row',
+        emphasis: {focus: 'series'}
+      },
+      {
+        type: 'line',
+        smooth: true,
+        seriesLayoutBy: 'row',
+        emphasis: {focus: 'series'}
+      },
+      {
+        type: 'line',
+        smooth: true,
+        seriesLayoutBy: 'row',
+        emphasis: {focus: 'series'}
+      }
+    ]
+  };
+  top5Ref.value.loadChart(option);
+}
+
 function initVisitNumberChart(name, data) {
   data.sort((a, b) => b.value - a.value)
   let d = data.slice(0, 9)
@@ -414,12 +676,15 @@ function initViewNumByCity() {
 onMounted(() => {
   initStatisticData()
 
-  inintChartTop1()
-  initChartTop2()
+  initChartTop1()
+  // initChartTop2()
   initChartTop3()
-  initChartBottom1()
+  initChartTop5()
+  initChartTop9()
+  initChartTop11()
+  // initChartBottom1()
   // initChartBottom2()
-  initViewNumByCity()
+  // initViewNumByCity()
 });
 </script>
 <style scoped lang="scss">

+ 220 - 0
ruoyi-ui/src/views/service/app/index.vue

@@ -0,0 +1,220 @@
+<template>
+  <div class="app-container">
+    <el-row justify="space-between" style="margin-bottom: 10px;">
+      <el-col :span="12">
+        <el-button size="mini" @click="handleAdd">添加应用</el-button>
+      </el-col>
+      <el-col :span="4">
+        <el-input size="mini" v-model="queryParams.appName">
+          <template #append>
+            <el-button :icon="Search" @click="getList"></el-button>
+          </template>
+        </el-input>
+      </el-col>
+    </el-row>
+    <el-row class="table_box">
+      <el-table
+          stripe
+          :data="tableData"
+          :height="tableHeight"
+          style="width: 100%"
+          :header-cell-style="{
+          background: '#ebf3fb',
+          color: '#333',
+          padding: '4px 0',
+          'border-right': '1px solid #fff',
+        }"
+      >
+        <el-table-column type="index" align="center" label="序号" :index="1" width="55"/>
+        <el-table-column show-overflow-tooltip v-for="(param, index) in tableColumns" :key="index" header-align="center"
+                         :align="param.align ? param.align : 'center'" :width="param.width ? param.width : 'auto'"
+                         :prop="param.paramCode" :label="param.paramName">
+          <template #default="scope">
+            <span v-if="!param.copy">{{ scope.row[param.paramCode] }}</span>
+            <span v-else style="cursor: pointer;"
+                  @click="copyParams(scope.row[param.paramCode])">{{ scope.row[param.paramCode] }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column fixed="right" align="center" label="操作" width="160">
+          <template #default="scope">
+            <el-button size="mini" @click="handleUpdate(scope.row)">
+              编辑
+            </el-button>
+            <el-button
+                size="mini"
+                type="danger"
+                @click="handleDelete(scope.row.appId)"
+            >
+              删除
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-row>
+    <pagination
+        v-show="total>0"
+        :total="total"
+        v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize"
+        @pagination="getList"
+    />
+
+    <el-dialog :model-value="dialogVisible" title="添加应用" center>
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="应用名称" prop="appName">
+          <el-input v-model="form.appName"></el-input>
+        </el-form-item>
+        <el-form-item label="应用类型">
+          <el-select v-model="form.appType">
+            <el-option label="Web" value="Web"></el-option>
+            <el-option label="IOS/AndRoid" value="IOS/AndRoid"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="应用地址" prop="url">
+          <el-input v-model="form.url">
+            <template #prepend>
+              <el-select v-model="form.urlPrepend" style="width: 100px">
+                <el-option label="http://" value="http://"></el-option>
+                <el-option label="https://" value="https://"></el-option>
+              </el-select>
+            </template>
+          </el-input>
+        </el-form-item>
+        <el-form-item label="开发者">
+          <el-input v-model="form.appDeveloper"></el-input>
+        </el-form-item>
+      </el-form>
+      <el-row justify="center">
+        <el-button type="primary" @click="onSubmit"> 保存</el-button>
+        <el-button @click="closeDialog">取消</el-button>
+      </el-row>
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import {onMounted, reactive, ref} from "vue";
+import {Search} from '@element-plus/icons-vue';
+import useClipboard from 'vue-clipboard3'
+import {addApp, deletePtApp, getPtApp, updateApp} from "@/api/service/app.js";
+import Pagination from "@/components/Pagination/index.vue";
+import {ElMessage} from "element-plus";
+
+const {toClipboard} = useClipboard()
+const {proxy} = getCurrentInstance();
+const tableHeight = ref(window.innerHeight - 300)
+const tableColumns = ref([
+  {paramCode: 'appName', paramName: '应用名称', width: '240'},
+  {paramCode: 'appType', paramName: '应用类型', width: '120'},
+  {paramCode: 'appDeveloper', paramName: '应用开发商', width: '100'},
+  {paramCode: 'appId', paramName: 'appId', width: '240'},
+  {paramCode: 'appSecret', paramName: 'appSecret', width: '240', copy: true},
+])
+const queryParams = reactive({pageNum: 1, pageSize: 20, appName: "",})
+const tableData = ref([])
+const total = ref(0)
+const dialogVisible = ref(false)
+const formRef = ref(null)
+const httpsReg = new RegExp('https://', 'i')
+const httpReg = new RegExp('http://', 'i')
+const form = reactive({
+  appName: '',
+  url: '',
+  appUrl: '',
+  urlPrepend: 'http://',
+  appDeveloper: '',
+})
+const rules = reactive({
+  appName: [
+    {
+      required: true,
+      message: '请填写信息,该属性为必填项',
+      trigger: 'blur',
+    },
+  ],
+  url: [
+    {
+      required: true,
+      message: '请填写信息,该属性为必填项',
+      trigger: 'blur',
+    },
+  ],
+})
+
+async function copyParams(message) {
+  toClipboard(message).then(() => {
+    proxy.$modal.msgSuccess("复制成功!");
+  })
+}
+
+function getList() {
+  getPtApp(queryParams)
+      .then((r) => {
+        tableData.value = r.rows;
+        total.value = r.total;
+      });
+}
+
+function handleAdd() {
+  dialogVisible.value = true
+  form.appId = null
+  form.appName = ''
+  form.url = ''
+  form.appUrl = ''
+  form.urlPrepend = 'http://'
+  form.appDeveloper = ''
+}
+
+function handleUpdate(row) {
+  dialogVisible.value = true
+  form.appId = row.appId
+  form.appName = row.appName
+  form.appType = row.appType
+  form.appUrl = row.appUrl
+  form.appDeveloper = row.appDeveloper
+
+  if (form.appUrl) {
+    let isHas = form.appUrl.match(httpsReg)
+    if (isHas) {
+      form.urlPrepend = 'https://'
+      form.url = form.appUrl.replace(httpsReg, '')
+    } else {
+      form.url = form.appUrl.replace(httpReg, '')
+    }
+  }
+}
+
+function handleDelete(id) {
+  deletePtApp(id).then((r) => {
+    ElMessage.success('删除应用成功')
+    getList()
+  })
+}
+
+const closeDialog = (value) => {
+  dialogVisible.value = false
+  if (value) {
+    getList()
+  }
+}
+
+const onSubmit = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      form.appUrl = form.urlPrepend + form.url
+      if (form.appId) {
+        updateApp(form)
+      } else {
+        addApp(form)
+      }
+      closeDialog(true)
+      return true
+    } else {
+      return false
+    }
+  })
+}
+
+onMounted(() => {
+  getList()
+});
+</script>

+ 4 - 4
ruoyi-ui/src/views/service/gateway/index.vue

@@ -110,17 +110,17 @@
 
     <!-- 添加或修改服务配置对话框 -->
     <el-dialog :title="title" v-model="open" width="600px" append-to-body>
-      <el-form :model="form" :rules="rules" ref="userRef" label-width="100px">
+      <el-form :model="form" :rules="rules" ref="userRef" label-width="120px">
         <el-form-item label="服务名称" prop="serviceName">
           <el-input v-model="form.serviceName" placeholder="请输入服务名称" maxlength="30"/>
         </el-form-item>
         <el-form-item label="服务地址" prop="uri">
           <el-input v-model="form.uri" placeholder="请输入服务地址" maxlength="200"/>
         </el-form-item>
-        <el-form-item label="服务代理" prop="predicates">
-          <el-input v-model="form.predicates" placeholder="请输入服务地址"/>
+        <el-form-item label="代理地址" prop="predicates">
+          <el-input v-model="form.predicates" placeholder="请输入代理地址"/>
         </el-form-item>
-        <el-form-item label="是否过滤代理" prop="filters">
+        <el-form-item label="过滤代理地址" prop="filters">
           <el-radio-group v-model="form.filters">
             <el-radio value="1">是</el-radio>
             <el-radio value="0">否</el-radio>

File diff suppressed because it is too large
+ 734 - 679
ruoyi-ui/src/views/service/info/editModel.vue


+ 17 - 2
ruoyi-ui/src/views/service/log/index.vue

@@ -47,7 +47,12 @@
       >
         <el-table-column type="index" align="center" label="序号" :index="1"/>
         <el-table-column show-overflow-tooltip align="center" width="150" prop="serviceName" label="服务名称"/>
-        <el-table-column show-overflow-tooltip prop="senText" label="服务地址"/>
+        <el-table-column prop="url" align="center" label="服务地址"/>
+        <el-table-column show-overflow-tooltip align="center" width="100" prop="senText" label="请求参数">
+          <template #default="scope">
+            <span style="cursor: copy;" @click="copyParams(scope.row.senText)">{{ scope.row.senText }}</span>
+          </template>
+        </el-table-column>
         <el-table-column show-overflow-tooltip align="center" width="180" prop="tm" label="请求时间">
           <template #default="scope">
             <i class="el-icon-time"></i>
@@ -76,7 +81,10 @@
 <script setup>
 import {onMounted, reactive, ref} from "vue";
 import {getServiceLogList} from "@/api/service/log.js";
+import useClipboard from 'vue-clipboard3'
 
+const {toClipboard} = useClipboard()
+const {proxy} = getCurrentInstance();
 const tableHeight = ref(window.innerHeight - 300)
 const queryParams = reactive({
   pageNum: 1,
@@ -129,8 +137,14 @@ const shortcuts = ref([
   },
 ])
 
+async function copyParams(message) {
+  toClipboard(message).then(() => {
+    proxy.$modal.msgSuccess("复制成功!");
+  })
+}
+
 function getList() {
-  getServiceLogList()
+  getServiceLogList(queryParams)
       .then((r) => {
         tableData.value = r.rows;
         total.value = r.total;
@@ -145,6 +159,7 @@ watch(() => queryParams.time, value => {
   queryParams.sttm = value[0];
   queryParams.entm = value[1];
 }, {immediate: true})
+
 </script>
 <style scoped>
 .el-row {

Some files were not shown because too many files changed in this diff