فهرست منبع

1.添加 UserKey, UserNode model, 接口和页面
2.更新 StoreNode, UploadChannel 的接口和页面

reghao 2 سال پیش
والد
کامیت
6c58d2a1d7
87فایلهای تغییر یافته به همراه1120 افزوده شده و 1711 حذف شده
  1. 2 2
      oss-web/src/main/java/cn/reghao/oss/web/OssConsoleApplication.java
  2. 0 53
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/AppStatusController.java
  3. 1 1
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/AudioFileController.java
  4. 4 11
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/ImageFileController.java
  5. 1 1
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/MediaController.java
  6. 19 4
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/OssController.java
  7. 0 58
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/UploadChannelController.java
  8. 1 1
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/VideoFileController.java
  9. 39 0
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/KeyAuthController.java
  10. 41 0
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/StoreChannelController.java
  11. 19 37
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/StoreChannelPageController.java
  12. 14 16
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/StoreNodeController.java
  13. 11 16
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/StoreNodePageController.java
  14. 56 0
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/StoreObjectPageController.java
  15. 40 0
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/UserKeyController.java
  16. 52 0
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/UserKeyPageController.java
  17. 41 0
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/UserStoreNodeController.java
  18. 27 19
      oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/UserStoreNodePageController.java
  19. 0 19
      oss-web/src/main/java/cn/reghao/oss/web/app/db/query/AppConfigQuery.java
  20. 0 63
      oss-web/src/main/java/cn/reghao/oss/web/app/db/query/impl/AppConfigQueryImpl.java
  21. 0 21
      oss-web/src/main/java/cn/reghao/oss/web/app/db/repository/AppConfigRepository.java
  22. 3 0
      oss-web/src/main/java/cn/reghao/oss/web/app/db/repository/StoreNodeRepository.java
  23. 7 2
      oss-web/src/main/java/cn/reghao/oss/web/app/db/repository/UploadChannelRepository.java
  24. 17 0
      oss-web/src/main/java/cn/reghao/oss/web/app/db/repository/UserKeyRepository.java
  25. 12 0
      oss-web/src/main/java/cn/reghao/oss/web/app/db/repository/UserNodeRepository.java
  26. 15 0
      oss-web/src/main/java/cn/reghao/oss/web/app/model/dto/KeyAuthDto.java
  27. 1 0
      oss-web/src/main/java/cn/reghao/oss/web/app/model/dto/StoreNodeUpdateDto.java
  28. 17 0
      oss-web/src/main/java/cn/reghao/oss/web/app/model/dto/UserKeyDto.java
  29. 18 0
      oss-web/src/main/java/cn/reghao/oss/web/app/model/dto/UserNodeDto.java
  30. 0 56
      oss-web/src/main/java/cn/reghao/oss/web/app/model/po/AppConfig.java
  31. 2 1
      oss-web/src/main/java/cn/reghao/oss/web/app/model/po/StoreNode.java
  32. 7 3
      oss-web/src/main/java/cn/reghao/oss/web/app/model/po/UploadChannel.java
  33. 27 0
      oss-web/src/main/java/cn/reghao/oss/web/app/model/po/UserKey.java
  34. 29 0
      oss-web/src/main/java/cn/reghao/oss/web/app/model/po/UserNode.java
  35. 63 13
      oss-web/src/main/java/cn/reghao/oss/web/app/service/OssService.java
  36. 10 0
      oss-web/src/main/java/cn/reghao/oss/web/app/service/StoreNodeService.java
  37. 25 2
      oss-web/src/main/java/cn/reghao/oss/web/app/service/UploadChannelService.java
  38. 85 0
      oss-web/src/main/java/cn/reghao/oss/web/app/service/UserKeyService.java
  39. 70 0
      oss-web/src/main/java/cn/reghao/oss/web/app/service/UserNodeService.java
  40. 3 6
      oss-web/src/main/java/cn/reghao/oss/web/app/service/media/ImageService.java
  41. 2 2
      oss-web/src/main/java/cn/reghao/oss/web/config/spring/AppLifecycle.java
  42. 1 1
      oss-web/src/main/resources/application-dev.yml
  43. 1 1
      oss-web/src/main/resources/application-test.yml
  44. 1 1
      oss-web/src/main/resources/application.yml
  45. 0 46
      oss-web/src/main/resources/templates/app/config/build/builddir.html
  46. 0 78
      oss-web/src/main/resources/templates/app/config/compiler/add.html
  47. 0 13
      oss-web/src/main/resources/templates/app/config/compiler/detail.html
  48. 0 44
      oss-web/src/main/resources/templates/app/config/compiler/edit.html
  49. 0 60
      oss-web/src/main/resources/templates/app/config/compiler/index.html
  50. 0 71
      oss-web/src/main/resources/templates/app/config/packer/add.html
  51. 0 28
      oss-web/src/main/resources/templates/app/config/packer/detail.html
  52. 0 45
      oss-web/src/main/resources/templates/app/config/packer/edit.html
  53. 0 57
      oss-web/src/main/resources/templates/app/config/packer/index.html
  54. 0 82
      oss-web/src/main/resources/templates/app/config/repoauth/add.html
  55. 0 35
      oss-web/src/main/resources/templates/app/config/repoauth/detail.html
  56. 0 57
      oss-web/src/main/resources/templates/app/config/repoauth/edit.html
  57. 0 57
      oss-web/src/main/resources/templates/app/config/repoauth/index.html
  58. 0 82
      oss-web/src/main/resources/templates/app/stat/applog.html
  59. 0 144
      oss-web/src/main/resources/templates/app/stat/log.html
  60. 0 97
      oss-web/src/main/resources/templates/app/stat/log1.html
  61. 0 205
      oss-web/src/main/resources/templates/app/stat/nginxlog.html
  62. 0 19
      oss-web/src/main/resources/templates/app/type/add.html
  63. 0 18
      oss-web/src/main/resources/templates/app/type/index.html
  64. 15 1
      oss-web/src/main/resources/templates/channel/add.html
  65. 0 0
      oss-web/src/main/resources/templates/channel/deploy.html
  66. 5 3
      oss-web/src/main/resources/templates/channel/index.html
  67. 0 0
      oss-web/src/main/resources/templates/channel/log/buildconfig.html
  68. 0 0
      oss-web/src/main/resources/templates/channel/log/buildlog.html
  69. 0 0
      oss-web/src/main/resources/templates/channel/log/buildresult.html
  70. 0 0
      oss-web/src/main/resources/templates/channel/log/buildtime.html
  71. 0 0
      oss-web/src/main/resources/templates/node/add.html
  72. 0 0
      oss-web/src/main/resources/templates/node/copy.html
  73. 0 0
      oss-web/src/main/resources/templates/node/deploy/add.html
  74. 0 0
      oss-web/src/main/resources/templates/node/deploy/detail.html
  75. 0 0
      oss-web/src/main/resources/templates/node/deploy/edit.html
  76. 0 0
      oss-web/src/main/resources/templates/node/deploy/index.html
  77. 0 0
      oss-web/src/main/resources/templates/node/detail.html
  78. 1 1
      oss-web/src/main/resources/templates/node/edit.html
  79. 5 6
      oss-web/src/main/resources/templates/node/index.html
  80. 11 0
      oss-web/src/main/resources/templates/object/add.html
  81. 67 0
      oss-web/src/main/resources/templates/object/deploy.html
  82. 102 0
      oss-web/src/main/resources/templates/object/index.html
  83. 35 0
      oss-web/src/main/resources/templates/userkey/add.html
  84. 81 0
      oss-web/src/main/resources/templates/userkey/index1.html
  85. 3 31
      oss-web/src/main/resources/templates/usernode/add.html
  86. 9 19
      oss-web/src/main/resources/templates/usernode/index1.html
  87. 2 2
      oss-web/src/test/java/AccountTest.java

+ 2 - 2
oss-web/src/main/java/cn/reghao/oss/web/OssWebApplication.java → oss-web/src/main/java/cn/reghao/oss/web/OssConsoleApplication.java

@@ -8,8 +8,8 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 @SpringBootApplication
 @EnableJpaRepositories
 @EntityScan({"cn.reghao.oss.web"})
-public class OssWebApplication {
+public class OssConsoleApplication {
 	public static void main(String[] args) {
-		SpringApplication.run(OssWebApplication.class, args);
+		SpringApplication.run(OssConsoleApplication.class, args);
 	}
 }

+ 0 - 53
oss-web/src/main/java/cn/reghao/oss/web/app/controller/AppStatusController.java

@@ -1,53 +0,0 @@
-package cn.reghao.oss.web.app.controller;
-
-import cn.reghao.jutil.jdk.result.Result;
-import cn.reghao.jutil.jdk.result.ResultStatus;
-import cn.reghao.jutil.jdk.result.WebResult;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * @author reghao
- * @date 2020-02-28 11:33:23
- */
-@Slf4j
-@Api(tags = "应用状态管理接口")
-@RestController
-@RequestMapping("/api/app/status")
-public class AppStatusController {
-    @ApiOperation(value = "重启应用")
-    @PostMapping(value = "/restart/{appId}/{machineId}", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String restart(@PathVariable("appId") String appId, @PathVariable("machineId") String machineId) throws Exception {
-        return WebResult.result(Result.result(ResultStatus.SUCCESS, appId + " 正在重启,请 10s 后刷新页面查看最新状态"));
-    }
-
-    @ApiOperation(value = "停止应用")
-    @PostMapping(value = "/stop/{appId}/{machineId}", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String stop(@PathVariable("appId") String appId, @PathVariable("machineId") String machineId) throws Exception {
-        return WebResult.result(Result.result(ResultStatus.SUCCESS, appId + " 正在停止,请稍后刷新页面"));
-    }
-
-    @ApiOperation(value = "启动应用")
-    @PostMapping(value = "/start/{appId}/{machineId}", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String start(@PathVariable("appId") String appId, @PathVariable("machineId") String machineId) throws Exception {
-        return WebResult.result(Result.result(ResultStatus.SUCCESS, appId + " 正在启动,请 10s 后刷新页面查看最新状态"));
-    }
-
-    @ApiOperation(value = "应用当前状态")
-    @GetMapping(value = "/{appId}/{machineId}", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String status(@PathVariable("appId") String appId, @PathVariable("machineId") String machineId) {
-        String msg = String.format("正在获取 %s 的状态,请 10s 后刷新页面查看", appId);
-        return WebResult.result(Result.result(ResultStatus.SUCCESS, msg));
-    }
-
-    @ApiOperation(value = "应用历史日志")
-    @GetMapping(value = "/log", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String getAppLog() {
-        return WebResult.success();
-    }
-}

+ 1 - 1
oss-web/src/main/java/cn/reghao/oss/web/app/controller/AudioFileController.java

@@ -21,7 +21,7 @@ import java.util.List;
  */
 @Api(tags = "音频文件接口")
 @RestController
-@RequestMapping("/api/media/audio")
+@RequestMapping("/api/oss/media/audio")
 public class AudioFileController {
     private final AudioService audioService;
 

+ 4 - 11
oss-web/src/main/java/cn/reghao/oss/web/app/controller/ImageFileController.java

@@ -17,7 +17,7 @@ import java.util.Set;
  */
 @Api(tags = "图片文件接口")
 @RestController
-@RequestMapping("/api/media/image")
+@RequestMapping("/api/oss/media/image")
 public class ImageFileController {
     private final ImageService imageService;
 
@@ -41,16 +41,9 @@ public class ImageFileController {
 
     @ApiOperation(value = "获取图片文件 url")
     @GetMapping(value = "/url", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String getImageUrl(@RequestParam("channelId") int channelId,
-                              @RequestParam("imageFileId") String imageFileId,
-                              @RequestParam(value = "loginUser", required = false) Long loginUser) {
-        ImageUrlDto imageUrlDto;
-        if (loginUser != null) {
-            imageUrlDto = imageService.getImageUrl(imageFileId, loginUser, channelId);
-        } else {
-            imageUrlDto = imageService.getImageUrl(channelId, imageFileId);
-        }
-
+    public String getImageUrl(@RequestParam("channelName") String channelName,
+                              @RequestParam("imageFileId") String imageFileId) {
+        ImageUrlDto imageUrlDto = imageService.getImageUrl(channelName, imageFileId);
         return WebResult.success(imageUrlDto);
     }
 

+ 1 - 1
oss-web/src/main/java/cn/reghao/oss/web/app/controller/MediaController.java

@@ -16,7 +16,7 @@ import java.util.Set;
  */
 @Api(tags = "媒体接口")
 @RestController
-@RequestMapping("/api/media")
+@RequestMapping("/api/oss/media")
 public class MediaController {
     private final MediaService mediaService;
 

+ 19 - 4
oss-web/src/main/java/cn/reghao/oss/web/app/controller/OssController.java

@@ -1,8 +1,8 @@
 package cn.reghao.oss.web.app.controller;
 
 import cn.reghao.jutil.jdk.result.WebResult;
-import cn.reghao.oss.api.constant.UploadChannel;
 import cn.reghao.oss.api.dto.DownloadUrl;
+import cn.reghao.oss.api.dto.ObjectChannel;
 import cn.reghao.oss.api.dto.ObjectInfo;
 import cn.reghao.oss.api.dto.ServerInfo;
 import cn.reghao.oss.web.app.service.OssService;
@@ -14,6 +14,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.List;
+
 /**
  * @author reghao
  * @date 2024-02-23 09:27:36
@@ -30,12 +32,25 @@ public class OssController {
 
     @ApiOperation(value = "获取 oss-store 节点")
     @GetMapping(value = "/server/info", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String getServerInfo(@RequestParam("userId") Long userId, @RequestParam("channelId") Integer channelId) {
-        String channelPrefix = UploadChannel.getUploadChannel(channelId).getPrefix();
-        ServerInfo serverInfo = ossService.getServerInfo(channelPrefix, userId, channelId);
+    public String getServerInfo(@RequestParam("channelId") int channelId) throws Exception {
+        ServerInfo serverInfo = ossService.getServerInfo(channelId);
         return WebResult.success(serverInfo);
     }
 
+    @ApiOperation(value = "获取所有的 UploadChannel")
+    @GetMapping(value = "/channels", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getChannels(@RequestParam("nodeAddr") String nodeAddr) {
+        List<ObjectChannel> list = ossService.getObjectChannels(nodeAddr);
+        return WebResult.success(list);
+    }
+
+    @ApiOperation(value = "获取某个 UploadChannel")
+    @GetMapping(value = "/channel", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getChannel(@RequestParam("nodeAddr") String nodeAddr, @RequestParam("channelId") int channelId) {
+        ObjectChannel objectChannel = ossService.getObjectChannel(nodeAddr, channelId);
+        return WebResult.success(objectChannel);
+    }
+
     @ApiOperation(value = "获取对象信息")
     @GetMapping(value = "/object/info", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getObjectInfo(@RequestParam("objectId") String objectId) {

+ 0 - 58
oss-web/src/main/java/cn/reghao/oss/web/app/controller/UploadChannelController.java

@@ -1,58 +0,0 @@
-package cn.reghao.oss.web.app.controller;
-
-import cn.reghao.jutil.jdk.result.WebResult;
-import cn.reghao.oss.web.app.model.dto.UploadChannelDto;
-import cn.reghao.oss.web.app.service.UploadChannelService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.MediaType;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-/**
- * @author reghao
- * @date 2024-02-23 15:05:30
- */
-@Slf4j
-@Api(tags = "上传通道接口")
-@RestController
-@RequestMapping("/api/channel/upload")
-public class UploadChannelController {
-    private final UploadChannelService uploadChannelService;
-
-    public UploadChannelController(UploadChannelService uploadChannelService) {
-        this.uploadChannelService = uploadChannelService;
-    }
-
-    @ApiOperation(value = "添加上传通道")
-    @PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String buildAndDeploy(@Validated UploadChannelDto uploadChannelDto) {
-        uploadChannelService.add(uploadChannelDto);
-        return WebResult.success();
-    }
-
-    @ApiOperation(value = "构建应用")
-    @PostMapping(value = "/build/appId", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String build() throws Exception {
-        return WebResult.successWithMsg("构建请求已提交");
-    }
-
-    @ApiOperation(value = "部署应用")
-    @PostMapping(value = "/deploy", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String deploy() {
-        return WebResult.success();
-    }
-
-    @ApiOperation(value = "重置应用构建状态")
-    @PostMapping(value = "/reset", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String resetState() {
-        return WebResult.success();
-    }
-
-    @ApiOperation(value = "webhook 自动构建部署")
-    @PostMapping("/hook")
-    public String hook() throws Exception {
-        return WebResult.success();
-    }
-}

+ 1 - 1
oss-web/src/main/java/cn/reghao/oss/web/app/controller/VideoFileController.java

@@ -18,7 +18,7 @@ import java.util.List;
  */
 @Api(tags = "视频文件接口")
 @RestController
-@RequestMapping("/api/media/video")
+@RequestMapping("/api/oss/media/video")
 public class VideoFileController {
     private final VideoService videoService;
 

+ 39 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/KeyAuthController.java

@@ -0,0 +1,39 @@
+package cn.reghao.oss.web.app.controller.page;
+
+import cn.reghao.jutil.jdk.result.Result;
+import cn.reghao.jutil.jdk.result.WebResult;
+import cn.reghao.oss.web.app.model.dto.KeyAuthDto;
+import cn.reghao.oss.web.app.service.UserKeyService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author reghao
+ * @date 2024-02-27 11:32:23
+ */
+@Api(tags = "oss key 认证接口")
+@RestController
+@RequestMapping("/api/oss/key")
+public class KeyAuthController {
+    private final UserKeyService userKeyService;
+
+    public KeyAuthController(UserKeyService userKeyService) {
+        this.userKeyService = userKeyService;
+    }
+
+    @ApiOperation(value = "认证 oss key")
+    @PostMapping(value = "/auth", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String authKey(@Validated KeyAuthDto keyAuthDto) {
+        Result result = userKeyService.auth(keyAuthDto);
+        if (result.getCode() == 0) {
+            return WebResult.success(result.getData());
+        }
+
+        return WebResult.result(result);
+    }
+}

+ 41 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/StoreChannelController.java

@@ -0,0 +1,41 @@
+package cn.reghao.oss.web.app.controller.page;
+
+import cn.reghao.jutil.jdk.result.WebResult;
+import cn.reghao.oss.web.app.model.dto.UploadChannelDto;
+import cn.reghao.oss.web.app.service.UploadChannelService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author reghao
+ * @date 2024-02-23 15:05:30
+ */
+@Slf4j
+@Api(tags = "上传通道接口")
+@RestController
+@RequestMapping("/api/store/channel")
+public class StoreChannelController {
+    private final UploadChannelService uploadChannelService;
+
+    public StoreChannelController(UploadChannelService uploadChannelService) {
+        this.uploadChannelService = uploadChannelService;
+    }
+
+    @ApiOperation(value = "添加上传通道")
+    @PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String addUploadChannel(@Validated UploadChannelDto uploadChannelDto) {
+        uploadChannelService.add(uploadChannelDto);
+        return WebResult.success();
+    }
+
+    @ApiOperation(value = "删除上传通道")
+    @DeleteMapping(value = "/delete", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String deleteUploadChannel(@Validated UploadChannelDto uploadChannelDto) {
+        uploadChannelService.add(uploadChannelDto);
+        return WebResult.success();
+    }
+}

+ 19 - 37
oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/UploadChannelPageController.java → oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/StoreChannelPageController.java

@@ -3,7 +3,7 @@ package cn.reghao.oss.web.app.controller.page;
 import cn.reghao.oss.web.app.db.repository.UploadChannelRepository;
 import cn.reghao.oss.web.app.model.po.UploadChannel;
 import cn.reghao.oss.web.app.model.vo.KeyValue;
-import cn.reghao.oss.web.app.service.StoreNodeService;
+import cn.reghao.oss.web.app.service.UserNodeService;
 import cn.reghao.oss.web.util.DefaultSetting;
 import cn.reghao.oss.web.util.db.PageSort;
 import io.swagger.annotations.Api;
@@ -24,18 +24,18 @@ import java.util.stream.Collectors;
 @Slf4j
 @Api(tags = "上传通道页面")
 @Controller
-@RequestMapping("/app/bd")
-public class UploadChannelPageController {
+@RequestMapping("/store/channel")
+public class StoreChannelPageController {
     private final UploadChannelRepository uploadChannelRepository;
-    private final StoreNodeService storeNodeService;
+    private final UserNodeService userNodeService;
 
-    public UploadChannelPageController(UploadChannelRepository uploadChannelRepository, StoreNodeService storeNodeService) {
+    public StoreChannelPageController(UploadChannelRepository uploadChannelRepository, UserNodeService userNodeService) {
         this.uploadChannelRepository = uploadChannelRepository;
-        this.storeNodeService = storeNodeService;
+        this.userNodeService = userNodeService;
     }
 
     @ApiOperation(value = "上传通道列表页面")
-    @GetMapping(value = "/build")
+    @GetMapping(value = "/list")
     public String index(@RequestParam(value = "env", required = false) String env,
                         @RequestParam(value = "type", required = false) String type,
                         @RequestParam(value = "appName", required = false) String appName, Model model) throws Exception {
@@ -54,20 +54,29 @@ public class UploadChannelPageController {
         model.addAttribute("type", type);
         model.addAttribute("page", page);
         model.addAttribute("list", page.getContent());
-        return "/app/bd/index";
+        return "/channel/index";
     }
 
     @ApiOperation(value = "新增上传通道页面")
     @GetMapping("/add")
     public String deployPage(Model model) {
+        List<KeyValue> objectTypes = new ArrayList<>();
+        objectTypes.add(new KeyValue("application/octet-stream", "other"));
+        objectTypes.add(new KeyValue("image/jpeg", "image"));
+        objectTypes.add(new KeyValue("text/plain", "text"));
+        objectTypes.add(new KeyValue("video/mp4", "video"));
+        objectTypes.add(new KeyValue("audio/wav", "audio"));
+        model.addAttribute("objectTypes", objectTypes);
+
         List<KeyValue> list1 = new ArrayList<>();
         list1.add(new KeyValue(1024L*1024*2+"", "2MiB"));
         list1.add(new KeyValue(1024L*1024*10+"", "10MiB"));
         list1.add(new KeyValue(1024L*1024*100+"", "100MiB"));
         list1.add(new KeyValue(1024L*1024*1024+"", "1GiB"));
         list1.add(new KeyValue(1024L*1024*1024*10+"", "10GiB"));
+        list1.add(new KeyValue(1024L*1024*1024*20+"", "20GiB"));
 
-        List<KeyValue> list = storeNodeService.getStoreNodes().stream()
+        List<KeyValue> list = userNodeService.getUserStoreNodes().stream()
                 .map(storeNode -> {
                     String domain = storeNode.getDomain();
                     return new KeyValue(domain, domain);
@@ -75,33 +84,6 @@ public class UploadChannelPageController {
 
         model.addAttribute("sizeList", list1);
         model.addAttribute("storeNodes", list);
-        return "/app/bd/add";
-    }
-
-    @ApiOperation(value = "构建结果页面")
-    @GetMapping("/build/result")
-    public String buildLogResultPage(@RequestParam("buildLogId") String buildLogId, Model model) {
-        List<String> list = new ArrayList<>();
-        list.add("构建结果暂不可用");
-        model.addAttribute("list", list);
-        return "/app/bd/log/buildresult";
-    }
-
-    @ApiOperation(value = "历史构建页面")
-    @GetMapping("/build/history")
-    public String buildLogPage(@RequestParam("appId") String appId, Model model) {
-        return "/app/bd/log/buildlog";
-    }
-
-    @ApiOperation(value = "构建配置页面")
-    @GetMapping("/build/config")
-    public String buildConfigPage(@RequestParam("buildLogId") String buildLogId, Model model) {
-        return "/app/bd/log/buildconfig";
-    }
-
-    @ApiOperation(value = "构建耗时页面")
-    @GetMapping("/build/consumed")
-    public String buildTimePage(@RequestParam("buildLogId") String buildLogId, Model model) {
-        return "/app/bd/log/buildtime";
+        return "/channel/add";
     }
 }

+ 14 - 16
oss-web/src/main/java/cn/reghao/oss/web/app/controller/StoreNodeController.java → oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/StoreNodeController.java

@@ -1,8 +1,7 @@
-package cn.reghao.oss.web.app.controller;
+package cn.reghao.oss.web.app.controller.page;
 
 import cn.reghao.jutil.jdk.result.Result;
 import cn.reghao.oss.web.app.model.dto.StoreNodeUpdateDto;
-import cn.reghao.oss.web.app.model.po.AppConfig;
 import cn.reghao.jutil.jdk.result.WebResult;
 import cn.reghao.oss.web.app.model.po.StoreNode;
 import cn.reghao.oss.web.app.service.StoreNodeService;
@@ -13,8 +12,6 @@ import org.springframework.http.MediaType;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.List;
-
 /**
  * @author reghao
  * @date 2024-02-23 11:29:14
@@ -22,7 +19,7 @@ import java.util.List;
 @Slf4j
 @Api(tags = "存储节点数据接口")
 @RestController
-@RequestMapping("/api/oss/store")
+@RequestMapping("/api/oss/store/node")
 public class StoreNodeController {
     private final StoreNodeService storeNodeService;
 
@@ -30,29 +27,30 @@ public class StoreNodeController {
         this.storeNodeService = storeNodeService;
     }
 
-    @ApiOperation(value = "添加应用配置")
-    @PostMapping(value = "/node", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String addAppConfig(@RequestBody @Validated StoreNode storeNode) {
+    @ApiOperation(value = "添加存储节点")
+    @PostMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String addStoreNode(@RequestBody @Validated StoreNode storeNode) {
         storeNodeService.add(storeNode);
         return WebResult.success();
     }
 
-    @ApiOperation(value = "修改应用配置")
+    @ApiOperation(value = "设置存储节点的域名")
     @PostMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String updateAppConfig(@Validated StoreNodeUpdateDto storeNodeUpdateDto) {
+    public String updateStoreNodeDomain(@Validated StoreNodeUpdateDto storeNodeUpdateDto) {
         Result result = storeNodeService.updateDomain(storeNodeUpdateDto);
         return WebResult.result(result);
     }
 
-    @ApiOperation(value = "删除应用配置")
+    @ApiOperation(value = "删除存储节点")
     @DeleteMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String deleteAppConfig(@PathVariable("id") AppConfig app) {
-        String appId = app.getAppId();
-        return WebResult.success();
+    public String deleteStoreNode(@PathVariable("id") Integer nodeId) {
+        Result result = storeNodeService.delete(nodeId);
+        return WebResult.result(result);
     }
 
-    @PostMapping(value = "/enable", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String deleteAll(@RequestParam(value = "ids") List<String> appIds) {
+    @ApiOperation(value = "设置存储节点状态")
+    @PostMapping(value = "/status/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String setStatus(@PathVariable("id") Integer nodeId) {
         return WebResult.success();
     }
 }

+ 11 - 16
oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/StoreNodePageController.java

@@ -1,14 +1,11 @@
 package cn.reghao.oss.web.app.controller.page;
 
 import cn.reghao.oss.web.app.db.repository.StoreNodeRepository;
-import cn.reghao.oss.web.app.model.po.AppConfig;
 import cn.reghao.oss.web.app.model.po.StoreNode;
 import cn.reghao.oss.web.util.DefaultSetting;
 import cn.reghao.oss.web.util.db.PageSort;
-import cn.reghao.oss.web.app.db.query.AppConfigQuery;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageImpl;
 import org.springframework.data.domain.PageRequest;
@@ -22,21 +19,18 @@ import java.util.*;
  * @author reghao
  * @date 2024-02-23 11:29:14
  */
-@Slf4j
-@Api(tags = "应用配置页面")
+@Api(tags = "存储节点页面")
 @Controller
-@RequestMapping("/app/config/app")
+@RequestMapping("/store/node")
 public class StoreNodePageController {
-    private final AppConfigQuery appConfigQuery;
     private final StoreNodeRepository storeNodeRepository;
 
-    public StoreNodePageController(AppConfigQuery appConfigQuery, StoreNodeRepository storeNodeRepository) {
-        this.appConfigQuery = appConfigQuery;
+    public StoreNodePageController(StoreNodeRepository storeNodeRepository) {
         this.storeNodeRepository = storeNodeRepository;
     }
 
     @ApiOperation(value = "存储节点列表页面")
-    @GetMapping
+    @GetMapping("/list")
     public String appConfigPage(@RequestParam(value = "env", required = false) String env,
                                 @RequestParam(value = "type", required = false) String type,
                                 @RequestParam(value = "appName", required = false) String appName,
@@ -52,14 +46,15 @@ public class StoreNodePageController {
         if (appName != null) {
             Map<String, String> map = new HashMap<>();
             map.put("appName", appName);
-            List<AppConfig> list = appConfigQuery.query(map);
-            Page<AppConfig> page = new PageImpl<>(list);
+            //List<AppConfig> list = appConfigQuery.query(map);
+            List<String> list = Collections.emptyList();
+            Page<String> page = new PageImpl<>(list);
 
             model.addAttribute("env", env);
             model.addAttribute("type", type);
             model.addAttribute("page", page);
             model.addAttribute("list", page.getContent());
-            return "/app/config/app/index";
+            return "/node/index";
         }
 
         PageRequest pageRequest = PageSort.pageRequest();
@@ -69,14 +64,14 @@ public class StoreNodePageController {
         model.addAttribute("type", type);
         model.addAttribute("page", page);
         model.addAttribute("list", page.getContent());
-        return "/app/config/app/index";
+        return "/node/index";
     }
 
     @ApiOperation(value = "存储节点域名设置页面")
     @GetMapping("/domain/{id}")
     public String editAppConfigPage(@PathVariable("id") StoreNode storeNode, Model model) {
         model.addAttribute("storeNode", storeNode);
-        return "/app/config/app/edit";
+        return "/node/edit";
     }
 
     @ApiOperation(value = "存储节点详情页面")
@@ -84,6 +79,6 @@ public class StoreNodePageController {
     public String appConfigPage(@PathVariable("id") Integer id, Model model) {
         StoreNode storeNode = storeNodeRepository.findById(id).orElse(null);
         model.addAttribute("storeNode", storeNode);
-        return "/app/config/app/detail";
+        return "/node/detail";
     }
 }

+ 56 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/StoreObjectPageController.java

@@ -0,0 +1,56 @@
+package cn.reghao.oss.web.app.controller.page;
+
+import cn.reghao.oss.web.app.db.repository.UploadChannelRepository;
+import cn.reghao.oss.web.app.model.po.UploadChannel;
+import cn.reghao.oss.web.app.service.StoreNodeService;
+import cn.reghao.oss.web.util.DefaultSetting;
+import cn.reghao.oss.web.util.db.PageSort;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * @author reghao
+ * @date 2024-02-27 09:12:14
+ */
+@Api(tags = "存储对象页面")
+@Controller
+@RequestMapping("/store/object")
+public class StoreObjectPageController {
+    private final UploadChannelRepository uploadChannelRepository;
+    private final StoreNodeService storeNodeService;
+
+    public StoreObjectPageController(UploadChannelRepository uploadChannelRepository, StoreNodeService storeNodeService) {
+        this.uploadChannelRepository = uploadChannelRepository;
+        this.storeNodeService = storeNodeService;
+    }
+
+    @ApiOperation(value = "文件列表页面")
+    @GetMapping(value = "/list")
+    public String index(@RequestParam(value = "env", required = false) String env,
+                        @RequestParam(value = "type", required = false) String type,
+                        @RequestParam(value = "appName", required = false) String appName, Model model) throws Exception {
+        if (env == null) {
+            env = DefaultSetting.getDefaultAppEnv();
+        }
+
+        if (type == null) {
+            type = DefaultSetting.getDefaultAppType();
+        }
+
+        PageRequest pageRequest = PageSort.pageRequest();
+        Page<UploadChannel> page = uploadChannelRepository.findAll(pageRequest);
+
+        model.addAttribute("env", env);
+        model.addAttribute("type", type);
+        model.addAttribute("page", page);
+        model.addAttribute("list", page.getContent());
+        return "/object/index";
+    }
+}

+ 40 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/UserKeyController.java

@@ -0,0 +1,40 @@
+package cn.reghao.oss.web.app.controller.page;
+
+import cn.reghao.jutil.jdk.result.Result;
+import cn.reghao.jutil.jdk.result.WebResult;
+import cn.reghao.oss.web.app.model.dto.UserKeyDto;
+import cn.reghao.oss.web.app.service.UserKeyService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author reghao
+ * @date 2024-02-27 10:59:07
+ */
+@Api(tags = "用户帐号接口")
+@RestController
+@RequestMapping("/api/store/my/key")
+public class UserKeyController {
+    private final UserKeyService userKeyService;
+
+    public UserKeyController(UserKeyService userKeyService) {
+        this.userKeyService = userKeyService;
+    }
+
+    @ApiOperation(value = "创建帐号")
+    @PostMapping(value = "/create", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String create(@Validated UserKeyDto userKeyDto) {
+        Result result = userKeyService.create(userKeyDto);
+        return WebResult.result(result);
+    }
+
+    @ApiOperation(value = "删除帐号")
+    @DeleteMapping(value = "/delete/{accessKeyId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String delete(@PathVariable("accessKeyId") String accessKeyId) {
+        userKeyService.delete(accessKeyId);
+        return WebResult.success();
+    }
+}

+ 52 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/UserKeyPageController.java

@@ -0,0 +1,52 @@
+package cn.reghao.oss.web.app.controller.page;
+
+import cn.reghao.oss.web.app.model.po.UserKey;
+import cn.reghao.oss.web.app.model.vo.KeyValue;
+import cn.reghao.oss.web.app.service.StoreNodeService;
+import cn.reghao.oss.web.app.service.UserKeyService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author reghao
+ * @date 2024-02-27 10:24:31
+ */
+@Api(tags = "我的帐号页面")
+@Controller
+@RequestMapping("/store/my/key")
+public class UserKeyPageController {
+    private final StoreNodeService storeNodeService;
+    private final UserKeyService userKeyService;
+
+    public UserKeyPageController(StoreNodeService storeNodeService, UserKeyService userKeyService) {
+        this.storeNodeService = storeNodeService;
+        this.userKeyService = userKeyService;
+    }
+
+    @ApiOperation(value = "我的帐号页面")
+    @GetMapping(value = "")
+    public String userKeyPage(Model model) {
+        List<UserKey> list = userKeyService.getUserKeys();
+        model.addAttribute("list", list);
+        return "/userkey/index1";
+    }
+
+    @ApiOperation(value = "帐号创建页面")
+    @GetMapping(value = "/add")
+    public String userKeyAddPage(Model model) {
+        List<KeyValue> storeNodes = storeNodeService.getStoreNodes().stream()
+                .map(storeNode -> {
+                    String domain = storeNode.getDomain();
+                    return new KeyValue(domain, domain);
+                }).collect(Collectors.toList());
+        model.addAttribute("storeNodes", storeNodes);
+        return "/userkey/add";
+    }
+}

+ 41 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/UserStoreNodeController.java

@@ -0,0 +1,41 @@
+package cn.reghao.oss.web.app.controller.page;
+
+import cn.reghao.jutil.jdk.result.Result;
+import cn.reghao.jutil.jdk.result.WebResult;
+import cn.reghao.oss.web.app.model.dto.UserNodeDto;
+import cn.reghao.oss.web.app.model.po.StoreNode;
+import cn.reghao.oss.web.app.service.UserNodeService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author reghao
+ * @date 2024-02-27 09:40:54
+ */
+@Api(tags = "用户存储节点数据接口")
+@RestController
+@RequestMapping("/api/store/my")
+public class UserStoreNodeController {
+    private final UserNodeService userNodeService;
+
+    public UserStoreNodeController(UserNodeService userNodeService) {
+        this.userNodeService = userNodeService;
+    }
+
+    @ApiOperation(value = "添加存储节点")
+    @PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String addUserNode(@Validated UserNodeDto userNodeDto) {
+        Result result = userNodeService.add(userNodeDto);
+        return WebResult.result(result);
+    }
+
+    @ApiOperation(value = "删除存储节点")
+    @DeleteMapping(value = "/delete/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String deleteUserNode(@PathVariable("id") Integer nodeId) {
+        userNodeService.delete(nodeId);
+        return WebResult.success();
+    }
+}

+ 27 - 19
oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/StatusPageController.java → oss-web/src/main/java/cn/reghao/oss/web/app/controller/page/UserStoreNodePageController.java

@@ -1,14 +1,11 @@
 package cn.reghao.oss.web.app.controller.page;
 
-import cn.reghao.oss.web.util.DefaultSetting;
-import cn.reghao.oss.web.util.db.PageSort;
-import cn.reghao.jutil.jdk.db.PageList;
+import cn.reghao.oss.web.app.model.po.StoreNode;
+import cn.reghao.oss.web.app.model.vo.KeyValue;
+import cn.reghao.oss.web.app.service.StoreNodeService;
+import cn.reghao.oss.web.app.service.UserNodeService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.PageRequest;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -17,41 +14,52 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * @author reghao
  * @date 2019-08-30 18:49:15
  */
-@Slf4j
 @Api(tags = "我的节点页面")
 @Controller
-@RequestMapping("/app/stat")
-public class StatusPageController {
+@RequestMapping("/store/my")
+public class UserStoreNodePageController {
+    private final UserNodeService userNodeService;
+    private final StoreNodeService storeNodeService;
+
+    public UserStoreNodePageController(UserNodeService userNodeService, StoreNodeService storeNodeService) {
+        this.userNodeService = userNodeService;
+        this.storeNodeService = storeNodeService;
+    }
+
     @ApiOperation(value = "我的节点列表页面")
     @GetMapping(value = "/list")
-    public String statusPage1(@RequestParam(value = "env", required = false) String env,
+    public String userNodesPage(@RequestParam(value = "env", required = false) String env,
                               @RequestParam(value = "appType", required = false) String appType,
-                              @RequestParam(value = "status", required = false) Boolean status,
-                              @RequestParam(value = "appName", required = false) String appName,
                               Model model) {
+        List<StoreNode> list = userNodeService.getUserStoreNodes();
         model.addAttribute("env", env);
         model.addAttribute("type", appType);
-        model.addAttribute("status", status);
-        model.addAttribute("page", Page.empty());
-        model.addAttribute("list", Collections.emptyList());
-        return "/app/stat/index1";
+        model.addAttribute("list", list);
+        return "/usernode/index1";
     }
 
     @ApiOperation(value = "我的节点创建页面")
     @GetMapping(value = "/add")
     public String statusPage(Model model) {
-        return "/app/stat/index2";
+        List<KeyValue> storeNodes = storeNodeService.getStoreNodes().stream()
+                .map(storeNode -> {
+                    String domain = storeNode.getDomain();
+                    return new KeyValue(domain, domain);
+                }).collect(Collectors.toList());
+        model.addAttribute("storeNodes", storeNodes);
+        return "/usernode/add";
     }
 
     @ApiOperation(value = "应用运行状态详情页面")
     @GetMapping(value = "/detail/{appId}")
     public String statusPage2(@PathVariable(value = "appId") String appId, Model model) {
         model.addAttribute("list", Collections.emptyList());
-        return "/app/stat/index2";
+        return "/usernode/index1";
     }
 }

+ 0 - 19
oss-web/src/main/java/cn/reghao/oss/web/app/db/query/AppConfigQuery.java

@@ -1,19 +0,0 @@
-package cn.reghao.oss.web.app.db.query;
-
-import cn.reghao.oss.web.app.model.po.AppConfig;
-import cn.reghao.jutil.jdk.db.BaseQuery;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author reghao
- * @date 2021-06-02 15:01:18
- */
-public interface AppConfigQuery extends BaseQuery<AppConfig> {
-    List<AppConfig> query(Map<String, String> kv);
-    AppConfig findByAppId(String appId);
-    Page<AppConfig> findByEnvAndType(String env, String type, Pageable pageable);
-}

+ 0 - 63
oss-web/src/main/java/cn/reghao/oss/web/app/db/query/impl/AppConfigQueryImpl.java

@@ -1,63 +0,0 @@
-package cn.reghao.oss.web.app.db.query.impl;
-
-import cn.reghao.oss.web.app.db.query.AppConfigQuery;
-import cn.reghao.oss.web.app.db.repository.AppConfigRepository;
-import cn.reghao.oss.web.app.model.po.AppConfig;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.stereotype.Service;
-
-import javax.persistence.criteria.Predicate;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author reghao
- * @date 2021-06-02 15:01:18
- */
-@Service
-public class AppConfigQueryImpl implements AppConfigQuery {
-    private final AppConfigRepository appRepository;
-
-    public AppConfigQueryImpl(AppConfigRepository appRepository) {
-        this.appRepository = appRepository;
-    }
-
-    @Override
-    public AppConfig findById(int id) {
-        return appRepository.getOne(id);
-    }
-
-    @Override
-    public List<AppConfig> query(Map<String, String> kv) {
-        Specification<AppConfig> specification = (root, query, cb) -> {
-            List<Predicate> predicates = new ArrayList<>();
-            kv.forEach((name, value) -> {
-                predicates.add(cb.like(root.get(name), "%" + value + "%"));
-            });
-
-            // select * from app_building where app_id like '%test%' and app_name like '%测试%'
-            return cb.and(predicates.toArray(new Predicate[0]));
-        };
-        return appRepository.findAll(specification);
-    }
-
-    //@Cacheable({"appId"})
-    @Override
-    public AppConfig findByAppId(String appId) {
-        return appRepository.findByDeletedFalseAndAppId(appId);
-    }
-
-    @Override
-    public Page<AppConfig> findByEnvAndType(String env, String type, Pageable pageable) {
-        return appRepository.findByEnvAndAppType(env, type, pageable);
-    }
-
-    //@Cacheable({"appId"})
-    @Override
-    public List<AppConfig> findAll() {
-        return appRepository.findAll();
-    }
-}

+ 0 - 21
oss-web/src/main/java/cn/reghao/oss/web/app/db/repository/AppConfigRepository.java

@@ -1,21 +0,0 @@
-package cn.reghao.oss.web.app.db.repository;
-
-import cn.reghao.oss.web.app.model.po.AppConfig;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-
-import java.util.List;
-
-/**
- *
- * @author reghao
- * @date 2020-01-21 14:53:03
- */
-public interface AppConfigRepository extends JpaRepository<AppConfig, Integer>, JpaSpecificationExecutor<AppConfig> {
-    AppConfig findByDeletedFalseAndAppId(String appId);
-    List<AppConfig> findByAppRepoAndRepoBranch(String repo, String branch);
-    Page<AppConfig> findByEnv(String env, Pageable pageable);
-    Page<AppConfig> findByEnvAndAppType(String env, String type, Pageable pageable);
-}

+ 3 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/db/repository/StoreNodeRepository.java

@@ -3,6 +3,8 @@ package cn.reghao.oss.web.app.db.repository;
 import cn.reghao.oss.web.app.model.po.StoreNode;
 import org.springframework.data.jpa.repository.JpaRepository;
 
+import java.util.List;
+
 /**
  * @author reghao
  * @date 2024-02-23 11:31:05
@@ -10,4 +12,5 @@ import org.springframework.data.jpa.repository.JpaRepository;
 public interface StoreNodeRepository extends JpaRepository<StoreNode, Integer> {
     StoreNode findByIpv4Addr(String ipv4Addr);
     StoreNode findByDomain(String domain);
+    List<StoreNode> findByDomainIn(List<String> domains);
 }

+ 7 - 2
oss-web/src/main/java/cn/reghao/oss/web/app/db/repository/UploadChannelRepository.java

@@ -3,11 +3,16 @@ package cn.reghao.oss.web.app.db.repository;
 import cn.reghao.oss.web.app.model.po.UploadChannel;
 import org.springframework.data.jpa.repository.JpaRepository;
 
+import java.util.List;
+
 /**
  * @author reghao
  * @date 2024-02-23 15:05:30
  */
 public interface UploadChannelRepository extends JpaRepository<UploadChannel, Integer> {
-    /*UploadChannel findByCode(int code);*/
-    UploadChannel findByPrefix(String prefix);
+    int countByCreateBy(int createBy);
+    UploadChannel findByChannelIdAndCreateBy(int channelId, int createBy);
+    UploadChannel findByPrefixAndCreateBy(String prefix, int createBy);
+    List<UploadChannel> findByBindDomain(String domain);
+    UploadChannel findByBindDomainAndChannelId(String domain, int channelId);
 }

+ 17 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/db/repository/UserKeyRepository.java

@@ -0,0 +1,17 @@
+package cn.reghao.oss.web.app.db.repository;
+
+import cn.reghao.oss.web.app.model.po.UserKey;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2024-02-27 10:35:53
+ */
+public interface UserKeyRepository extends JpaRepository<UserKey, Integer> {
+    int countByDomainAndUserId(String domain, int userId);
+    List<UserKey> findByUserId(int userId);
+    List<UserKey> findByDomainAndUserId(String domain, int userId);
+    UserKey findByAccessKeyId(String accessKeyId);
+}

+ 12 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/db/repository/UserNodeRepository.java

@@ -0,0 +1,12 @@
+package cn.reghao.oss.web.app.db.repository;
+
+import cn.reghao.oss.web.app.model.po.UserNode;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * @author reghao
+ * @date 2024-02-27 09:49:12
+ */
+public interface UserNodeRepository extends JpaRepository<UserNode, Integer> {
+    UserNode findByDomainAndUserId(String domain, int userId);
+}

+ 15 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/model/dto/KeyAuthDto.java

@@ -0,0 +1,15 @@
+package cn.reghao.oss.web.app.model.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author reghao
+ * @date 2024-02-27 11:21:07
+ */
+@Setter
+@Getter
+public class KeyAuthDto {
+    private String accessKeyId;
+    private String accessKeySecret;
+}

+ 1 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/model/dto/StoreNodeUpdateDto.java

@@ -20,4 +20,5 @@ public class StoreNodeUpdateDto {
     private String ipv4Addr;
     @NotBlank(message = "必须指定域名")
     private String domain;
+    private String location;
 }

+ 17 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/model/dto/UserKeyDto.java

@@ -0,0 +1,17 @@
+package cn.reghao.oss.web.app.model.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author reghao
+ * @date 2024-02-27 11:01:40
+ */
+@Setter
+@Getter
+public class UserKeyDto {
+    @NotBlank
+    private String domain;
+}

+ 18 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/model/dto/UserNodeDto.java

@@ -0,0 +1,18 @@
+package cn.reghao.oss.web.app.model.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author reghao
+ * @date 2024-02-27 09:42:44
+ */
+@Setter
+@Getter
+public class UserNodeDto {
+    @NotBlank
+    private String domain;
+    private String description;
+}

+ 0 - 56
oss-web/src/main/java/cn/reghao/oss/web/app/model/po/AppConfig.java

@@ -1,56 +0,0 @@
-package cn.reghao.oss.web.app.model.po;
-
-import cn.reghao.oss.web.app.model.constant.AppType;
-import cn.reghao.oss.web.util.db.BaseEntity;
-import cn.reghao.oss.web.util.validator.ValidEnum;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-import org.hibernate.validator.constraints.Length;
-
-import javax.persistence.*;
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotNull;
-
-/**
- * @author reghao
- * @date 2020-02-28 14:11:02
- */
-@NoArgsConstructor
-@Getter
-@Setter
-@Entity
-public class AppConfig extends BaseEntity {
-    @Column(nullable = false, unique = true)
-    @NotBlank(message = "应用 ID 不能为空字符串")
-    @Length(min = 4, max = 64, message = "应用 ID 仅可包含数字,大小写字母和 '-' 等字符, 长度为 4 ~ 64 个字符")
-    private String appId;
-    @NotNull
-    @NotBlank(message = "应用名字不能为空白字符串")
-    private String appName;
-    @NotNull
-    @ValidEnum(value = AppType.class, message = "请选择正确的应用类型")
-    private String appType;
-    @NotBlank(message = "环境不能为空白字符串")
-    private String env;
-    @NotNull
-    @NotBlank(message = "应用仓库不能为空白字符串")
-    private String appRepo;
-    @NotNull
-    @NotBlank(message = "仓库分支不能为空白字符串")
-    private String repoBranch;
-    private Boolean enabled;
-
-    /* 构建配置 */
-    private String projDirname;
-    @NotNull
-    @NotBlank(message = "应用根目录不能为空白字符串")
-    private String appRootPath;
-    private String bindPorts;
-    private String healthCheck;
-
-    // TODO packType 是 docker 时使用
-    @Lob
-    @Column(columnDefinition="text")
-    private String dockerfile;
-}

+ 2 - 1
oss-web/src/main/java/cn/reghao/oss/web/app/model/po/StoreNode.java

@@ -22,7 +22,8 @@ public class StoreNode extends BaseEntity {
     private Integer httpPort;
     @NotNull
     private Integer rpcPort;
-    private String domain;
     private Long total;
     private Long avail;
+    private String domain;
+    private Integer regionId;
 }

+ 7 - 3
oss-web/src/main/java/cn/reghao/oss/web/app/model/po/UploadChannel.java

@@ -17,17 +17,21 @@ import javax.persistence.Entity;
 @Setter
 @Entity
 public class UploadChannel extends BaseEntity {
-/*    private String name;
-    private Integer code;*/
+    private Integer channelId;
+    private String name;
     private String prefix;
     private Long maxSize;
+    private String contentType;
     private String description;
     private String bindDomain;
+    private Integer createBy;
 
-    public UploadChannel(UploadChannelDto uploadChannelDto) {
+    public UploadChannel(int channelId, UploadChannelDto uploadChannelDto, int createBy) {
+        this.channelId = channelId;
         this.prefix = uploadChannelDto.getChannelPrefix();
         this.maxSize = uploadChannelDto.getMaxSize();
         this.description = uploadChannelDto.getDescription();
         this.bindDomain = uploadChannelDto.getDomain();
+        this.createBy = createBy;
     }
 }

+ 27 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/model/po/UserKey.java

@@ -0,0 +1,27 @@
+package cn.reghao.oss.web.app.model.po;
+
+import cn.reghao.oss.web.util.db.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+
+/**
+ * @author reghao
+ * @date 2024-02-27 10:32:53
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter
+@Setter
+@Entity
+public class UserKey extends BaseEntity {
+    @Column(unique = true)
+    private String accessKeyId;
+    private String accessKeySecret;
+    private String domain;
+    private Integer userId;
+}

+ 29 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/model/po/UserNode.java

@@ -0,0 +1,29 @@
+package cn.reghao.oss.web.app.model.po;
+
+import cn.reghao.oss.web.app.model.dto.UserNodeDto;
+import cn.reghao.oss.web.util.db.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import javax.persistence.Entity;
+
+/**
+ * @author reghao
+ * @date 2024-02-27 09:45:11
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter
+@Setter
+@Entity
+public class UserNode extends BaseEntity {
+    private String domain;
+    private Integer userId;
+
+    public UserNode(UserNodeDto userNodeDto, int userId) {
+        this.domain = userNodeDto.getDomain();
+        this.userId = userId;
+    }
+}

+ 63 - 13
oss-web/src/main/java/cn/reghao/oss/web/app/service/OssService.java

@@ -1,15 +1,17 @@
 package cn.reghao.oss.web.app.service;
 
-import cn.reghao.oss.api.constant.ChannelAction;
 import cn.reghao.oss.api.dto.*;
 import cn.reghao.oss.api.iface.ObjectService;
+import cn.reghao.oss.api.iface.OssServerService;
+import cn.reghao.oss.web.app.db.repository.StoreNodeRepository;
 import cn.reghao.oss.web.app.db.repository.UploadChannelRepository;
+import cn.reghao.oss.web.app.model.po.StoreNode;
 import cn.reghao.oss.web.app.model.po.UploadChannel;
-import cn.reghao.oss.web.util.JwtUtil;
 import org.springframework.stereotype.Service;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * @author reghao
@@ -18,32 +20,80 @@ import java.util.List;
 @Service
 public class OssService {
     private final UploadChannelRepository uploadChannelRepository;
+    private final StoreNodeRepository storeNodeRepository;
 
-    public OssService(UploadChannelRepository uploadChannelRepository) {
+    public OssService(UploadChannelRepository uploadChannelRepository, StoreNodeRepository storeNodeRepository) {
         this.uploadChannelRepository = uploadChannelRepository;
+        this.storeNodeRepository = storeNodeRepository;
     }
 
-    public ServerInfo getServerInfo(String channelPrefix, long userId, int channelId) {
-        UploadChannel uploadChannel = uploadChannelRepository.findByPrefix(channelPrefix);
+    public ServerInfo getServerInfo(int channelId) throws Exception {
+        int userId = 1;
+        UploadChannel uploadChannel = uploadChannelRepository.findByChannelIdAndCreateBy(channelId, userId);
         if (uploadChannel == null) {
-            return null;
+            String errMsg = String.format("channel_id %s not exist", channelId);
+            throw new Exception(errMsg);
         }
 
         String domain = uploadChannel.getBindDomain();
-        String ossUrl = String.format("https://%s/", domain);
+        String ossUrl = String.format("https://%s", domain);
         long maxSize = uploadChannel.getMaxSize();
 
-        String action = ChannelAction.upload.getName();
-        long expireAt = System.currentTimeMillis() + 3600*1000;
-        OssPayload ossPayload = new OssPayload(action, channelId, userId);
-        String token = JwtUtil.createToken(ossPayload, expireAt, "secretKey");
+        StoreNode storeNode = storeNodeRepository.findByDomain(domain);
+        if (storeNode == null) {
+            String errMsg = String.format("store_node %s not exist", domain);
+            throw new Exception(errMsg);
+        }
+
+        String host = storeNode.getIpv4Addr();
+        int port = storeNode.getRpcPort();
+        RemoteService<OssServerService> remoteService = new RemoteService<>();
+        OssServerService ossServerService = remoteService.getService(host, port, OssServerService.class);
+        String token = ossServerService.getUploadToken(channelId);
         return new ServerInfo(ossUrl, channelId, maxSize, token);
     }
 
+    public List<ObjectChannel> getObjectChannels(String nodeAddr) {
+        StoreNode storeNode = storeNodeRepository.findByIpv4Addr(nodeAddr);
+        if (storeNode == null) {
+            return Collections.emptyList();
+        }
+
+        String domain = storeNode.getDomain();
+        return uploadChannelRepository.findByBindDomain(domain).stream()
+                .map(uploadChannel -> {
+                    String name = uploadChannel.getDescription();
+                    long maxSize = uploadChannel.getMaxSize();
+                    String channelPrefix = uploadChannel.getPrefix();
+                    String contentType = uploadChannel.getContentType();
+                    return new ObjectChannel(name, channelPrefix, maxSize, contentType, domain);
+                })
+                .collect(Collectors.toList());
+    }
+
+    public ObjectChannel getObjectChannel(String nodeAddr, int channelId) {
+        StoreNode storeNode = storeNodeRepository.findByIpv4Addr(nodeAddr);
+        if (storeNode == null) {
+            return null;
+        }
+
+        String domain = storeNode.getDomain();
+        UploadChannel uploadChannel = uploadChannelRepository.findByBindDomainAndChannelId(domain, channelId);
+        if (uploadChannel == null) {
+            return null;
+        }
+
+        String name = uploadChannel.getDescription();
+        String channelPrefix = uploadChannel.getPrefix();
+        long maxSize = uploadChannel.getMaxSize();
+        String contentType = uploadChannel.getContentType();
+        return new ObjectChannel(name, channelPrefix, maxSize, contentType, domain);
+    }
+
     public ObjectInfo getObjectInfo(String objectId) {
         RemoteService<ObjectService> remoteService = new RemoteService<>();
         String host = "";
-        int port = 11011;
+        int port = -1;
         ObjectService objectService = remoteService.getService(host, port, ObjectService.class);
         return objectService.getObjectInfo(objectId);
     }
@@ -51,7 +101,7 @@ public class OssService {
     public DownloadUrl getDownloadUrl(String objectId, int channelId, long userId) {
         RemoteService<ObjectService> remoteService = new RemoteService<>();
         String host = "";
-        int port = 11011;
+        int port = -1;
         ObjectService objectService = remoteService.getService(host, port, ObjectService.class);
         return objectService.getDownloadUrl(objectId, channelId, userId);
     }

+ 10 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/service/StoreNodeService.java

@@ -50,6 +50,16 @@ public class StoreNodeService {
         return Result.success();
     }
 
+    public Result delete(int nodeId) {
+        StoreNode storeNode = storeNodeRepository.findById(nodeId).orElse(null);
+        if (storeNode == null) {
+            return Result.fail("node not exist");
+        }
+
+        //storeNodeRepository.delete(storeNode);
+        return Result.success("not implement");
+    }
+
     public StoreNode get() {
         List<StoreNode> list = storeNodeRepository.findAll();
         if (list.isEmpty()) {

+ 25 - 2
oss-web/src/main/java/cn/reghao/oss/web/app/service/UploadChannelService.java

@@ -1,6 +1,9 @@
 package cn.reghao.oss.web.app.service;
 
 import cn.reghao.jutil.jdk.result.Result;
+import cn.reghao.oss.api.dto.ObjectChannel;
+import cn.reghao.oss.api.iface.OssServerService;
+import cn.reghao.oss.web.account.service.UserContext;
 import cn.reghao.oss.web.app.db.repository.StoreNodeRepository;
 import cn.reghao.oss.web.app.db.repository.UploadChannelRepository;
 import cn.reghao.oss.web.app.model.dto.UploadChannelDto;
@@ -29,14 +32,34 @@ public class UploadChannelService {
             return Result.fail(String.format("store_node with domain %s not exist", domain));
         }
 
+        int createBy = UserContext.getUser().getId();
         String channelPrefix = uploadChannelDto.getChannelPrefix();
-        UploadChannel uploadChannel = uploadChannelRepository.findByPrefix(channelPrefix);
+        UploadChannel uploadChannel = uploadChannelRepository.findByPrefixAndCreateBy(channelPrefix, createBy);
         if (uploadChannel != null) {
             return Result.fail(String.format("channel_prefix %s exist", channelPrefix));
         }
 
-        uploadChannel = new UploadChannel(uploadChannelDto);
+        int channelId = getNextChannelId();
+        uploadChannel = new UploadChannel(channelId, uploadChannelDto, createBy);
         uploadChannelRepository.save(uploadChannel);
+
+        String name = uploadChannel.getDescription();
+        long maxSize = uploadChannel.getMaxSize();
+        String contentType = "video/";
+        ObjectChannel channel = new ObjectChannel(name, channelPrefix, maxSize, contentType, domain);
+
+        String host = storeNode.getIpv4Addr();
+        int port = storeNode.getRpcPort();
+        RemoteService<OssServerService> remoteService = new RemoteService<>();
+        OssServerService ossServerService = remoteService.getService(host, port, OssServerService.class);
+        ossServerService.createChannel(createBy, channel);
         return Result.success();
     }
+
+    private int getNextChannelId() {
+        int channelId = 1001;
+        int userId = UserContext.getUser().getId();
+        int total = uploadChannelRepository.countByCreateBy(userId);
+        return channelId + total;
+    }
 }

+ 85 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/service/UserKeyService.java

@@ -0,0 +1,85 @@
+package cn.reghao.oss.web.app.service;
+
+import cn.reghao.jutil.jdk.result.Result;
+import cn.reghao.jutil.jdk.security.RandomString;
+import cn.reghao.oss.api.constant.ChannelAction;
+import cn.reghao.oss.api.dto.OssPayload;
+import cn.reghao.oss.web.account.service.UserContext;
+import cn.reghao.oss.web.app.db.repository.UserKeyRepository;
+import cn.reghao.oss.web.app.model.dto.KeyAuthDto;
+import cn.reghao.oss.web.app.model.dto.UserKeyDto;
+import cn.reghao.oss.web.app.model.po.UserKey;
+import cn.reghao.oss.web.util.JwtUtil;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2024-02-27 10:25:25
+ */
+@Service
+public class UserKeyService {
+    private final UserKeyRepository userKeyRepository;
+
+    public UserKeyService(UserKeyRepository userKeyRepository) {
+        this.userKeyRepository = userKeyRepository;
+    }
+
+    public Result create(UserKeyDto userKeyDto) {
+        String domain = userKeyDto.getDomain();
+        int userId = UserContext.getUser().getId();
+        int total = userKeyRepository.countByDomainAndUserId(domain, userId);
+        if (total > 2) {
+            String errMsg = String.format("you already have %s keys, key exceed limit", total);
+            return Result.fail(errMsg);
+        }
+
+        String accessKeyId = RandomString.getString(8);
+        String accessKeySecret = RandomString.getString(18);
+        UserKey userKey = new UserKey(accessKeyId, accessKeySecret, domain, userId);
+        userKeyRepository.save(userKey);
+        return Result.success("key has created");
+    }
+
+    public Result auth(KeyAuthDto keyAuthDto) {
+        String accessKeyId = keyAuthDto.getAccessKeyId();
+        UserKey userKey = userKeyRepository.findByAccessKeyId(accessKeyId);
+        if (userKey == null) {
+            return Result.fail("key not exist");
+        }
+
+        if (!userKey.getAccessKeySecret().equals(keyAuthDto.getAccessKeySecret())) {
+            return Result.fail("secret not matched");
+        }
+
+        long loginUser = userKey.getUserId();
+        String token = getToken(loginUser);
+
+        return Result.success(token);
+    }
+
+    public String getToken(long loginUser) {
+        String secretKey = "ossconsole.reghao.cn";
+        long timestamp = System.currentTimeMillis() + 3600*24*365;
+        String action = ChannelAction.download.getName();
+        int channelId = 1;
+        OssPayload ossPayload = new OssPayload(action, channelId, loginUser);
+        return JwtUtil.createToken(ossPayload, timestamp, secretKey);
+    }
+
+    public int getUserIdFromToken(String token) {
+        String secretKey = "ossconsole.reghao.cn";
+        OssPayload ossPayload = JwtUtil.getOssPayload(token, secretKey);
+        return ossPayload.getUserId().intValue();
+    }
+
+    public void delete(String accessKeyId) {
+    }
+
+    public List<UserKey> getUserKeys() {
+        int userId = UserContext.getUser().getId();
+        List<UserKey> list = userKeyRepository.findByUserId(userId);
+        return list;
+    }
+}

+ 70 - 0
oss-web/src/main/java/cn/reghao/oss/web/app/service/UserNodeService.java

@@ -0,0 +1,70 @@
+package cn.reghao.oss.web.app.service;
+
+import cn.reghao.jutil.jdk.result.Result;
+import cn.reghao.oss.web.account.model.po.User;
+import cn.reghao.oss.web.account.service.UserContext;
+import cn.reghao.oss.web.app.db.repository.StoreNodeRepository;
+import cn.reghao.oss.web.app.db.repository.UserNodeRepository;
+import cn.reghao.oss.web.app.model.dto.UserNodeDto;
+import cn.reghao.oss.web.app.model.po.StoreNode;
+import cn.reghao.oss.web.app.model.po.UserNode;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author reghao
+ * @date 2024-02-27 09:49:56
+ */
+@Service
+public class UserNodeService {
+    private final UserNodeRepository userNodeRepository;
+    private final StoreNodeRepository storeNodeRepository;
+
+    public UserNodeService(UserNodeRepository userNodeRepository, StoreNodeRepository storeNodeRepository) {
+        this.userNodeRepository = userNodeRepository;
+        this.storeNodeRepository = storeNodeRepository;
+    }
+
+    public Result add(UserNodeDto userNodeDto) {
+        String domain = userNodeDto.getDomain();
+        Integer userId = UserContext.getUser().getId();
+        UserNode userNode = userNodeRepository.findByDomainAndUserId(domain, userId);
+        if (userNode == null) {
+            StoreNode storeNode = storeNodeRepository.findByDomain(userNodeDto.getDomain());
+            if (storeNode != null) {
+                userNode = new UserNode(userNodeDto, userId);
+                userNodeRepository.save(userNode);
+                return Result.success("node added");
+            }
+        }
+
+        return Result.fail("node exist");
+    }
+
+    public void delete(Integer nodeId) {
+        StoreNode storeNode = storeNodeRepository.findById(nodeId).orElse(null);
+        if (storeNode != null) {
+            String domain = storeNode.getDomain();
+            int userId = UserContext.getUser().getId();
+            UserNode userNode = userNodeRepository.findByDomainAndUserId(domain, userId);
+            if (userNode != null) {
+                userNodeRepository.delete(userNode);
+            }
+        }
+    }
+
+    public List<StoreNode> getUserStoreNodes() {
+        List<UserNode> list = userNodeRepository.findAll();
+        if (list.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        List<String> domains = list.stream().map(UserNode::getDomain).collect(Collectors.toList());
+        return storeNodeRepository.findByDomainIn(domains);
+    }
+}

+ 3 - 6
oss-web/src/main/java/cn/reghao/oss/web/app/service/media/ImageService.java

@@ -25,19 +25,16 @@ public class ImageService {
         imageFileService.deleteByImageFileIds(imageFileIds);
     }
 
-    public ImageUrlDto getImageUrl(int channelId, String imageFileId) {
+    public ImageUrlDto getImageUrl(String channelName, String imageFileId) {
+        int channelId = 1;
         return imageFileService.getImageUrl(channelId, imageFileId);
     }
 
-    public ImageUrlDto getImageUrl(String imageFileId, long loginUser, int channelId) {
-        return imageFileService.getImageUrl(imageFileId, loginUser, channelId);
-    }
-
     public List<ImageUrlDto> getImageUrls(Set<String> imageFileIds) {
         return imageFileService.getImageUrls(imageFileIds);
     }
 
     public String getSignedUrl(String url, long loginUser, int channelId) {
-        return imageFileService.getSignedUrl(url, loginUser, channelId);
+        return imageFileService.getSignedUrl(url);
     }
 }

+ 2 - 2
oss-web/src/main/java/cn/reghao/oss/web/config/spring/AppLifecycle.java

@@ -17,11 +17,11 @@ import java.io.IOException;
 public class AppLifecycle implements ApplicationRunner, DisposableBean {
     @Override
     public void run(ApplicationArguments args) throws IOException {
-        log.info("oss-web started");
+        log.info("oss-console started");
     }
 
     @Override
     public void destroy() {
-        log.info("oss-web shutdown...");
+        log.info("oss-console shutdown...");
     }
 }

+ 1 - 1
oss-web/src/main/resources/application-dev.yml

@@ -5,6 +5,6 @@ spring:
   thymeleaf:
     cache: false
   datasource:
-    url: jdbc:mysql://localhost/reghao_oss_rdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
+    url: jdbc:mysql://localhost/reghao_oss_console_rdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
     username: dev
     password: Dev@123456

+ 1 - 1
oss-web/src/main/resources/application-test.yml

@@ -2,6 +2,6 @@ spring:
   thymeleaf:
     cache: true
   datasource:
-    url: jdbc:mysql://192.168.0.210/reghao_oss_tdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
+    url: jdbc:mysql://192.168.0.210/reghao_oss_console_tdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
     username: test
     password: Test@123456

+ 1 - 1
oss-web/src/main/resources/application.yml

@@ -6,7 +6,7 @@ server:
       timeout: 604800
 spring:
   application:
-    name: oss-web
+    name: oss-console
   profiles:
     active: @profile.active@
   servlet:

+ 0 - 46
oss-web/src/main/resources/templates/app/config/build/builddir.html

@@ -1,46 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
-
-<body class="timo-layout-page">
-<div class="layui-card">
-    <div class="layui-card-header timo-card-header">
-        <span><i class="fa fa-bars"></i> 构建目录</span>
-        <i class="layui-icon layui-icon-refresh refresh-btn"></i>
-    </div>
-    <div class="layui-card-body">
-        <div class="timo-table-wrap">
-            <table class="layui-table timo-table">
-                <thead>
-                <tr>
-                    <th class="sortable" data-field="machineIpv4">机器地址</th>
-                    <th class="sortable" data-field="dirPath">构建目录</th>
-                    <th class="sortable" data-field="mountedOn">所属分区</th>
-                    <th class="sortable" data-field="size">分区总量</th>
-                    <th class="sortable" data-field="avail">分区可用</th>
-                    <th>操作</th>
-                </tr>
-                </thead>
-                <tbody>
-                <tr th:each="item:${list}">
-                    <td th:text="${item.machineIpv4}">机器地址</td>
-                    <td th:text="${item.dirPath}">构建目录</td>
-                    <td th:text="${item.mountedOn}">所属分区</td>
-                    <td th:text="${item.totalStr}">分区总量</td>
-                    <td th:text="${item.availStr}">分区可用</td>
-                    <td>
-                        <a class="ajax-post"
-                           th:href="@{'/api/app/config/build/dir/erase'}">清空</a>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-        </div>
-    </div>
-</div>
-
-<script th:replace="/common/template :: script"></script>
-<script type="text/javascript">
-</script>
-</body>
-</html>

+ 0 - 78
oss-web/src/main/resources/templates/app/config/compiler/add.html

@@ -1,78 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
-
-<body>
-<div class="layui-form timo-compile">
-    <form th:action="@{/api/app/config/build/compiler}">
-        <div class="layui-form-item">
-            <label class="layui-form-label required">编译类型<i id="compile_type_tips" class="fa fa-question-circle"></i></label>
-            <div class="layui-input-inline">
-                <select name="type">
-                    <option th:each="item : ${compileTypes}" th:value="${item.key}">[[${item.value}]]</option>
-                </select>
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label required">编译名字</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="name" placeholder="请输入编译名字" required>
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label">编译器目录<i id="home_path_tips" class="fa fa-question-circle"></i></label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="homePath" placeholder="请输入编译器主目录">
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label">编译脚本<i id="compile_script_tips" class="fa fa-question-circle"></i></label>
-            <div class="layui-input-inline">
-                <textarea class="layui-textarea" name="compileScript" placeholder="请输入编译脚本"></textarea>
-            </div>
-        </div>
-        <div class="layui-form-item timo-finally">
-            <button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
-            <button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
-        </div>
-    </form>
-</div>
-
-<script th:replace="/common/template :: script"></script>
-<script type="text/javascript" th:src="@{/js/plugins/jquery-2.2.4.min.js}"></script>
-<script type="text/javascript">
-    $(function () {
-        $("#compile_type_tips").hover(function () {
-            var tips = layer.tips('不需要编译器指定 none 类型<br />',
-                '#compile_type_tips',{
-                tips: [1, '#555555']
-            });
-            sleep(1000);
-            layer.close(tips);
-        })
-
-        $("#home_path_tips").hover(function () {
-            var tips = layer.tips(
-                '采用 maven 编译必须指定 maven 的主目录<br/>' +
-                '其他编译类型不需要指定编译器的主目录<br/>', +
-                '#home_path_tips',{
-                    tips: [1, '#555555']
-                });
-            sleep(1000);
-            layer.close(tips);
-        })
-
-        $("#compile_script_tips").hover(function () {
-            var tips = layer.tips(
-                '编译脚本中的编译器必须指定绝对路径(absolute path)<br/>',
-                '#compile_script_tips',{
-                    tips: [1, '#555555']
-                });
-            sleep(1000);
-            layer.close(tips);
-        })
-    })
-</script>
-</body>
-</html>

+ 0 - 13
oss-web/src/main/resources/templates/app/config/compiler/detail.html

@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
-<body>
-    <div class="timo-detail-page">
-        <div class="layui-card">
-            <div class="layui-card-body">
-                <textarea class="layui-textarea" readonly="readonly" th:text="${compiler.compileScript}"></textarea>
-            </div>
-        </div>
-    </div>
-</body>
-</html>

+ 0 - 44
oss-web/src/main/resources/templates/app/config/compiler/edit.html

@@ -1,44 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
-
-<body>
-<div class="layui-form timo-compile">
-    <form th:action="@{/api/app/config/build/compiler}">
-        <!--<input type="hidden" name="machineId" th:value="${machineId}"/>-->
-        <div class="layui-form-item">
-            <label class="layui-form-label">编译类型</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="type" readonly th:value="${compiler.type}">
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label">编译名字</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="name" readonly th:value="${compiler.name}">
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label required">编译器主目录</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="homePath" th:value="${compiler.homePath}">
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label required">编译脚本</label>
-            <div class="layui-input-inline">
-                <textarea class="layui-textarea" name="compileScript" th:text="${compiler.compileScript}"></textarea>
-            </div>
-        </div>
-        <div class="layui-form-item timo-finally">
-            <button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
-            <button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
-        </div>
-    </form>
-</div>
-<script th:replace="/common/template :: script"></script>
-<script type="text/javascript">
-</script>
-</body>
-</html>

+ 0 - 60
oss-web/src/main/resources/templates/app/config/compiler/index.html

@@ -1,60 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
-
-<body class="timo-layout-page">
-<div class="layui-card">
-    <div class="layui-card-header timo-card-header">
-        <span><i class="fa fa-bars"></i> 编译配置</span>
-        <i class="layui-icon layui-icon-refresh refresh-btn"></i>
-    </div>
-    <div class="layui-card-body">
-        <div class="layui-row timo-card-screen put-row">
-            <div class="pull-right screen-btn-group">
-                <div class="btn-group-right">
-                    <button class="layui-btn open-popup" data-title="添加编译配置" th:attr="data-url=@{/app/config/build/compiler/add}"
-                            data-size="640,480">
-                        <i class="fa fa-plus"></i> 添加
-                    </button>
-                </div>
-            </div>
-        </div>
-        <div class="timo-table-wrap">
-            <table class="layui-table timo-table">
-                <thead>
-                <tr>
-                    <th class="sortable" data-field="type">编译类型</th>
-                    <th class="sortable" data-field="name">编译名字</th>
-                    <th class="sortable" data-field="homePath">编译器主目录</th>
-                    <th class="sortable" data-field="compileScript">编译脚本</th>
-                    <th>操作</th>
-                </tr>
-                </thead>
-                <tbody>
-                <tr th:each="item:${list}">
-                    <td th:text="${item.type}">编译类型</td>
-                    <td th:text="${item.name}">编译名字</td>
-                    <td th:text="${item.homePath}">编译器主目录</td>
-                    <td>
-                        <a class="open-popup" data-title="编译脚本" th:attr="data-url=@{'/app/config/build/compiler/detail/'+${item.id}}"
-                           data-size="640,480" href="#">查看</a>
-                    </td>
-                    <td>
-                        <a class="open-popup" data-title="编辑" th:attr="data-url=@{'/app/config/build/compiler/edit/'+${item.id}}"
-                           data-size="640,480" href="#">编辑</a>
-                        <a class="ajax-delete" th:attr="data-msg='确定要删除 '+ ${item.name} + '?'"
-                           th:href="@{'/api/app/config/build/compiler/' + ${item.id}}">删除</a>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-        </div>
-        <div th:replace="/common/fragment :: page"></div>
-    </div>
-</div>
-
-<script th:replace="/common/template :: script"></script>
-<script type="text/javascript">
-</script>
-</body>
-</html>

+ 0 - 71
oss-web/src/main/resources/templates/app/config/packer/add.html

@@ -1,71 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
-
-<body>
-<div class="layui-form timo-compile">
-    <form th:action="@{/api/app/config/build/packer}">
-        <div class="layui-form-item">
-            <label class="layui-form-label required">打包类型</label>
-            <div class="layui-input-inline">
-                <select name="type">
-                    <option th:each="item : ${packTypes}" th:value="${item.key}">[[${item.value}]]</option>
-                </select>
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label required">打包名字</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="name" placeholder="请输入打包名字" required>
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label">存放位置<i id="target_path_tips" class="fa fa-question-circle"></i></label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="targetPath" placeholder="docker 打包类型必须填写" required>
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label">bin 目录名<i id="bin_dirname_tips" class="fa fa-question-circle"></i></label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="binDirname" placeholder="zip 打包类型必须填写" required>
-            </div>
-        </div>
-        <div class="layui-form-item timo-finally">
-            <button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
-            <button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
-        </div>
-    </form>
-</div>
-
-<script th:replace="/common/template :: script"></script>
-<script type="text/javascript" th:src="@{/js/plugins/jquery-2.2.4.min.js}"></script>
-<script type="text/javascript">
-    $(function () {
-        $("#target_path_tips").hover(function () {
-            var tips = layer.tips(
-                'docker 打包类型的存放地址是 docker 仓库地址<br/>' +
-                'zip 打包类型不需要填写<br/>', +
-                    '#target_path_tips',{
-                    tips: [1, '#555555']
-                });
-            sleep(1000);
-            layer.close(tips);
-        })
-
-        $("#bin_dirname_tips").hover(function () {
-            var tips = layer.tips(
-                '构建生成的可执行文件及配置文件, 脚本文件等所在的目录名<br/>' +
-                'docker 打包类型不需要填写<br/>' +
-                'zip 打包类型必须填写<br/>',
-                '#bin_dirname_tips',{
-                    tips: [1, '#555555']
-                });
-            sleep(1000);
-            layer.close(tips);
-        })
-    })
-</script>
-</body>
-</html>

+ 0 - 28
oss-web/src/main/resources/templates/app/config/packer/detail.html

@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
-<body>
-    <div class="timo-detail-page">
-        <table class="layui-table timo-detail-table">
-            <tbody>
-            <tr>
-                <th>打包类型</th>
-                <td th:text="${packer.type}"></td>
-            </tr>
-            <tr>
-                <th>打包名字</th>
-                <td th:text="${packer.name}"></td>
-            </tr>
-            <tr>
-                <th>存放位置</th>
-                <td th:text="${packer.targetPath}"></td>
-            </tr>
-            <tr>
-                <th>bin 目录名</th>
-                <td th:text="${packer.binDirname}"></td>
-            </tr>
-            </tbody>
-        </table>
-    </div>
-</body>
-</html>

+ 0 - 45
oss-web/src/main/resources/templates/app/config/packer/edit.html

@@ -1,45 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
-
-<body>
-<div class="layui-form timo-compile">
-    <form th:action="@{/api/app/config/build/packer}">
-        <input type="hidden" name="id" th:value="${packer.id}"/>
-        <div class="layui-form-item">
-            <label class="layui-form-label">打包类型</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" readonly name="type" th:value="${packer.type}">
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label">打包名字</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" readonly name="name" th:value="${packer.name}">
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label">存放位置</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="targetPath" required th:value="${packer.targetPath}">
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label">bin 目录名</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="binDirname" required th:value="${packer.binDirname}">
-            </div>
-        </div>
-        <div class="layui-form-item timo-finally">
-            <button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
-            <button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
-        </div>
-    </form>
-</div>
-
-<script th:replace="/common/template :: script"></script>
-<script type="text/javascript">
-</script>
-</body>
-</html>

+ 0 - 57
oss-web/src/main/resources/templates/app/config/packer/index.html

@@ -1,57 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
-
-<body class="timo-layout-page">
-<div class="layui-card">
-    <div class="layui-card-header timo-card-header">
-        <span><i class="fa fa-bars"></i> 打包配置</span>
-        <i class="layui-icon layui-icon-refresh refresh-btn"></i>
-    </div>
-    <div class="layui-card-body">
-        <div class="layui-row timo-card-screen put-row">
-            <div class="pull-right screen-btn-group">
-                <div class="btn-group-right">
-                    <button class="layui-btn open-popup" data-title="添加打包配置" th:attr="data-url=@{/app/config/build/packer/add}"
-                            data-size="640,480">
-                        <i class="fa fa-plus"></i> 添加
-                    </button>
-                </div>
-            </div>
-        </div>
-        <div class="timo-table-wrap">
-            <table class="layui-table timo-table">
-                <thead>
-                <tr>
-                    <th class="sortable" data-field="type">打包类型</th>
-                    <th class="sortable" data-field="name">打包名字</th>
-                    <th class="sortable" data-field="targetPath">存放位置</th>
-                    <th>操作</th>
-                </tr>
-                </thead>
-                <tbody>
-                <tr th:each="item:${list}">
-                    <td th:text="${item.type}">打包类型</td>
-                    <td th:text="${item.name}">打包名字</td>
-                    <td th:text="${item.targetPath}">存放位置</td>
-                    <td>
-                        <a class="open-popup" data-title="详细" th:attr="data-url=@{'/app/config/build/packer/detail/'+${item.id}}"
-                           data-size="640,480" href="#">详细</a>
-                        <a class="open-popup" data-title="编辑" th:attr="data-url=@{'/app/config/build/packer/edit/'+${item.id}}"
-                           data-size="640,480" href="#">编辑</a>
-                        <a class="ajax-delete" th:attr="data-msg='确定要删除 '+ ${item.name} + '?'"
-                           th:href="@{'/api/app/config/build/packer/' + ${item.id}}">删除</a>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-        </div>
-        <div th:replace="/common/fragment :: page"></div>
-    </div>
-</div>
-
-<script th:replace="/common/template :: script"></script>
-<script type="text/javascript">
-</script>
-</body>
-</html>

+ 0 - 82
oss-web/src/main/resources/templates/app/config/repoauth/add.html

@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
-
-<body>
-<div class="layui-form timo-compile">
-    <form th:action="@{/api/app/config/build/repoauth}">
-        <div class="layui-form-item">
-            <label class="layui-form-label required">仓库类型<i id="repo_type_tips" class="fa fa-question-circle"></i></label>
-            <div class="layui-input-inline">
-                <select name="type">
-                    <option th:each="item : ${repos}" th:value="${item.key}">[[${item.value}]]</option>
-                </select>
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label required">认证名字</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="name" placeholder="请输入认证名字" required>
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label required">认证类型<i id="repo_auth_type_tips" class="fa fa-question-circle"></i></label>
-            <div class="layui-input-inline">
-                <select name="authType">
-                    <option th:each="item : ${auths}" th:value="${item.key}">[[${item.value}]]</option>
-                </select>
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label">用户名</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="username" placeholder="请输入用户名">
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label">密码</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="password" placeholder="请输入密码">
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label">RSA 私钥</label>
-            <div class="layui-input-inline">
-                <textarea class="layui-textarea" name="rsaPrikey" placeholder="请输入 RSA 私钥"></textarea>
-            </div>
-        </div>
-        <div class="layui-form-item timo-finally">
-            <button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
-            <button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
-        </div>
-    </form>
-</div>
-
-<script th:replace="/common/template :: script"></script>
-<script type="text/javascript" th:src="@{/js/plugins/jquery-2.2.4.min.js}"></script>
-<script type="text/javascript" th:inline="javascript">
-    $(function () {
-        $("#repo_type_tips").hover(function () {
-            var tips = layer.tips('目前仅支持 git 仓库<br />', '#repo_type_tips',{
-                tips: [1, '#555555']
-            });
-            sleep(1000);
-            layer.close(tips);
-        })
-
-        $("#repo_auth_type_tips").hover(function () {
-            var tips = layer.tips(
-                '仓库不需要认证则选择 none 类型<br/>' +
-                'http 认证类型必须填写用户名和密码<br/>' +
-                'ssh 认证必须填写 RSA 私钥<br/>',
-                '#repo_auth_type_tips',{
-                tips: [1, '#555555']
-            });
-            sleep(1000);
-            layer.close(tips);
-        })
-    })
-</script>
-</body>
-</html>

+ 0 - 35
oss-web/src/main/resources/templates/app/config/repoauth/detail.html

@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
-<body>
-    <div class="timo-detail-page">
-        <table class="layui-table timo-detail-table">
-            <tbody>
-            <tr>
-                <th>仓库类型</th>
-                <td th:text="${repoAuth.type}"></td>
-                <th>认证名字</th>
-                <td th:text="${repoAuth.name}"></td>
-            </tr>
-            <tr>
-                <th>认证方式</th>
-                <td th:text="${repoAuth.authType}"></td>
-                <span th:if="${repoAuth.authType} == 'ssh'">
-                    <th>RSA 私钥</th>
-                    <td>
-                        <textarea class="layui-textarea" readonly="readonly" th:text="${repoAuth.rsaPrikey}"></textarea>
-                    </td>
-                </span>
-                <span th:if="${repoAuth.authType} == 'http'">
-                    <th>用户名</th>
-                    <td th:text="${repoAuth.username}"></td>
-                    <th>密码</th>
-                    <td th:text="${repoAuth.password}"></td>
-                </span>
-            </tr>
-            </tbody>
-        </table>
-    </div>
-<script th:replace="/common/template :: script"></script>
-</body>
-</html>

+ 0 - 57
oss-web/src/main/resources/templates/app/config/repoauth/edit.html

@@ -1,57 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
-
-<body>
-<div class="layui-form timo-compile">
-    <form th:action="@{/api/app/config/build/repoauth}">
-        <div class="layui-form-item">
-            <label class="layui-form-label required">仓库类型</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="type" th:value="${repoAuth.type}" readonly>
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label required">认证名字</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="name" th:value="${repoAuth.name}" readonly>
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label required">认证类型</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="authType" th:value="${repoAuth.authType}" readonly>
-            </div>
-        </div>
-        <div th:if="${repoAuth.getAuthType()} == 'http'">
-            <div class="layui-form-item">
-                <label class="layui-form-label required">用户名</label>
-                <div class="layui-input-inline">
-                    <input class="layui-input" type="text" name="username" placeholder="请输入用户名" required>
-                </div>
-            </div>
-            <div class="layui-form-item">
-                <label class="layui-form-label required">密码</label>
-                <div class="layui-input-inline">
-                    <input class="layui-input" type="text" name="password" placeholder="请输入密码" required>
-                </div>
-            </div>
-        </div>
-        <div class="layui-form-item" th:if="${repoAuth.getAuthType()} == 'ssh'">
-            <label class="layui-form-label required">RSA 私钥</label>
-            <div class="layui-input-inline">
-                <textarea class="layui-textarea" name="rsaPrikey" placeholder="请输入 RSA 私钥"></textarea>
-            </div>
-        </div>
-        <div class="layui-form-item timo-finally">
-            <button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 更新</button>
-            <button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
-        </div>
-    </form>
-</div>
-
-<script th:replace="/common/template :: script"></script>
-<script type="text/javascript" th:src="@{/js/plugins/jquery-2.2.4.min.js}"></script>
-</body>
-</html>

+ 0 - 57
oss-web/src/main/resources/templates/app/config/repoauth/index.html

@@ -1,57 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
-
-<body class="timo-layout-page">
-<div class="layui-card">
-    <div class="layui-card-header timo-card-header">
-        <span><i class="fa fa-bars"></i> 仓库认证</span>
-        <i class="layui-icon layui-icon-refresh refresh-btn"></i>
-    </div>
-    <div class="layui-card-body">
-        <div class="layui-row timo-card-screen put-row">
-            <div class="pull-right screen-btn-group">
-                <div class="btn-group-right">
-                    <button class="layui-btn open-popup" data-title="添加仓库认证" th:attr="data-url=@{/app/config/build/repoauth/add}"
-                            data-size="640,480">
-                        <i class="fa fa-plus"></i> 添加
-                    </button>
-                </div>
-            </div>
-        </div>
-        <div class="timo-table-wrap">
-            <table class="layui-table timo-table">
-                <thead>
-                <tr>
-                    <th class="sortable" data-field="type">仓库类型</th>
-                    <th class="sortable" data-field="name">认证名字</th>
-                    <th class="sortable" data-field="authType">认证类型</th>
-                    <th>操作</th>
-                </tr>
-                </thead>
-                <tbody>
-                <tr th:each="item:${list}">
-                    <td th:text="${item.type}">仓库类型</td>
-                    <td th:text="${item.name}">认证名字</td>
-                    <td th:text="${item.authType}">认证类型</td>
-                    <td>
-                        <a class="open-popup" data-title="详细" th:attr="data-url=@{'/app/config/build/repoauth/detail/'+${item.id}}"
-                           data-size="640,480" href="#">详细</a>
-                        <a class="open-popup" data-title="编辑" th:attr="data-url=@{'/app/config/build/repoauth/edit/'+${item.id}}"
-                           data-size="640,480" href="#">编辑</a>
-                        <a class="ajax-delete" th:attr="data-msg='确定要删除 '+ ${item.name} + '?'"
-                           th:href="@{'/api/app/config/build/repoauth/' + ${item.id}}">删除</a>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-        </div>
-        <div th:replace="/common/fragment :: page"></div>
-    </div>
-</div>
-
-<script th:replace="/common/template :: script"></script>
-<script type="text/javascript">
-</script>
-</body>
-</html>

+ 0 - 82
oss-web/src/main/resources/templates/app/stat/applog.html

@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org"
-      xmlns:mo="https://gitee.com/aun/Timo">
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
-    <link rel="stylesheet" th:href="@{/lib/zTree_v3/css/zTreeStyle/zTreeStyle.css}" type="text/css">
-    <link rel="stylesheet" th:href="@{/css/xterm.css}"/>
-</head>
-
-<body class="timo-layout-page">
-<div class="layui-card">
-    <div class="layui-card-body">
-        <div class="layui-row timo-card-screen put-row">
-            <div class="pull-left layui-form-pane">
-                <div class="layui-inline">
-                    <label class="layui-form-label">环境</label>
-                    <div class="layui-input-block timo-search-status">
-                        <select id="getPageByEnv" class="timo-search-select" name="env" onchange="getPageByEnv()"
-                                mo:dict="ENVIRONMENT" mo-selected="${env}"></select>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div id="terminal">
-        </div>
-    </div>
-</div>
-</body>
-<script th:replace="/common/template :: script"></script>
-<script type="text/javascript" th:src="@{/js/plugins/jquery-3.4.1.min.js}"></script>
-<script type="text/javascript" th:src="@{/js/websocket.js}"></script>
-<script type="text/javascript" th:src="@{/js/xterm.js}"></script>
-<script type="text/javascript" th:inline="javascript">
-    function getPageByEnv() {
-        console.log('切换机器')
-        layer.msg('切换机器', {offset: '15px', time: 5000, icon: 1});
-    }
-
-    openTerminal();
-    function openTerminal(){
-        var client = new WebSocketClient();
-        var term = new Terminal({
-            cols: 80,
-            rows: 30,
-            cursorBlink: true, // 光标闪烁
-            cursorStyle: "block", // 光标样式  null | 'block' | 'underline' | 'bar'
-            scrollback: 50, //回滚
-            tabStopWidth: 8, //制表宽度
-            screenKeys: true
-        });
-
-        term.open(document.getElementById('terminal'));
-        // 键盘输入时的回调函数
-        /*term.on('data', function (data) {
-            client.sendClientData(data);
-        });*/
-        //在页面上显示连接中...
-        term.write('Connecting...');
-        //执行连接操作
-        client.connect({
-            onError: function (error) {
-                // 连接失败回调
-                console.log('WebSocket 连接错误...')
-                term.write('Error: ' + error + '\r\n');
-            },
-            onConnect: function () {
-                // 连接成功回调
-                console.log('WebSocket 连接成功...')
-            },
-            onClose: function () {
-                // 连接关闭回调
-                console.log('WebSocket 连接关闭...')
-                term.write("\rconnection closed");
-            },
-            onData: function (data) {
-                // 收到数据时回调
-                console.log('接收到 WebSocket 的数据...')
-                term.write(data);
-            }
-        });
-    }
-</script>
-</html>

+ 0 - 144
oss-web/src/main/resources/templates/app/stat/log.html

@@ -1,144 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org"
-      xmlns:mo="https://gitee.com/aun/Timo">
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
-    <link rel="stylesheet" th:href="@{/lib/zTree_v3/css/zTreeStyle/zTreeStyle.css}" type="text/css">
-    <link rel="stylesheet" th:href="@{/css/xterm.css}"/>
-</head>
-
-<body class="timo-layout-page">
-<div class="layui-card">
-    <div class="layui-card-header">
-        <span><i class="fa fa-table"></i> 实时日志</span>
-        <span id="ws-status" style="background: red">离线</span>
-        <div class="layui-inline">
-            <label class="layui-form-label">环境</label>
-            <div class="layui-input-block">
-                <select id="getPageByEnv" name="env" onchange="getPageByEnv()"
-                        mo:dict="ENVIRONMENT" mo-selected="${env}"></select>
-            </div>
-        </div>
-        <div class="layui-inline">
-            <label class="layui-form-label">类型</label>
-            <div class="layui-input-block">
-                <select id="getPageByEnv1" name="env" onchange="getPageByEnv()"
-                        mo:dict="ENVIRONMENT" mo-selected="${env}"></select>
-            </div>
-        </div>
-        <div class="layui-inline">
-            <label class="layui-form-label">应用</label>
-            <div class="layui-input-block">
-                <select id="getPageByEnv2" name="env" onchange="getPageByEnv()"
-                        mo:dict="ENVIRONMENT" mo-selected="${env}"></select>
-            </div>
-        </div>
-        <div class="layui-inline">
-            <label class="layui-form-label">机器</label>
-            <div class="layui-input-block">
-                <select id="getPageByEnv3" name="env" onchange="getPageByEnv()"
-                        mo:dict="ENVIRONMENT" mo-selected="${env}"></select>
-            </div>
-        </div>
-    </div>
-    <div class="layui-card-body" style="background: black">
-        <ul id="applog" class="flow-default layui-timeline" style="height: 500px;overflow: auto">
-            <!--<li id="li2">
-                <div class="layui-text">
-                    <p>
-                        1. 更新:重命名菜单类型为:目录、菜单、按钮<2. 更新:重写Shiro“记住我”系列化数据,减少cookie体积3. 新增:获取用户角色列表方法4. 修复:获取部门数据时延迟加载超时问题 5. 修复:将jq版本改为2.2.4,解决layui弹出窗口最大化问题 6. 新增:项目配置项,可直接通过yml文件配置Shiro和XSS防护忽略规则 7. 新增:ResultExceptionError和ResultExceptionSuccess异常类 8. 修复:若干页面显示问题,优化加载时提示<br>
-                    </p>
-                </div>
-            </li>-->
-        </ul>
-    </div>
-</div>
-</body>
-<script th:replace="/common/template :: script"></script>
-<script type="text/javascript" th:src="@{/js/plugins/jquery-3.4.1.min.js}"></script>
-<script type="text/javascript" th:inline="javascript">
-    function getPageByEnv() {
-        console.log('切换机器')
-        layer.msg('切换机器', {offset: '15px', time: 5000, icon: 1});
-    }
-
-    function add(text) {
-        var p = document.createElement("p");
-        p.innerHTML = text + '<br>'
-
-        var div = document.createElement("div");
-        div.className = 'layui-text'
-        div.appendChild(p)
-
-        var li = document.createElement("li");
-        li.appendChild(div)
-
-        var ul = document.getElementById("applog");
-        ul.prepend(li);
-        //ul.appendChild(li);
-    }
-
-    function setOnline() {
-        var span = document.getElementById("ws-status")
-        span.style = "background: green"
-        span.innerHTML = '在线'
-    }
-
-    function setOffline() {
-        var span = document.getElementById("ws-status")
-        span.style = "background: red"
-        span.innerHTML = '离线'
-    }
-
-    var connected = false
-    var ws
-    function initWebSocket() {
-        if ("WebSocket" in window) {
-            var token = '0123456789'
-            var app = 'admin-service'
-            var host = '172.16.90.200'
-            var params = 'token=' + token + '&app=' + app + '&host=' + host;
-
-            var host1 = window.location.host
-            var url = 'wss://' + host1 + '/ws/log/pull?' + params
-            ws = new WebSocket(url);
-            ws.onopen = function() {
-                connected = true
-                setOnline()
-                // Web Socket 已连接上,使用 send() 方法发送数据
-                console.log("websocket connected...");
-            };
-            ws.onclose = function() {
-                connected = false
-                setOffline()
-                console.log("websocket connection closed...");
-                reconnect()
-            };
-            ws.onerror = function () {
-                connected = false
-                setOffline()
-                console.log("websocket connection error...");
-                reconnect()
-            };
-            ws.onmessage = function (evt) {
-                var event = JSON.parse(evt.data)
-                var eventType = event.event
-                var title = new Date().getTime()
-                add1(title, event.payload)
-                //document.getElementById("myTextarea").value = evt.data
-            }
-        } else {
-            // 浏览器不支持 WebSocket
-            alert("您的浏览器不支持 WebSocket!");
-        }
-    }
-    function reconnect() {
-        if (connected) return
-
-        setTimeout(function () {
-            console.log('websocket reconnecting...')
-            initWebSocket()
-        }, 5000)
-    }
-    initWebSocket()
-</script>
-</html>

+ 0 - 97
oss-web/src/main/resources/templates/app/stat/log1.html

@@ -1,97 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org"
-      xmlns:mo="https://gitee.com/aun/Timo">
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
-    <link rel="stylesheet" th:href="@{/lib/zTree_v3/css/zTreeStyle/zTreeStyle.css}" type="text/css">
-    <link rel="stylesheet" th:href="@{/css/xterm.css}"/>
-</head>
-
-<body class="timo-layout-page">
-<div class="layui-card">
-    <div class="layui-card-header">
-        <span><i class="fa fa-table"></i> 历史日志</span>
-        <div class="layui-inline">
-            <label class="layui-form-label">环境</label>
-            <div class="layui-input-block">
-                <select id="getPageByEnv" name="env" onchange="getPageByEnv()"
-                        mo:dict="ENVIRONMENT" mo-selected="${env}"></select>
-            </div>
-        </div>
-        <div class="layui-inline">
-            <label class="layui-form-label">类型</label>
-            <div class="layui-input-block">
-                <select id="getPageByEnv1" name="env" onchange="getPageByEnv()"
-                        mo:dict="ENVIRONMENT" mo-selected="${env}"></select>
-            </div>
-        </div>
-        <div class="layui-inline">
-            <label class="layui-form-label">应用</label>
-            <div class="layui-input-block">
-                <select id="getPageByEnv2" name="app" onchange="getPageByEnv()"
-                        mo:dict="ENVIRONMENT" mo-selected="${env}"></select>
-            </div>
-        </div>
-        <div class="layui-inline">
-            <label class="layui-form-label">机器</label>
-            <div class="layui-input-block">
-                <select id="getPageByEnv3" name="host" onchange="getPageByEnv()"
-                        mo:dict="ENVIRONMENT" mo-selected="${env}"></select>
-            </div>
-        </div>
-    </div>
-    <div class="layui-card-body" style="background: black">
-        <ul id="applog" class="flow-default layui-timeline" style="height: 500px;overflow: auto">
-        </ul>
-    </div>
-</div>
-</body>
-<script th:replace="/common/template :: script"></script>
-<script type="text/javascript" th:src="@{/js/plugins/jquery-3.4.1.min.js}"></script>
-<script type="text/javascript" th:inline="javascript">
-    function getPageByEnv() {
-        console.log('切换机器')
-        layer.msg('切换机器', {offset: '15px', time: 5000, icon: 1});
-    }
-
-    layui.use('flow', function(){
-        var flow = layui.flow;
-        flow.load({
-            elem: '#applog' //流加载容器
-            ,scrollElem: '#applog' //滚动条所在元素,一般不用填,此处只是演示需要。
-            ,done: function(page, next){ //执行下一页的回调
-                $.ajax({
-                    url: '/api/app/status/log',
-                    type: 'get',
-                    success: function (result) {
-                        if (result.code === 0) {
-                            var list = []
-                            for (payload of result.data) {
-                                var app = '<span style="color: yellowgreen">' +  payload.app + ' ' + '</span>'
-                                var host = '<span style="color: green">' +  payload.host + ' ' + '</span>'
-                                var timestamp = payload.timestamp
-                                var thread = payload.thread
-                                var level
-                                if (payload.level === 'INFO') {
-                                    level = '<span style="color: green">' +  payload.level + ' ' + '</span>'
-                                } else if (payload.level === 'ERROR') {
-                                    level = '<span style="color: red">' +  payload.level + ' ' + '</span>'
-                                } else {
-                                    level = '<span style="color: yellow">' +  payload.level + ' ' + '</span>'
-                                }
-
-                                var logger = '<span style="color: wheat">' +  payload.logger + ' ' + '</span>'
-                                var message = '<span style="color: white">' +  payload.message + ' ' + '</span>'
-
-                                var text = app + ' ' +  host + ' ' + timestamp + ' ' + thread + ' ' + level + ' ' + logger + ' ' + message + '<br>'
-                                list.push(text)
-                            }
-
-                            next(list.join(''), page < 10);
-                        }
-                    }
-                });
-            }
-        });
-    });
-</script>
-</html>

+ 0 - 205
oss-web/src/main/resources/templates/app/stat/nginxlog.html

@@ -1,205 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
-    <style>
-        a{
-            color: #005980;
-        }
-        .widget-small{
-            background-color: #FFFFFF;
-            overflow: hidden;
-            text-align: center;
-            border-radius: 2px;
-            box-shadow: 0 1px 2px 0 rgba(0,0,0,.05);
-        }
-        .widget-small .fa{
-            float: left;
-            width: 40%;
-            line-height: 80px;
-            color: #FFFFFF;
-        }
-        .widget-user .fa{
-            background-color: #029789;
-        }
-        .widget-visit .fa{
-            background-color: #17a2b8;
-        }
-        .widget-message .fa{
-            background-color: #fbad4c;
-        }
-        .widget-like .fa{
-            background-color: #ff646d;
-        }
-        .widget-small-info{
-            float: left;
-            text-align: left;
-            width: 40%;
-            margin-left: 20px;
-            margin-top: 18px;
-            line-height: 24px;
-        }
-        .widget-small-info h4{
-            font-size: 18px;
-        }
-        .widget-small-info span{
-            font-size: 16px;
-        }
-        .project-introduce{
-            min-height: 466px;
-        }
-        .project-introduce h4{
-            font-weight: bold;
-            margin-top: 12px;
-            margin-bottom: 8px;
-        }
-        .project-introduce li{
-            list-style: decimal;
-            margin-left: 28px;
-        }
-        .alert {
-            padding: 15px;
-            margin-bottom: 10px;
-            border: 1px solid transparent;
-            border-radius: 4px;
-        }
-        .alert-info {
-            color: #31708f;
-            background-color: #d9edf7;
-            border-color: #bce8f1;
-        }
-    </style>
-</head>
-
-<body class="timo-layout-page">
-<div class="layui-row layui-col-space15">
-    <div class="layui-card">
-        <div id="chart1" class="layui-card-body" style="height:500px;"></div>
-    </div>
-</div>
-
-<script th:src="@{/js/plugins/jquery-3.4.1.min.js}" charset="utf-8"></script>
-<script th:src="@{/lib/echarts-4.7.0/echarts.js}" charset="utf-8"></script>
-<script type="text/javascript" th:inline="javascript">
-    var myChart = echarts.init(document.getElementById('chart1'));
-    var xData = []
-    var yData = []
-    var option = {
-        title: {
-            text: 'Nginx Log'
-        },
-        tooltip: {},
-        toolbox: {
-            feature: {
-                dataZoom: {
-                    yAxisIndex: 'none'
-                },
-                restore: {},
-                saveAsImage: {}
-            }
-        },
-        legend: {
-            data:['reqs/s']
-        },
-        xAxis: {
-            type: 'category',
-            data: xData
-        },
-        yAxis: {},
-        series: [{
-            name: 'reqs/s',
-            type: 'line',
-            smooth:true,
-            data: yData
-        }],
-        dataZoom: [{//这个是设置滚动条的,可以拉动这个滚动条来改变你的图形的显示比例
-            type: 'slider',
-            show: true, //flase直接隐藏图形
-            xAxisIndex: [0],
-            left: '9%', //滚动条靠左侧的百分比
-            bottom: -5,
-            start: 0,//滚动条的起始位置
-            end: 50 //滚动条的截止位置(按比例分割你的柱状图x轴长度)
-        }]
-    };
-    myChart.setOption(option)
-    $.get("/api/log/nginx/chart", function (result) {
-        var data = result.data
-        for (const x of data[0]) {
-            xData.push(x)
-        }
-        for (const y of data[1]) {
-            yData.push(y)
-        }
-
-        myChart.setOption({
-            xAxis: {
-                data: xData
-            },
-            series: [{
-                data: yData
-            }],
-        })
-    })
-
-    var connected = false
-    var ws
-    function initWebSocket() {
-        if ("WebSocket" in window) {
-            var token = '0123456789'
-            var app = 'admin-service'
-            var host = '172.16.90.200'
-            var params = 'token=' + token + '&app=' + app + '&host=' + host;
-
-            var host1 = window.location.host
-            var url = 'wss://' + host1 + '/ws/log/pull?' + params
-            ws = new WebSocket(url);
-            ws.onopen = function() {
-                connected = true
-                // Web Socket 已连接上,使用 send() 方法发送数据
-                console.log("websocket connected...");
-            };
-            ws.onclose = function() {
-                connected = false
-                console.log("websocket connection closed...");
-                reconnect()
-            };
-            ws.onerror = function () {
-                connected = false
-                console.log("websocket connection error...");
-                reconnect()
-            };
-            ws.onmessage = function (evt) {
-                /*var data = JSON.parse(evt.data)
-                for (const x of data[0]) {
-                    xData.push(x)
-                }
-                for (const y of data[1]) {
-                    yData.push(y)
-                }
-
-                myChart.setOption({
-                    xAxis: {
-                        data: xData
-                    },
-                    series: [{
-                        data: yData
-                    }],
-                })*/
-            }
-        } else {
-            // 浏览器不支持 WebSocket
-            alert("您的浏览器不支持 WebSocket!");
-        }
-    }
-    function reconnect() {
-        if (connected) return
-
-        setTimeout(function () {
-            console.log('websocket reconnecting...')
-            initWebSocket()
-        }, 5000)
-    }
-    // initWebSocket()
-</script>
-</body>
-</html>

+ 0 - 19
oss-web/src/main/resources/templates/app/type/add.html

@@ -1,19 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org">
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
-
-<body>
-<div class="layui-form timo-compile">
-    <form th:action="@{/api/app/type}">
-        <table class="layui-table timo-detail-table">
-        </table>
-        <div class="layui-form-item timo-finally">
-            <button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
-            <button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
-        </div>
-    </form>
-</div>
-<script th:replace="/common/template :: script"></script>
-<script type="text/javascript" th:src="@{/js/plugins/jquery-2.2.4.min.js}"></script>
-</body>
-</html>

+ 0 - 18
oss-web/src/main/resources/templates/app/type/index.html

@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org"
-      xmlns:mo="https://gitee.com/aun/Timo">
-<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
-    <link rel="stylesheet" th:href="@{/lib/zTree_v3/css/zTreeStyle/zTreeStyle.css}" type="text/css">
-</head>
-
-<body class="timo-layout-page">
-<div class="layui-card">
-    <div class="layui-card-header timo-card-header">
-        <span><i class="fa fa-bars"></i> 应用类型列表</span>
-        <i class="layui-icon layui-icon-refresh refresh-btn"></i>
-    </div>
-</div>
-
-<script th:replace="/common/template :: script"></script>
-</body>
-</html>

+ 15 - 1
oss-web/src/main/resources/templates/app/bd/add.html → oss-web/src/main/resources/templates/channel/add.html

@@ -4,7 +4,7 @@
 
 <body>
 <div class="layui-form timo-compile">
-    <form th:action="@{/api/channel/upload/add}">
+    <form th:action="@{/api/store/channel/add}">
         <table class="layui-table timo-detail-table">
             <tbody>
             <tr>
@@ -35,6 +35,20 @@
                     </div>
                 </td>
             </tr>
+            <tr>
+                <th>
+                    <label class="layui-form-label required">对象类型</label>
+                </th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <select name="objectType">
+                                <option th:each="item : ${objectTypes}" th:value="${item.key}">[[${item.value}]]</option>
+                            </select>
+                        </div>
+                    </div>
+                </td>
+            </tr>
             <tr>
                 <th>
                     <label class="layui-form-label required">最大文件</label>

+ 0 - 0
oss-web/src/main/resources/templates/app/bd/deploy.html → oss-web/src/main/resources/templates/channel/deploy.html


+ 5 - 3
oss-web/src/main/resources/templates/app/bd/index.html → oss-web/src/main/resources/templates/channel/index.html

@@ -44,7 +44,7 @@
                 </div>
                 <div class="pull-right">
                     <div class="btn-group-right">
-                        <button class="layui-btn open-popup" data-title="添加应用" th:attr="data-url=@{/app/bd/add}"
+                        <button class="layui-btn open-popup" data-title="新增上传通道" th:attr="data-url=@{/store/channel/add}"
                                 data-size="640,480">
                             <i class="fa fa-plus"></i> 添加
                         </button>
@@ -60,10 +60,11 @@
                         <label class="timo-checkbox"><input type="checkbox">
                             <i class="layui-icon layui-icon-ok"></i></label>
                     </th>
-                    <th class="sortable" data-field="appName">域名</th>
+                    <th class="sortable" data-field="appName">Channel ID</th>
                     <th class="sortable" data-field="appId">前缀</th>
                     <th class="sortable" data-field="repoBranch">最大文件</th>
                     <th class="sortable" data-field="appType">简介</th>
+                    <th class="sortable" data-field="appName">绑定域名</th>
                     <th>操作</th>
                 </tr>
                 </thead>
@@ -75,10 +76,11 @@
                             <i class="layui-icon layui-icon-ok"></i>
                         </label>
                     </td>
-                    <td th:text="${item.bindDomain}">域名</td>
+                    <td th:text="${item.id}">ID</td>
                     <td th:text="${item.prefix}">前缀</td>
                     <td th:text="${item.maxSize}">最大文件</td>
                     <td th:text="${item.description}">简介</td>
+                    <td th:text="${item.bindDomain}">绑定域名</td>
                     <td>
                         <a class="open-popup" data-title="应用详细信息" th:attr="data-url=@{'/app/config/app/detail/'+${item.id}}"
                            data-size="1200,500" href="#">详细</a>

+ 0 - 0
oss-web/src/main/resources/templates/app/bd/log/buildconfig.html → oss-web/src/main/resources/templates/channel/log/buildconfig.html


+ 0 - 0
oss-web/src/main/resources/templates/app/bd/log/buildlog.html → oss-web/src/main/resources/templates/channel/log/buildlog.html


+ 0 - 0
oss-web/src/main/resources/templates/app/bd/log/buildresult.html → oss-web/src/main/resources/templates/channel/log/buildresult.html


+ 0 - 0
oss-web/src/main/resources/templates/app/bd/log/buildtime.html → oss-web/src/main/resources/templates/channel/log/buildtime.html


+ 0 - 0
oss-web/src/main/resources/templates/app/config/app/add.html → oss-web/src/main/resources/templates/node/add.html


+ 0 - 0
oss-web/src/main/resources/templates/app/config/app/copy.html → oss-web/src/main/resources/templates/node/copy.html


+ 0 - 0
oss-web/src/main/resources/templates/app/config/app/deploy/add.html → oss-web/src/main/resources/templates/node/deploy/add.html


+ 0 - 0
oss-web/src/main/resources/templates/app/config/app/deploy/detail.html → oss-web/src/main/resources/templates/node/deploy/detail.html


+ 0 - 0
oss-web/src/main/resources/templates/app/config/app/deploy/edit.html → oss-web/src/main/resources/templates/node/deploy/edit.html


+ 0 - 0
oss-web/src/main/resources/templates/app/config/app/deploy/index.html → oss-web/src/main/resources/templates/node/deploy/index.html


+ 0 - 0
oss-web/src/main/resources/templates/app/config/app/detail.html → oss-web/src/main/resources/templates/node/detail.html


+ 1 - 1
oss-web/src/main/resources/templates/app/config/app/edit.html → oss-web/src/main/resources/templates/node/edit.html

@@ -22,7 +22,7 @@
             </tr>
             <tr>
                 <th>
-                    <label class="layui-form-label required">域名</label>
+                    <label class="layui-form-label required">节点域名</label>
                 </th>
                 <td>
                     <div class="layui-form-item">

+ 5 - 6
oss-web/src/main/resources/templates/app/config/app/index.html → oss-web/src/main/resources/templates/node/index.html

@@ -52,7 +52,7 @@
                     <th class="sortable" data-field="appId">HTTP 端口</th>
                     <th class="sortable" data-field="repoBranch">RPC 端口</th>
                     <th class="sortable" data-field="appName">节点域名</th>
-                    <th>设置域名</th>
+                    <th class="sortable" data-field="appName">节点位置</th>
                     <th>操作</th>
                 </tr>
                 </thead>
@@ -62,15 +62,14 @@
                     <td th:text="${item.httpPort}">应用 ID</td>
                     <td th:text="${item.rpcPort}">分支</td>
                     <td th:text="${item.domain}">应用名</td>
+                    <td th:text="${item.domain}">应用名</td>
                     <td>
-                        <a class="open-popup" data-title="设置域名" th:attr="data-url=@{'/app/config/app/domain/'+${item.id}}"
+                        <a class="open-popup" data-title="设置存储节点属性" th:attr="data-url=@{'/app/config/app/domain/'+${item.id}}"
                            data-size="640,480" href="#">设置</a>
-                    </td>
-                    <td>
                         <a class="open-popup" data-title="应用详细信息" th:attr="data-url=@{'/app/config/app/detail/'+${item.id}}"
-                           data-size="1200,500" href="#">详细</a>
+                           data-size="640,480" href="#">详细</a>
                         <a class="ajax-delete" th:attr="data-msg='确定要删除 '+ ${item.id}"
-                           th:href="@{'/api/app/config/app/' + ${item.id}}">删除</a>
+                           th:href="@{'/api/oss/store/node/' + ${item.id}}">删除</a>
                     </td>
                 </tr>
                 </tbody>

+ 11 - 0
oss-web/src/main/resources/templates/object/add.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+
+<body>
+<div class="layui-form timo-compile">
+</div>
+
+<script th:replace="/common/template :: script"></script>
+</body>
+</html>

+ 67 - 0
oss-web/src/main/resources/templates/object/deploy.html

@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+<body class="timo-layout-page">
+<div class="layui-card">
+    <div class="layui-card-body">
+        <div class="timo-table-wrap">
+            <table class="layui-table timo-table">
+                <thead>
+                <tr>
+                    <th class="sortable" data-field="machineIpv4">机器地址</th>
+                    <th class="sortable" data-field="machineStatus">机器状态</th>
+                    <th class="sortable" data-field="commitId">当前版本</th>
+                    <th class="sortable" data-field="packagePath">包路径</th>
+                    <th class="sortable" data-field="deployBy">部署用户</th>
+                    <th class="sortable" data-field="deployTime">部署时间</th>
+                    <th class="sortable" data-field="deployResult">部署结果</th>
+                    <th>操作</th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr th:each="item:${list}">
+                    <td th:text="${item.machineIpv4}">机器地址</td>
+                    <td class="machine-status" th:text="${item.machineStatus}">机器状态</td>
+                    <td th:text="${item?.commitId}">当前版本</td>
+                    <td th:text="${item?.packagePath}">包路径</td>
+                    <td th:text="${item?.deployBy}">部署用户</td>
+                    <td th:text="${item?.deployTime}">部署时间</td>
+                    <td class="deploy-result" th:text="${item?.deployResult}">部署结果</td>
+                    <td>
+                        <a class="ajax-post"
+                           th:href="@{'/api/app/bd/deploy/'+${buildLogId}+'/'+${item.machineId}}">部署</a>
+                    </td>
+                </tr>
+                </tbody>
+            </table>
+        </div>
+    </div>
+</div>
+
+<script th:replace="/common/template :: script"></script>
+<script type="text/javascript" th:src="@{/js/plugins/jquery-2.2.4.min.js}"></script>
+<script type="text/javascript">
+    $(".deploy-result").each(function () {
+        var text = $(this).text().trim()
+        if (text === '尚未部署') {
+            $(this).css("color", "#4169e1")
+        } else if (text === '正在部署') {
+            $(this).css("color", "#e3cf57")
+        } else if (text === '部署成功') {
+            $(this).css("color", "#009688")
+        } else if (text === '部署失败') {
+            $(this).css("color", "#ff0000")
+        }
+    })
+
+    $(".machine-status").each(function () {
+        var text = $(this).text().trim()
+        if (text === 'Online') {
+            $(this).css("color", "#009688")
+        } else {
+            $(this).css("color", "#ff0000")
+        }
+    })
+</script>
+</body>
+</html>

+ 102 - 0
oss-web/src/main/resources/templates/object/index.html

@@ -0,0 +1,102 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org"
+      xmlns:mo="https://gitee.com/aun/Timo">
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
+    <link rel="stylesheet" th:href="@{/lib/zTree_v3/css/zTreeStyle/zTreeStyle.css}" type="text/css">
+</head>
+
+<body class="timo-layout-page">
+<div class="layui-card">
+    <div class="layui-card-header timo-card-header">
+        <span><i class="fa fa-bars"></i> 文件列表</span>
+        <i class="layui-icon layui-icon-refresh refresh-btn"></i>
+    </div>
+    <div class="layui-card-body">
+        <div class="layui-row timo-card-screen put-row">
+            <div class="layui-row timo-card-screen put-row">
+                <div class="pull-left layui-form-pane">
+                    <div class="layui-inline">
+                        <label class="layui-form-label">节点</label>
+                        <div class="layui-input-block timo-search-status">
+                            <select id="getPageByEnv" class="timo-search-select" name="env" onchange="getPageByCriteria()"
+                                    mo:dict="ENVIRONMENT" mo-selected="${env}"></select>
+                        </div>
+                    </div>
+                </div>
+                <div class="pull-right">
+                    <div class="btn-group-right">
+                        <button class="layui-btn open-popup" data-title="添加应用" th:attr="data-url=@{/app/bd/add}"
+                                data-size="640,480">
+                            <i class="fa fa-plus"></i> 新建目录
+                        </button>
+                        <button class="layui-btn open-popup" data-title="添加应用" th:attr="data-url=@{/app/bd/add}"
+                                data-size="640,480">
+                            <i class="fa fa-upload"></i> 上传文件
+                        </button>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="timo-table-wrap">
+            <table class="layui-table timo-table">
+                <thead>
+                <tr>
+                    <th class="timo-table-checkbox">
+                        <label class="timo-checkbox"><input type="checkbox">
+                            <i class="layui-icon layui-icon-ok"></i></label>
+                    </th>
+                    <th class="sortable" data-field="appName">ID</th>
+                    <th class="sortable" data-field="appId">文件名</th>
+                    <th class="sortable" data-field="repoBranch">文件大小</th>
+                    <th class="sortable" data-field="appName">存储类型</th>
+                    <th class="sortable" data-field="appType">更新时间</th>
+                    <th>操作</th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr th:each="item:${list}">
+                    <td>
+                        <label class="timo-checkbox">
+                            <input type="checkbox" th:value="${item.id}">
+                            <i class="layui-icon layui-icon-ok"></i>
+                        </label>
+                    </td>
+                    <td th:text="${item.id}">ID</td>
+                    <td th:text="${item.prefix}">前缀</td>
+                    <td th:text="${item.maxSize}">最大文件</td>
+                    <td th:text="${item.description}">简介</td>
+                    <td th:text="${item.bindDomain}">绑定域名</td>
+                    <td>
+                        <a class="open-popup" data-title="应用详细信息" th:attr="data-url=@{'/app/config/app/detail/'+${item.id}}"
+                           data-size="1200,500" href="#">详细</a>
+                        <a class="open-popup" data-title="编辑" th:attr="data-url=@{'/app/config/app/edit/'+${item.id}}"
+                           data-size="1200,500" href="#">编辑</a>
+                        <a class="ajax-delete" th:attr="data-msg='确定要删除 '+ ${item.id}"
+                           th:href="@{'/api/app/config/app/' + ${item.id}}">删除</a>
+                    </td>
+                </tr>
+                </tbody>
+            </table>
+        </div>
+        <div th:replace="/common/fragment :: page"></div>
+    </div>
+</div>
+
+<script th:replace="/common/template :: script"></script>
+<script type="text/javascript" th:src="@{/js/plugins/jquery-2.2.4.min.js}"></script>
+<script type="text/javascript">
+    function getPageByCriteria() {
+        console.log('select 事件')
+
+        var envSelectedOption = $("#getPageByEnv option:selected")
+        var envParam = envSelectedOption.text()
+
+        var typeSelectedOption = $("#getPageByType option:selected")
+        var typeParam = typeSelectedOption.text()
+
+        url = '?env=' + envParam + '&type=' + typeParam
+        window.location.href = window.location.pathname + url;
+    }
+</script>
+</body>
+</html>

+ 35 - 0
oss-web/src/main/resources/templates/userkey/add.html

@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+
+<body>
+<div class="layui-form timo-compile">
+    <form th:action="@{/api/store/my/key/create}">
+        <table class="layui-table timo-detail-table">
+            <tbody>
+            <tr>
+                <th>
+                    <label class="layui-form-label required">存储节点</label>
+                </th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <select name="domain">
+                                <option th:each="item : ${storeNodes}" th:value="${item.key}">[[${item.value}]]</option>
+                            </select>
+                        </div>
+                    </div>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+        <div class="layui-form-item timo-finally">
+            <button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
+            <button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
+        </div>
+    </form>
+</div>
+
+<script th:replace="/common/template :: script"></script>
+</body>
+</html>

+ 81 - 0
oss-web/src/main/resources/templates/userkey/index1.html

@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org"
+      xmlns:mo="https://gitee.com/aun/Timo">
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
+    <link rel="stylesheet" th:href="@{/lib/zTree_v3/css/zTreeStyle/zTreeStyle.css}" type="text/css">
+</head>
+
+<body class="timo-layout-page">
+<div class="layui-card">
+    <div class="layui-card-header timo-card-header">
+        <span><i class="fa fa-bars"></i> 我的帐号列表</span>
+        <i class="layui-icon layui-icon-refresh refresh-btn"></i>
+    </div>
+    <div class="layui-card-body">
+        <div class="layui-row timo-card-screen put-row">
+            <div class="layui-row timo-card-screen put-row">
+                <div class="pull-left layui-form-pane">
+                    <div class="layui-inline">
+                        <label class="layui-form-label">节点</label>
+                        <div class="layui-input-block timo-search-status">
+                            <select id="getPageByEnv" class="timo-search-select" name="env" onchange="getPageByCriteria()"
+                                    mo:dict="ENVIRONMENT" mo-selected="${env}"></select>
+                        </div>
+                    </div>
+                </div>
+                <div class="pull-right">
+                    <div class="btn-group-right">
+                        <button class="layui-btn open-popup" data-title="创建帐号" th:attr="data-url=@{/store/my/key/add}"
+                                data-size="640,480">
+                            <i class="fa fa-plus"></i> 创建
+                        </button>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="timo-table-wrap">
+            <table class="layui-table timo-table">
+                <thead>
+                <tr>
+                    <th class="sortable" data-field="appName">domain</th>
+                    <th class="sortable" data-field="appName">AccessKeyId</th>
+                    <th class="sortable" data-field="appName">AccessKeySecret</th>
+                    <th>操作</th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr th:each="item:${list}">
+                    <td th:text="${item.domain}">节点</td>
+                    <td th:text="${item.accessKeyId}">应用名</td>
+                    <td th:text="${item.accessKeySecret}">应用 ID</td>
+                    <td>
+                        <a class="open-popup" data-title="应用详细信息" th:attr="data-url=@{'/app/config/app/detail/'+${item.id}}"
+                           data-size="1200,500" href="#">详细</a>
+                        <a class="ajax-delete" th:attr="data-msg='确定要删除 '+ ${item.accessKeyId}"
+                           th:href="@{'/api/store/my/key/delete/' + ${item.accessKeyId}}">删除</a>
+                    </td>
+                </tr>
+                </tbody>
+            </table>
+        </div>
+    </div>
+</div>
+
+<script th:replace="/common/template :: script"></script>
+<script type="text/javascript" th:src="@{/js/plugins/jquery-2.2.4.min.js}"></script>
+<script type="text/javascript">
+    function getPageByCriteria() {
+        console.log('select 事件')
+
+        var envSelectedOption = $("#getPageByEnv option:selected")
+        var envParam = envSelectedOption.text()
+
+        var typeSelectedOption = $("#getPageByType option:selected")
+        var typeParam = typeSelectedOption.text()
+
+        url = '?env=' + envParam + '&type=' + typeParam
+        window.location.href = window.location.pathname + url;
+    }
+</script>
+</body>
+</html>

+ 3 - 31
oss-web/src/main/resources/templates/app/stat/index2.html → oss-web/src/main/resources/templates/usernode/add.html

@@ -4,7 +4,7 @@
 
 <body>
 <div class="layui-form timo-compile">
-    <form th:action="@{/api/channel/upload/add}">
+    <form th:action="@{/api/store/my/add}">
         <table class="layui-table timo-detail-table">
             <tbody>
             <tr>
@@ -23,40 +23,12 @@
             </tr>
             <tr>
                 <th>
-                    <label class="layui-form-label required">通道前缀</label>
+                    <label class="layui-form-label required">简介</label>
                 </th>
                 <td>
                     <div class="layui-form-item">
                         <div class="layui-input-inline">
-                            <label>
-                                <input class="layui-input" type="text" name="channelPrefix" placeholder="请输入通道前缀" required>
-                            </label>
-                        </div>
-                    </div>
-                </td>
-            </tr>
-            <tr>
-                <th>
-                    <label class="layui-form-label required">最大文件</label>
-                </th>
-                <td>
-                    <div class="layui-form-item">
-                        <div class="layui-input-inline">
-                            <select name="maxSize">
-                                <option th:each="item : ${sizeList}" th:value="${item.key}">[[${item.value}]]</option>
-                            </select>
-                        </div>
-                    </div>
-                </td>
-            </tr>
-            <tr>
-                <th>
-                    <label class="layui-form-label required">通道简介</label>
-                </th>
-                <td>
-                    <div class="layui-form-item">
-                        <div class="layui-input-inline">
-                            <textarea class="layui-textarea" name="description" placeholder="请填写通道简介"></textarea>
+                            <textarea class="layui-textarea" name="description" placeholder="请填写节点简介"></textarea>
                         </div>
                     </div>
                 </td>

+ 9 - 19
oss-web/src/main/resources/templates/app/stat/index1.html → oss-web/src/main/resources/templates/usernode/index1.html

@@ -44,9 +44,9 @@
                 </div>
                 <div class="pull-right">
                     <div class="btn-group-right">
-                        <button class="layui-btn open-popup" data-title="新建节点" th:attr="data-url=@{/app/stat/add}"
+                        <button class="layui-btn open-popup" data-title="添加节点" th:attr="data-url=@{/store/my/add}"
                                 data-size="640,480">
-                            <i class="fa fa-plus"></i> 新建
+                            <i class="fa fa-plus"></i> 添加
                         </button>
                     </div>
                 </div>
@@ -56,35 +56,25 @@
             <table class="layui-table timo-table">
                 <thead>
                 <tr>
-                    <th class="sortable" data-field="appName">节点地址</th>
-                    <th class="sortable" data-field="appId">HTTP 端口</th>
-                    <th class="sortable" data-field="repoBranch">RPC 端口</th>
                     <th class="sortable" data-field="appName">节点域名</th>
-                    <th>设置域名</th>
+                    <th class="sortable" data-field="appName">节点地址</th>
                     <th>操作</th>
                 </tr>
                 </thead>
                 <tbody>
                 <tr th:each="item:${list}">
-                    <td th:text="${item.ipv4Addr}">应用名</td>
-                    <td th:text="${item.httpPort}">应用 ID</td>
-                    <td th:text="${item.rpcPort}">分支</td>
-                    <td th:text="${item.domain}">应用名</td>
-                    <td>
-                        <a class="open-popup" data-title="设置域名" th:attr="data-url=@{'/app/config/app/domain/'+${item.id}}"
-                           data-size="640,480" href="#">设置</a>
-                    </td>
+                    <td th:text="${item.domain}">节点域名</td>
+                    <td th:text="${item.ipv4Addr}">节点地址</td>
                     <td>
-                        <a class="open-popup" data-title="应用详细信息" th:attr="data-url=@{'/app/config/app/detail/'+${item.id}}"
-                           data-size="1200,500" href="#">详细</a>
-                        <a class="ajax-delete" th:attr="data-msg='确定要删除 '+ ${item.id}"
-                           th:href="@{'/api/app/config/app/' + ${item.id}}">删除</a>
+                        <a class="open-popup" data-title="存储节点详细信息" th:attr="data-url=@{'/app/config/app/detail/'+${item.id}}"
+                           data-size="640,480" href="#">详细</a>
+                        <a class="ajax-delete" th:attr="data-msg='确定要删除 '+ ${item.domain}"
+                           th:href="@{'/api/store/my/delete/' + ${item.id}}">删除</a>
                     </td>
                 </tr>
                 </tbody>
             </table>
         </div>
-        <div th:replace="/common/fragment :: page"></div>
     </div>
 </div>
 

+ 2 - 2
oss-web/src/test/java/AccountTest.java

@@ -1,4 +1,4 @@
-import cn.reghao.oss.web.OssWebApplication;
+import cn.reghao.oss.web.OssConsoleApplication;
 import cn.reghao.oss.web.account.service.AccountService;
 import lombok.extern.slf4j.Slf4j;
 import org.junit.Test;
@@ -14,7 +14,7 @@ import org.springframework.test.context.junit4.SpringRunner;
  */
 @Slf4j
 @ActiveProfiles("dev")
-@SpringBootTest(classes = OssWebApplication.class)
+@SpringBootTest(classes = OssConsoleApplication.class)
 @RunWith(SpringRunner.class)
 public class AccountTest {
     @Autowired