Browse Source

完成构建部署页面

包括分页,模糊查找和环境切换
reghao 5 years ago
parent
commit
6bd4d56f08
54 changed files with 809 additions and 342 deletions
  1. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/StatusController.java
  2. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/crud/AppConfigController.java
  3. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/crud/BuildConfigController.java
  4. 55 11
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/view/AppConfigPageController.java
  5. 34 12
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/view/AppPageController.java
  6. 42 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/app/AppBuildingQuery.java
  7. 45 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/app/AppConfigQuery.java
  8. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/AppOrchestrationCrudService.java
  9. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/BuildDirCrudService.java
  10. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/CompilerConfigCrudService.java
  11. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/PackerConfigCrudService.java
  12. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/ProjOrchestrationCrudService.java
  13. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/RepoAuthConfigCrudService.java
  14. 6 23
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/config/AppOrchestration.java
  15. 1 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/config/build/PackerConfig.java
  16. 3 2
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/config/deploy/DeployConfig.java
  17. 2 2
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/log/BuildLog.java
  18. 3 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/repository/AppBuildingRepository.java
  19. 2 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/repository/config/AppOrchestrationRepository.java
  20. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/AppStatusService.java
  21. 2 3
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/AppIntegrate.java
  22. 24 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/validator/AppOrchestrationValidator.java
  23. 4 6
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/vo/orchestration/AppVO.java
  24. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app3/controller/App3CrudController.java
  25. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app3/service/crud/App3BakCrudService.java
  26. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app3/service/crud/App3BakLogCrudService.java
  27. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app3/service/crud/App3CrudService.java
  28. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/service/RoleService.java
  29. 1 3
      dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/service/UserService.java
  30. 2 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/common/db/CrudOps.java
  31. 1 2
      dmaster/src/main/java/cn/reghao/autodop/dmaster/common/db/MongoCrud.java
  32. 1 3
      dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/controller/MachinePageController.java
  33. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/controller/crud/MachineCrudController.java
  34. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/service/crud/MachineCrudService.java
  35. 1 2
      dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/service/crud/MachineLogCrudService.java
  36. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/db/HibernateSessionOps.java
  37. 38 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/db/HttpRequestUtil.java
  38. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/db/PageList.java
  39. 36 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/db/PageSort.java
  40. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/db/PrimaryKeyGenerator.java
  41. 2 3
      dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/AppPagesController.java
  42. 9 6
      dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/RolePageController.java
  43. 13 7
      dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/UserPageController.java
  44. 5 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/view/thymeleaf/attribute/SelectDictAttrProcessor.java
  45. 0 21
      dmaster/src/main/java/cn/reghao/autodop/dmaster/view/thymeleaf/utility/PageUtil.java
  46. 4 0
      dmaster/src/main/resources/static/js/main.js
  47. 17 8
      dmaster/src/main/resources/templates/app/build.html
  48. 90 0
      dmaster/src/main/resources/templates/app/config/app/add.bak.html
  49. 231 82
      dmaster/src/main/resources/templates/app/config/app/add.html
  50. 39 11
      dmaster/src/main/resources/templates/app/config/app/detail.html
  51. 44 32
      dmaster/src/main/resources/templates/app/config/app/index.html
  52. 7 78
      dmaster/src/main/resources/templates/app/log.html
  53. 1 1
      dmaster/src/main/resources/templates/common/fragment.html
  54. 24 2
      dmaster/src/test/java/cn/reghao/autodop/dmaster/app/entity/AppDeployingTest.java

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/StatusController.java

@@ -4,7 +4,7 @@ import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
 import cn.reghao.autodop.dmaster.app.service.AppStatusService;
 import cn.reghao.autodop.dmaster.utils.WebBody;
 import cn.reghao.autodop.common.dagent.app.api.data.log.LogFile;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/crud/AppConfigController.java

@@ -1,7 +1,7 @@
 package cn.reghao.autodop.dmaster.app.controller.crud;
 
 import cn.reghao.autodop.dmaster.utils.WebBody;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.common.utils.serializer.JsonConverter;
 import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
 import cn.reghao.autodop.dmaster.app.entity.config.ProjOrchestration;

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/crud/BuildConfigController.java

@@ -3,7 +3,7 @@ package cn.reghao.autodop.dmaster.app.controller.crud;
 import cn.reghao.autodop.dmaster.utils.WebBody;
 import cn.reghao.autodop.dmaster.app.entity.config.build.BuildDir;
 import cn.reghao.autodop.dmaster.app.db.config.BuildDirCrudService;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.common.utils.serializer.JsonConverter;
 import cn.reghao.autodop.dmaster.app.entity.config.build.CompilerConfig;
 import cn.reghao.autodop.dmaster.app.entity.config.build.PackerConfig;

+ 55 - 11
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/view/AppConfigPageController.java

@@ -1,20 +1,30 @@
 package cn.reghao.autodop.dmaster.app.controller.view;
 
 import cn.reghao.autodop.dmaster.app.constant.EnvType;
+import cn.reghao.autodop.dmaster.app.db.app.AppConfigQuery;
 import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
 import cn.reghao.autodop.dmaster.app.repository.config.AppOrchestrationRepository;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.app.validator.AppOrchestrationValidator;
+import cn.reghao.autodop.dmaster.auth.entity.User;
+import cn.reghao.autodop.dmaster.utils.WebBody;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageSort;
 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.data.domain.Sort;
+import org.springframework.http.MediaType;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @author reghao
@@ -25,29 +35,63 @@ import org.springframework.web.bind.annotation.RequestMapping;
 @Controller
 @RequestMapping("/app/config")
 public class AppConfigPageController {
+    private AppConfigQuery appConfigQuery;
     private AppOrchestrationRepository appRepository;
 
-    public AppConfigPageController(AppOrchestrationRepository appRepository) {
+    public AppConfigPageController(AppConfigQuery appConfigQuery, AppOrchestrationRepository appRepository) {
+        this.appConfigQuery = appConfigQuery;
         this.appRepository = appRepository;
     }
 
     @ApiOperation(value = "应用配置页面")
     @GetMapping("/app")
-    public String appConfigPage(Model model) {
-        String env = EnvType.test.name();
-        int page = 1;
-        int size = 10;
-        PageRequest pageRequest =
-                PageRequest.of(page-1, size, Sort.by(Sort.Direction.DESC, "updateTime"));
+    public String appConfigPage(@RequestParam(value = "env", required = false) String env,
+                                @RequestParam(value = "appName", required = false) String appName,
+                                Model model) {
+        if (env == null) {
+            env = EnvType.test.name();
+        }
+
+        if (appName != null) {
+            Map<String, String> map = new HashMap<>();
+            map.put("appName", appName);
+            List<AppOrchestration> list = appConfigQuery.query(map);
+            Page<AppOrchestration> page = new PageImpl<>(list);
+            PageList<AppOrchestration> pageList = PageList.pageList(page);
+
+            model.addAttribute("env", env);
+            model.addAttribute("page", page);
+            model.addAttribute("list", pageList.getList());
+            return "/app/config/app/index";
+        }
 
+        PageRequest pageRequest = PageSort.pageRequest();
         Page<AppOrchestration> appPage = appRepository.findByEnableTrueAndEnv(env, pageRequest);
         PageList<AppOrchestration> pageList = PageList.pageList(appPage);
 
+        model.addAttribute("env", env);
         model.addAttribute("page", appPage);
         model.addAttribute("list", pageList.getList());
         return "/app/config/app/index";
     }
 
+    @PostMapping(value = "/app", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String appConfigPage(@Validated AppOrchestrationValidator appOrchestrationValidator,
+                                AppOrchestration appOrchestration) {
+        return WebBody.success();
+    }
+
+    @GetMapping("/app/add")
+    public String addAppConfigPage() {
+        return "/app/config/app/add";
+    }
+
+    @GetMapping("/app/edit/{id}")
+    public String editAppConfigPage(@PathVariable("id") AppOrchestration app, Model model) {
+        model.addAttribute("app", app);
+        return "/app/config/app/add";
+    }
+
     @ApiOperation(value = "应用配置详情页面")
     @GetMapping("/app/detail/{appId}")
     public String appConfigPage(@PathVariable("appId") String appId, Model model) {

+ 34 - 12
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/view/AppPageController.java

@@ -1,6 +1,7 @@
 package cn.reghao.autodop.dmaster.app.controller.view;
 
 import cn.reghao.autodop.dmaster.app.constant.EnvType;
+import cn.reghao.autodop.dmaster.app.db.app.AppBuildingQuery;
 import cn.reghao.autodop.dmaster.app.entity.AppDeploying;
 import cn.reghao.autodop.dmaster.app.entity.AppRunning;
 import cn.reghao.autodop.dmaster.app.entity.log.BuildLog;
@@ -10,18 +11,20 @@ import cn.reghao.autodop.dmaster.app.repository.AppRunningRepository;
 import cn.reghao.autodop.dmaster.app.entity.AppBuilding;
 import cn.reghao.autodop.dmaster.app.repository.log.BuildLogRepository;
 import cn.reghao.autodop.dmaster.app.repository.log.DeployLogRepository;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageSort;
 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.PageRequest;
-import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.*;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author reghao
@@ -35,6 +38,7 @@ public class AppPageController {
     private AppBuildingRepository appBuildingRepository;
     private AppDeployingRepository appDeployingRepository;
     private AppRunningRepository appRunningRepository;
+    private AppBuildingQuery buildingQuery;
     private BuildLogRepository buildLogRepository;
     private DeployLogRepository deployLogRepository;
 
@@ -42,26 +46,43 @@ public class AppPageController {
                              AppDeployingRepository appDeployingRepository,
                              AppRunningRepository appRunningRepository,
                              BuildLogRepository buildLogRepository,
-                             DeployLogRepository deployLogRepository) {
+                             DeployLogRepository deployLogRepository,
+                             AppBuildingQuery buildingQuery) {
         this.appBuildingRepository = appBuildingRepository;
         this.appDeployingRepository = appDeployingRepository;
         this.appRunningRepository = appRunningRepository;
         this.buildLogRepository = buildLogRepository;
         this.deployLogRepository = deployLogRepository;
+        this.buildingQuery = buildingQuery;
     }
 
-    @ApiOperation(value = "构建页面")
+    @ApiOperation(value = "构建部署页面")
     @GetMapping("/build")
-    public String buildPage(Model model) {
-        String env = EnvType.test.name();
-        int page = 1;
-        int size = 10;
-        PageRequest pageRequest =
-                PageRequest.of(page-1, size, Sort.by(Sort.Direction.DESC, "updateTime"));
+    public String buildPage(@RequestParam(value = "env", required = false) String env,
+                            @RequestParam(value = "appName", required = false) String appName,
+                            Model model) {
+        if (env == null) {
+            env = EnvType.test.name();
+        }
+
+        if (appName != null) {
+            Map<String, String> map = new HashMap<>();
+            map.put("appName", appName);
+            List<AppBuilding> list = buildingQuery.query(map);
+            Page<AppBuilding> page = new PageImpl<>(list);
+            PageList<AppBuilding> pageList = PageList.pageList(page);
+
+            model.addAttribute("env", env);
+            model.addAttribute("page", page);
+            model.addAttribute("list", pageList.getList());
+            return "/app/build";
+        }
 
+        PageRequest pageRequest = PageSort.pageRequest();
         Page<AppBuilding> appBuildings = appBuildingRepository.findAllByEnv(env, pageRequest);
         PageList<AppBuilding> pageList = PageList.pageList(appBuildings);
 
+        model.addAttribute("env", env);
         model.addAttribute("page", appBuildings);
         model.addAttribute("list", pageList.getList());
         return "/app/build";
@@ -80,6 +101,7 @@ public class AppPageController {
     public String buildLogResultPage(@PathVariable("buildLogId") BuildLog buildLog, Model model) {
         String msg = buildLog.getResult().getMsg();
         model.addAttribute("msg", msg);
+        // TODO 后期使用 layui dialogue
         return "/app/log";
     }
 

+ 42 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/app/AppBuildingQuery.java

@@ -0,0 +1,42 @@
+package cn.reghao.autodop.dmaster.app.db.app;
+
+import cn.reghao.autodop.dmaster.app.entity.AppBuilding;
+import cn.reghao.autodop.dmaster.app.repository.AppBuildingRepository;
+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 AppBuildingQuery {
+    private AppBuildingRepository buildingRepository;
+
+    public AppBuildingQuery(AppBuildingRepository buildingRepository) {
+        this.buildingRepository = buildingRepository;
+    }
+
+    /**
+     * @param
+     * @return
+     * @date 2021-06-02 下午3:15
+     */
+    public List<AppBuilding> query(Map<String, String> kv) {
+        Specification<AppBuilding> 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 buildingRepository.findAll(specification);
+    }
+}

+ 45 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/app/AppConfigQuery.java

@@ -0,0 +1,45 @@
+package cn.reghao.autodop.dmaster.app.db.app;
+
+import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
+import cn.reghao.autodop.dmaster.app.repository.config.AppOrchestrationRepository;
+import cn.reghao.autodop.dmaster.app.repository.config.ProjOrchestrationRepository;
+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 AppConfigQuery {
+    private AppOrchestrationRepository appRepository;
+    private ProjOrchestrationRepository projRepository;
+
+    public AppConfigQuery(AppOrchestrationRepository appRepository, ProjOrchestrationRepository projRepository) {
+        this.appRepository = appRepository;
+        this.projRepository = projRepository;
+    }
+
+    /**
+     * @param
+     * @return
+     * @date 2021-06-02 下午3:15
+     */
+    public List<AppOrchestration> query(Map<String, String> kv) {
+        Specification<AppOrchestration> 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);
+    }
+}

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/AppOrchestrationCrudService.java

@@ -2,7 +2,7 @@ package cn.reghao.autodop.dmaster.app.db.config;
 
 import cn.reghao.autodop.dmaster.app.constant.AppType;
 import cn.reghao.autodop.dmaster.common.db.CrudOps;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
 import cn.reghao.autodop.dmaster.app.repository.config.AppOrchestrationRepository;
 import org.springframework.data.domain.Page;

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/BuildDirCrudService.java

@@ -3,7 +3,7 @@ package cn.reghao.autodop.dmaster.app.db.config;
 import cn.reghao.autodop.dmaster.app.entity.config.build.BuildDir;
 import cn.reghao.autodop.dmaster.app.repository.config.build.BuildDirRepository;
 import cn.reghao.autodop.dmaster.common.db.CrudOps;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Sort;

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/CompilerConfigCrudService.java

@@ -1,7 +1,7 @@
 package cn.reghao.autodop.dmaster.app.db.config;
 
 import cn.reghao.autodop.dmaster.common.db.CrudOps;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.app.entity.config.build.CompilerConfig;
 import cn.reghao.autodop.dmaster.app.repository.config.build.CompilerConfigRepository;
 import org.springframework.data.domain.Page;

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/PackerConfigCrudService.java

@@ -1,7 +1,7 @@
 package cn.reghao.autodop.dmaster.app.db.config;
 
 import cn.reghao.autodop.dmaster.common.db.CrudOps;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.app.entity.config.build.PackerConfig;
 import cn.reghao.autodop.common.dagent.app.api.data.deploy.PackerType;
 import cn.reghao.autodop.dmaster.app.repository.config.build.PackerConfigRepository;

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/ProjOrchestrationCrudService.java

@@ -1,7 +1,7 @@
 package cn.reghao.autodop.dmaster.app.db.config;
 
 import cn.reghao.autodop.dmaster.common.db.CrudOps;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.app.entity.config.ProjOrchestration;
 import cn.reghao.autodop.dmaster.app.repository.config.ProjOrchestrationRepository;
 import org.springframework.data.domain.Page;

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/RepoAuthConfigCrudService.java

@@ -1,7 +1,7 @@
 package cn.reghao.autodop.dmaster.app.db.config;
 
 import cn.reghao.autodop.dmaster.common.db.CrudOps;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.app.entity.config.build.RepoAuthConfig;
 import cn.reghao.autodop.dmaster.app.repository.config.build.RepoAuthConfigRepository;
 import org.springframework.data.domain.Page;

+ 6 - 23
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/config/AppOrchestration.java

@@ -25,29 +25,13 @@ import java.util.List;
 public class AppOrchestration extends BaseEntity<Integer> implements Cloneable {
     @Column(nullable = false, unique = true)
     private String appId;
-    @Column(nullable = false)
-    private String appType;
-    @Column(nullable = false)
-    private String env;
-
+    private String appName;
     private String description;
-    // 是否总是构建
-    @Column(nullable = false)
-    private Boolean alwaysBuild;
-    // 启用编排
-    @Column(nullable = false)
+    private String appType;
     private Boolean enable;
-    // 构建生成的可执行二进制文件名
-    private String execBinName;
-
-    @Column(nullable = false)
+    private String env;
     private String appRepo;
-    @Column(nullable = false)
     private String branch;
-    // 应用代码所在目录的名字
-    // TODO 检查 dirname 格式
-    @Column(nullable = false)
-    private String dirname;
 
     // TODO 操作系统类型和版本,CPU 架构
     // 构建配置,buildConfig 和 projId 二者只能存在一个
@@ -55,14 +39,13 @@ public class AppOrchestration extends BaseEntity<Integer> implements Cloneable {
     @ManyToOne(cascade = CascadeType.PERSIST)
     @JoinColumn(name = "proj_config_id", foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
     private ProjOrchestration proj;
-
+    private String dirname;
     // 编译应用时所处的目录,以仓库目录为起点
-    @Column(nullable = false)
     private String compileHome;
-    // 打包脚本,若使用的 docker,则是 dockerfile 的内容
+    private String execBinName;
     @Lob
     @Column(columnDefinition="text")
-    private String packScript;
+    private String dockerfile;
 
     /* 部署配置 */
     @ElementCollection(targetClass = DeployConfig.class)

+ 1 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/config/build/PackerConfig.java

@@ -7,6 +7,7 @@ import lombok.NoArgsConstructor;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
+import javax.persistence.Lob;
 
 /**
  * 打包方式配置

+ 3 - 2
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/config/deploy/DeployConfig.java

@@ -16,9 +16,8 @@ import javax.persistence.Lob;
 @Embeddable
 public class DeployConfig {
     private String machineId;
+    private String machineIpv4;
     private String packerType;
-    private String startHome;
-    private String startScript;
     // docker 容器启动参数
     // cn.reghao.autodop.common.dockerc.pojo.Config 序列化为 JSON 后的字符串
     //private Config dockerConfig;
@@ -26,4 +25,6 @@ public class DeployConfig {
     @Lob
     @Column(columnDefinition="text")
     private String dockerConfig;
+    private String startHome;
+    private String startScript;
 }

+ 2 - 2
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/log/BuildLog.java

@@ -25,7 +25,7 @@ public class BuildLog extends BaseDocument {
     private String repo;
     private String compiler;
     private String packer;
-    private String packScript;
+    private String dockerfile;
     private String packagePath;
 
     private CommitInfo commitInfo;
@@ -42,7 +42,7 @@ public class BuildLog extends BaseDocument {
         buildLog.setRepo(app.getBuildConfig().getRepoAuthConfig().getName());
         buildLog.setCompiler(app.getBuildConfig().getCompilerConfig().getName());
         buildLog.setPacker(app.getBuildConfig().getPackerConfig().getName());
-        buildLog.setPackScript(app.getPackScript());
+        buildLog.setDockerfile(app.getDockerfile());
 
         buildLog.setBuildTime(new BuildTime());
         buildLog.setResult(new Result());

+ 3 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/repository/AppBuildingRepository.java

@@ -4,12 +4,14 @@ import cn.reghao.autodop.dmaster.app.entity.AppBuilding;
 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;
 
 /**
  * @author reghao
  * @date 2021-05-24 15:20:24
  */
-public interface AppBuildingRepository extends JpaRepository<AppBuilding, Integer> {
+public interface AppBuildingRepository
+        extends JpaRepository<AppBuilding, Integer>, JpaSpecificationExecutor<AppBuilding> {
     AppBuilding findByAppId(String appId);
     Page<AppBuilding> findAllByEnv(String env, Pageable pageable);
     Page<AppBuilding> findAllByEnvAndAppType(String env, String appType, Pageable pageable);

+ 2 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/repository/config/AppOrchestrationRepository.java

@@ -15,7 +15,8 @@ import java.util.List;
  * @author reghao
  * @date 2020-01-21 14:53:03
  */
-public interface AppOrchestrationRepository extends JpaRepository<AppOrchestration, Integer>, JpaSpecificationExecutor<AppOrchestration> {
+public interface AppOrchestrationRepository
+        extends JpaRepository<AppOrchestration, Integer>, JpaSpecificationExecutor<AppOrchestration> {
     List<AppOrchestration> findByEnableTrueAndEnv(String env);
     Page<AppOrchestration> findByEnableTrueAndEnv(String env, Pageable pageable);
     List<AppOrchestration> findByEnableTrueAndEnvAndAppType(String env, String appType);

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/AppStatusService.java

@@ -10,7 +10,7 @@ import cn.reghao.autodop.dmaster.app.cache.BuildDeployCache;
 import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
 import cn.reghao.autodop.dmaster.app.entity.config.deploy.DeployConfig;
 import cn.reghao.autodop.common.dagent.app.api.data.log.LogFile;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;

+ 2 - 3
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/AppIntegrate.java

@@ -131,7 +131,7 @@ public class AppIntegrate {
         PackerConfig packerConfig = buildConfig.getPackerConfig();
         switch (PackerType.valueOf(packerConfig.getType())) {
             case docker:
-                codePacker = new DockerPack(packerConfig, app.getPackScript());
+                codePacker = new DockerPack(packerConfig, app.getDockerfile());
                 break;
             case zip:
                 codePacker = new ZipPack(packerConfig);
@@ -159,8 +159,7 @@ public class AppIntegrate {
         }
 
         UpdateStatus updateStatus = update0(remote, branch, local);
-        // TODO 代码版本未更改的情况下,是否应该构建
-        if (updateStatus.isUpdated || app.getAlwaysBuild()) {
+        if (updateStatus.isUpdated) {
             latestCommitInfo = updateStatus.getLatestCommitInfo();
             // 将代码由本地仓库复制到编译目录
             BuilderUtil.copyToCompileDir(local, app);

+ 24 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/validator/AppOrchestrationValidator.java

@@ -0,0 +1,24 @@
+package cn.reghao.autodop.dmaster.app.validator;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import java.io.Serializable;
+
+/**
+ * @author reghao
+ * @date 2021-05-18 14:38:49
+ */
+@Data
+public class AppOrchestrationValidator implements Serializable {
+    @NotEmpty(message = "应用 ID 不能为空字符串")
+    private String appId;
+    @NotEmpty(message = "应用名字不能为空字符串")
+    private String appName;
+    @NotEmpty(message = "应用类型不能为空字符串")
+    private String appType;
+    @NotEmpty(message = "应用仓库不能为空字符串")
+    private String appRepo;
+    @NotEmpty(message = "应用分支不能为空字符串")
+    private String branch;
+}

+ 4 - 6
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/vo/orchestration/AppVO.java

@@ -29,6 +29,7 @@ import java.util.List;
  * @author reghao
  * @date 2020-02-29 17:22:19
  */
+@Deprecated
 @Data
 public class AppVO {
     private String appId;
@@ -43,7 +44,7 @@ public class AppVO {
     private String branch;
     private String dirname;
     private String compileHome;
-    private String packScript;
+    private String dockerfile;
 
     private BuildConfigVO buildConfig;
     private String projId;
@@ -61,7 +62,6 @@ public class AppVO {
         vo.appId = app.getAppId();
         vo.env = app.getEnv();
         vo.description = app.getDescription();
-        vo.alwaysBuild = app.getAlwaysBuild();
         vo.enable = app.getEnable();
 
         vo.appType = app.getAppType();
@@ -69,7 +69,7 @@ public class AppVO {
         vo.branch = app.getBranch();
         vo.dirname = app.getDirname();
         vo.compileHome = app.getCompileHome();
-        vo.packScript = app.getPackScript();
+        vo.dockerfile = app.getDockerfile();
 
         if (app.getBuildConfig() != null) {
             vo.buildConfig = BuildConfigVO.from(app.getBuildConfig());
@@ -96,7 +96,6 @@ public class AppVO {
         app.setAppId(vo.appId);
         app.setEnv(vo.env);
         app.setDescription(vo.description);
-        app.setAlwaysBuild(vo.alwaysBuild);
         app.setEnable(vo.enable);
 
         app.setAppType(vo.appType);
@@ -104,7 +103,7 @@ public class AppVO {
         app.setBranch(vo.branch);
         app.setDirname(vo.dirname);
         app.setCompileHome(vo.compileHome);
-        app.setPackScript(vo.getPackScript());
+        app.setDockerfile(vo.getDockerfile());
 
         if (vo.getBuildConfig() != null) {
             app.setBuildConfig(BuildConfigVO.to(vo.getBuildConfig()));
@@ -133,7 +132,6 @@ public class AppVO {
         app.setAppId("content");
         app.setEnv(EnvType.test.name());
         app.setDescription("内容服务");
-        app.setAlwaysBuild(true);
         app.setEnable(true);
         app.setAppType(AppType.dotnetCore.name());
         app.setAppRepo("https://codeup.aliyun.com/5f1f8daf6207a1a8b17f6742/background/ContentService.git");

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app3/controller/App3CrudController.java

@@ -6,7 +6,7 @@ import cn.reghao.autodop.dmaster.app3.entity.App3Bak;
 import cn.reghao.autodop.dmaster.app3.service.crud.App3BakCrudService;
 import cn.reghao.autodop.dmaster.app3.service.crud.App3CrudService;
 import cn.reghao.autodop.common.utils.serializer.JsonConverter;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import io.swagger.annotations.Api;
 import org.springframework.web.bind.annotation.*;
 

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app3/service/crud/App3BakCrudService.java

@@ -1,7 +1,7 @@
 package cn.reghao.autodop.dmaster.app3.service.crud;
 
 import cn.reghao.autodop.dmaster.common.db.CrudOps;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.app3.entity.App3;
 import cn.reghao.autodop.dmaster.app3.entity.App3Bak;
 import cn.reghao.autodop.dmaster.app3.repository.App3BakRepository;

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app3/service/crud/App3BakLogCrudService.java

@@ -1,7 +1,7 @@
 package cn.reghao.autodop.dmaster.app3.service.crud;
 
 import cn.reghao.autodop.dmaster.common.db.CrudOps;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.app3.entity.App3BakLog;
 import cn.reghao.autodop.dmaster.app3.repository.App3BakLogRepository;
 import org.springframework.data.domain.Page;

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app3/service/crud/App3CrudService.java

@@ -3,7 +3,7 @@ package cn.reghao.autodop.dmaster.app3.service.crud;
 import cn.reghao.autodop.dmaster.app3.entity.App3;
 import cn.reghao.autodop.dmaster.app3.repository.App3Repository;
 import cn.reghao.autodop.dmaster.common.db.CrudOps;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Sort;

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/service/RoleService.java

@@ -2,7 +2,7 @@ package cn.reghao.autodop.dmaster.auth.service;
 
 import cn.reghao.autodop.dmaster.auth.entity.Role;
 import cn.reghao.autodop.dmaster.auth.repository.RoleRepository;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Sort;

+ 1 - 3
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/service/UserService.java

@@ -7,9 +7,8 @@ import cn.reghao.autodop.dmaster.auth.db.RoleCrud;
 import cn.reghao.autodop.dmaster.auth.entity.GrantedAuthorityImpl;
 import cn.reghao.autodop.dmaster.auth.entity.Role;
 import cn.reghao.autodop.dmaster.auth.entity.User;
-import cn.reghao.autodop.dmaster.auth.repository.RoleRepository;
 import cn.reghao.autodop.dmaster.auth.repository.UserRepository;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Sort;
@@ -18,7 +17,6 @@ import org.springframework.stereotype.Service;
 
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;

+ 2 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/common/db/CrudOps.java

@@ -1,5 +1,7 @@
 package cn.reghao.autodop.dmaster.common.db;
 
+import cn.reghao.autodop.dmaster.utils.db.PageList;
+
 import java.util.List;
 
 /**

+ 1 - 2
dmaster/src/main/java/cn/reghao/autodop/dmaster/common/db/MongoCrud.java

@@ -1,7 +1,6 @@
 package cn.reghao.autodop.dmaster.common.db;
 
-import cn.reghao.autodop.dmaster.common.db.CrudOps;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.app3.entity.App3BakLog;
 import org.springframework.data.mongodb.core.MongoTemplate;
 import org.springframework.data.mongodb.core.query.Criteria;

+ 1 - 3
dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/controller/MachinePageController.java

@@ -1,6 +1,6 @@
 package cn.reghao.autodop.dmaster.machine.controller;
 
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.machine.entity.MachineInfo;
 import cn.reghao.autodop.dmaster.machine.repository.MachineInfoRepository;
 import cn.reghao.autodop.dmaster.machine.vo.MachineInfoVO;
@@ -15,8 +15,6 @@ import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 
-import java.util.function.Function;
-
 /**
  * @author reghao
  * @date 2019-08-30 18:49:15

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/controller/crud/MachineCrudController.java

@@ -3,7 +3,7 @@ package cn.reghao.autodop.dmaster.machine.controller.crud;
 import cn.reghao.autodop.dmaster.utils.WebBody;
 import cn.reghao.autodop.dmaster.machine.entity.MachineInfo;
 import cn.reghao.autodop.dmaster.machine.vo.MachineInfoVO;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.machine.service.crud.MachineCrudService;
 import cn.reghao.autodop.dmaster.utils.dispatcher.MachineOpsDispatcher;
 import io.swagger.annotations.Api;

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/service/crud/MachineCrudService.java

@@ -3,7 +3,7 @@ package cn.reghao.autodop.dmaster.machine.service.crud;
 import cn.reghao.autodop.dmaster.machine.entity.MachineInfo;
 import cn.reghao.autodop.dmaster.machine.repository.MachineInfoRepository;
 import cn.reghao.autodop.dmaster.common.db.CrudOps;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Sort;

+ 1 - 2
dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/service/crud/MachineLogCrudService.java

@@ -2,9 +2,8 @@ package cn.reghao.autodop.dmaster.machine.service.crud;
 
 import cn.reghao.autodop.dmaster.machine.entity.MachineLog;
 import cn.reghao.autodop.dmaster.common.db.CrudOps;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.machine.repository.MachineLogRepository;
-import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/hibernate/HibernateSessionOps.java → dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/db/HibernateSessionOps.java

@@ -1,4 +1,4 @@
-package cn.reghao.autodop.dmaster.utils.hibernate;
+package cn.reghao.autodop.dmaster.utils.db;
 
 import org.hibernate.Session;
 import org.springframework.stereotype.Component;

+ 38 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/db/HttpRequestUtil.java

@@ -0,0 +1,38 @@
+package cn.reghao.autodop.dmaster.utils.db;
+
+import org.springframework.util.StringUtils;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author reghao
+ * @date 2021-06-02 13:16:58
+ */
+public class HttpRequestUtil {
+    /**
+     * 获取 query 参数值
+     *
+     * @param
+     * @return
+     * @date 2021-06-02 下午1:19
+     */
+    public static String getParameter(String param, String defaultValue){
+        String parameter = getRequest().getParameter(param);
+        return StringUtils.isEmpty(parameter) ? defaultValue : parameter;
+    }
+
+    public static HttpServletRequest getRequest(){
+        return getServletRequest().getRequest();
+    }
+
+    public static HttpServletResponse getResponse(){
+        return getServletRequest().getResponse();
+    }
+
+    private static ServletRequestAttributes getServletRequest(){
+        return (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+    }
+}

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/common/db/PageList.java → dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/db/PageList.java

@@ -1,4 +1,4 @@
-package cn.reghao.autodop.dmaster.common.db;
+package cn.reghao.autodop.dmaster.utils.db;
 
 import lombok.Data;
 import org.springframework.data.domain.Page;

+ 36 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/db/PageSort.java

@@ -0,0 +1,36 @@
+package cn.reghao.autodop.dmaster.utils.db;
+
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Sort;
+
+/**
+ * Hibernate 分页
+ *
+ * @author reghao
+ * @date 2021-06-02 11:07:56
+ */
+public class PageSort {
+    private static final int DEFAULT_PAGE_SIZE = 10;
+    private static final String DEFAULT_ORDER_BY_COLUMN = "updateTime";
+    private static final Sort.Direction DEFAULT_SORT_DIRECTION = Sort.Direction.DESC;
+
+    public static PageRequest pageRequest() {
+        return pageRequest(DEFAULT_PAGE_SIZE, DEFAULT_ORDER_BY_COLUMN, DEFAULT_SORT_DIRECTION);
+    }
+
+    /**
+     * @param pageSize 分页大小
+     * @param orderBy 排序字段
+     * @param sortDirection 排序方向(升序/降序)
+     * @return
+     * @date 2021-06-02 下午1:25
+     */
+    public static PageRequest pageRequest(int pageSize, String orderBy, Sort.Direction sortDirection) {
+        int index = Integer.parseInt(HttpRequestUtil.getParameter("page", String.valueOf(1)));
+        int size = Integer.parseInt(HttpRequestUtil.getParameter("size", String.valueOf(pageSize)));
+        String order =  HttpRequestUtil.getParameter("orderBy", orderBy);
+        String direction = HttpRequestUtil.getParameter("direction", sortDirection.toString());
+        Sort sort = Sort.by(sortDirection, order);
+        return PageRequest.of(index-1, size, sort);
+    }
+}

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/hibernate/PrimaryKeyGenerator.java → dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/db/PrimaryKeyGenerator.java

@@ -1,4 +1,4 @@
-package cn.reghao.autodop.dmaster.utils.hibernate;
+package cn.reghao.autodop.dmaster.utils.db;
 
 import org.hibernate.HibernateException;
 import org.hibernate.MappingException;

+ 2 - 3
dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/AppPagesController.java

@@ -2,7 +2,7 @@ package cn.reghao.autodop.dmaster.view.controller;
 
 import cn.reghao.autodop.dmaster.auth.entity.User;
 import cn.reghao.autodop.dmaster.auth.service.UserService;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.stereotype.Controller;
@@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.*;
  * @author reghao
  * @date 2021-04-04 21:24:18
  */
-@Api(tags = "应用页面")
+@Deprecated
 @RequestMapping("/app")
 @Controller
 public class AppPagesController {
@@ -23,7 +23,6 @@ public class AppPagesController {
         this.userService = userService;
     }
 
-    @ApiOperation(value = "获取构建部署页面")
     @GetMapping("/bd")
     public String userPage(Model model) {
         int page = 1;

+ 9 - 6
dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/RolePageController.java

@@ -8,9 +8,12 @@ import cn.reghao.autodop.dmaster.auth.repository.MenuRepository;
 import cn.reghao.autodop.dmaster.auth.repository.RoleRepository;
 import cn.reghao.autodop.dmaster.auth.repository.UserRepository;
 import cn.reghao.autodop.dmaster.auth.service.RoleService;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.utils.WebBody;
+import cn.reghao.autodop.dmaster.utils.db.PageSort;
 import io.swagger.annotations.Api;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
 import org.springframework.http.MediaType;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
@@ -44,13 +47,13 @@ public class RolePageController {
     }
 
     @GetMapping
-    public String rolePage(Model model, Role role) {
-        int page = 1;
-        int size = 10;
-        PageList<Role> pageList = roleService.findByPage(page, size);
+    public String rolePage(Model model) {
+        PageRequest pageRequest = PageSort.pageRequest();
+        Page<Role> rolePage = roleRepository.findAll(pageRequest);
+        PageList<Role> pageList = PageList.pageList(rolePage);
 
+        model.addAttribute("page", rolePage);
         model.addAttribute("list", pageList.getList());
-        model.addAttribute("page", pageList);
         return "/system/role/index";
     }
 

+ 13 - 7
dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/UserPageController.java

@@ -3,10 +3,14 @@ package cn.reghao.autodop.dmaster.view.controller;
 import cn.reghao.autodop.dmaster.auth.entity.Role;
 import cn.reghao.autodop.dmaster.auth.entity.User;
 import cn.reghao.autodop.dmaster.auth.repository.RoleRepository;
+import cn.reghao.autodop.dmaster.auth.repository.UserRepository;
 import cn.reghao.autodop.dmaster.auth.service.UserService;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.utils.WebBody;
+import cn.reghao.autodop.dmaster.utils.db.PageSort;
 import io.swagger.annotations.Api;
+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.*;
@@ -23,21 +27,23 @@ import java.util.List;
 @Controller
 public class UserPageController {
     private final UserService userService;
+    private UserRepository userRepository;
     private RoleRepository roleRepository;
 
-    public UserPageController(UserService userService, RoleRepository roleRepository) {
+    public UserPageController(UserService userService, RoleRepository roleRepository, UserRepository userRepository) {
         this.userService = userService;
         this.roleRepository = roleRepository;
+        this.userRepository = userRepository;
     }
 
     @GetMapping
     public String userPage(Model model) {
-        int page = 1;
-        int size = 10;
-        PageList<User> pageList = userService.findByPage(page, size);
-        model.addAttribute("list", pageList.getList());
-        model.addAttribute("page", pageList);
+        PageRequest pageRequest = PageSort.pageRequest();
+        Page<User> userPage = userRepository.findAll(pageRequest);
+        PageList<User> pageList = PageList.pageList(userPage);
 
+        model.addAttribute("page", userPage);
+        model.addAttribute("list", pageList.getList());
         return "/system/user/index";
     }
 

+ 5 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/view/thymeleaf/attribute/SelectDictAttrProcessor.java

@@ -27,6 +27,11 @@ public class SelectDictAttrProcessor extends AbstractAttributeTagProcessor {
         localCache.put("MENU_TYPE", new HashMap<>());
         localCache.get("MENU_TYPE").put("DIR", "DIR");
         localCache.get("MENU_TYPE").put("PAGE", "PAGE");
+
+        localCache.put("ENVIRONMENT", new HashMap<>());
+        localCache.get("ENVIRONMENT").put("dev", "dev");
+        localCache.get("ENVIRONMENT").put("test", "test");
+        localCache.get("ENVIRONMENT").put("prod", "prod");
     }
     
     public static final int PRECEDENCE = 1400;

+ 0 - 21
dmaster/src/main/java/cn/reghao/autodop/dmaster/view/thymeleaf/utility/PageUtil.java

@@ -1,6 +1,5 @@
 package cn.reghao.autodop.dmaster.view.thymeleaf.utility;
 
-import cn.reghao.autodop.dmaster.common.db.PageList;
 import org.springframework.data.domain.Page;
 
 import javax.servlet.http.HttpServletRequest;
@@ -16,26 +15,6 @@ import java.util.List;
 public class PageUtil {
     private String paramHref;
 
-    public boolean pageInit1(PageList pageList, HttpServletRequest request){
-        if (pageList.getTotalSize() > pageList.getPageSize() && pageList.getList().size() != 0){
-
-            // 获取分页参数地址
-            String servletPath = request.getServletPath();
-            StringBuffer param = new StringBuffer(servletPath + "?");
-            Enumeration em = request.getParameterNames();
-            while (em.hasMoreElements()) {
-                String name = (String) em.nextElement();
-                if(!"page".equals(name)){
-                    String value = request.getParameter(name);
-                    param.append(name + "=" + value + "&");
-                }
-            }
-            this.paramHref = param.toString();
-            return true;
-        }
-        return false;
-    }
-
     public boolean pageInit(Page page, HttpServletRequest request){
         if (page.getTotalElements() > page.getSize() && page.getNumberOfElements() != 0){
 

+ 4 - 0
dmaster/src/main/resources/static/js/main.js

@@ -351,6 +351,8 @@ layui.use(['element', 'form', 'layer', 'upload'], function () {
         if (getSearch !== "") {
             getSearch = "?" + getSearch.substr(0, getSearch.length - 1);
         }
+
+        console.log('搜索参数 -> ' + getSearch)
         window.location.href = window.location.pathname + getSearch;
     };
 
@@ -358,10 +360,12 @@ layui.use(['element', 'form', 'layer', 'upload'], function () {
     $(document).on("click", ".timo-search-btn", function () {
         paramSkip();
     });
+
     /* 改变显示页数 */
     $(document).on("change", ".page-number", function () {
         paramSkip();
     });
+
     /* 触发字段排序 */
     $(document).on("click", ".sortable", function () {
         $(".sortable").not(this).removeClass("asc").removeClass("desc");

+ 17 - 8
dmaster/src/main/resources/templates/app/build.html

@@ -2,26 +2,27 @@
 <html xmlns:th="http://www.thymeleaf.org"
       xmlns:mo="https://gitee.com/aun/Timo">
 <head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+
 <body class="timo-layout-page">
-<div class="layui-card">
+<div class="layui-card" th:attr="data-url=@{'/app/build/list?env=' + ${env}}">
     <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-left layui-form-pane timo-search-box">
+            <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 class="timo-search-select" name="status" mo:dict="SEARCH_STATUS"
-                                mo-selected="${param.env}"></select>
+                        <select id="getPageByEnv" class="timo-search-select" name="env" onchange="getPageByEnv()"
+                                mo:dict="ENVIRONMENT" mo-selected="${env}"></select>
                     </div>
                 </div>
-                <div class="layui-inline">
+                <div class="layui-inline timo-search-box">
                     <label class="layui-form-label">应用</label>
                     <div class="layui-input-block">
-                        <input type="text" name="appId" th:value="${param.appId}" placeholder="请输入应用"
+                        <input type="text" name="appId" th:value="${param.appName}" placeholder="请输入应用名字"
                                autocomplete="off" class="layui-input">
                     </div>
                 </div>
@@ -55,14 +56,14 @@
                     <td><label class="timo-checkbox"><input type="checkbox" th:value="${item.appId}">
                         <i class="layui-icon layui-icon-ok"></i></label></td>
                     <td>
-                        <a class="open-popup" data-title="应用配置详情" data-size="1000,600" href="#"
+                        <a class="open-popup" data-title="应用配置详情" data-size="1200,600" href="#"
                            th:text="${item.appId}" th:attr="data-url=@{'/app/config/app/detail/'+${item.appId}}"></a>
                     </td>
                     <td th:text="${item.branch}">分支</td>
                     <td th:text="${item.commitId}">版本</td>
                     <td th:text="${item.commitTime}">提交时间</td>
                     <td>
-                        <a class="open-popup" data-title="构建结果" data-size="800,600" href="#"
+                        <a class="open-popup" data-title="构建结果" data-size="640,480" href="#"
                            th:text="${item.buildResult}" th:attr="data-url=@{'/app/log/build/'+${item.buildLogId} + '/result'}"></a>
                     </td>
                     <td th:text="${item.buildTime}">构建时间</td>
@@ -80,8 +81,16 @@
         <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 getPageByEnv() {
+        var selectedOption = $("#getPageByEnv option:selected")
+        var param = selectedOption.text()
+        url = '?env=' + param
+        window.location.href = window.location.pathname + url;
+    }
 </script>
 </body>
 </html>

+ 90 - 0
dmaster/src/main/resources/templates/app/config/app/add.bak.html

@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<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>
+<div class="layui-form timo-compile">
+    <form th:action="@{/app/config/app}">
+        <input type="hidden" name="id" th:if="${app}" th:value="${app.id}"/>
+        <div class="layui-form-item" th:if="!${app}">
+            <label class="layui-form-label required">应用 ID</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="appId"  placeholder="请输入应用 ID">
+            </div>
+        </div>
+        <div class="layui-form-item" th:if="${app}">
+            <label class="layui-form-label required">应用 ID</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="appId"  placeholder="请输入应用 ID" disabled="disabled" th:value="${app.appId}">
+            </div>
+        </div>
+        <div class="layui-form-item" th:if="${app}">
+            <label class="layui-form-label required">应用名</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="appName"  placeholder="请输入应用名" th:value="${app.appName}">
+            </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="appName" placeholder="请输入用户昵称" th:value="${app?.appName}">
+            </div>
+        </div>
+        <div class="layui-form-item" th:if="!${app}">
+            <label class="layui-form-label required">用户密码</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="password" name="appName" 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="appName" placeholder="请输入电话号码" th:value="${app?.appName}">
+            </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="appName" placeholder="请输入邮箱" th:value="${app?.appName}">
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label">环境</label>
+            <div class="layui-input-inline">
+                <!--<input type="radio" name="env" value="1" title="dev" checked>
+                <div class="layui-unselect layui-form-radio layui-form-radioed">
+                    <i class="layui-anim layui-icon"></i>
+                    <div>dev</div>
+                </div>
+                <input type="radio" name="env" value="2" title="test" checked>
+                <div class="layui-unselect layui-form-radio layui-form-radioed">
+                    <i class="layui-anim layui-icon"></i>
+                    <div>test</div>
+                </div>
+                <input type="radio" name="env" value="3" title="prod" th:checked="${app?.appName} eq 3">
+                <div class="layui-unselect layui-form-radio">
+                    <i class="layui-anim layui-icon"></i>
+                    <div>prod</div>
+                </div>-->
+            </div>
+        </div>
+        <div class="layui-form-item layui-form-text">
+            <label class="layui-form-label">备注</label>
+            <div class="layui-input-block">
+                <textarea placeholder="请输入内容" class="layui-textarea" name="appName">[[${app?.appName}]]</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">
+</script>
+</body>
+</html>

+ 231 - 82
dmaster/src/main/resources/templates/app/config/app/add.html

@@ -1,71 +1,240 @@
 <!DOCTYPE html>
-<html xmlns:th="http://www.thymeleaf.org"
-      xmlns:mo="https://gitee.com/aun/Timo">
-
+<html xmlns:th="http://www.thymeleaf.org">
 <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>
 <div class="layui-form timo-compile">
-    <form th:action="@{/system/user/save}">
-        <input type="hidden" name="id" th:if="${user}" th:value="${user.id}"/>
-        <div class="layui-form-item" th:if="!${user}">
-            <label class="layui-form-label required">用户名</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="username"  placeholder="请输入用户名">
-            </div>
-        </div>
-        <div class="layui-form-item" th:if="${user}">
-            <label class="layui-form-label required">用户名</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="username"  placeholder="请输入用户名" disabled="disabled" th:value="${user.username}">
-            </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="nickname" placeholder="请输入用户昵称" th:value="${user?.nickname}">
-            </div>
-        </div>
-        <div class="layui-form-item" th:if="!${user}">
-            <label class="layui-form-label required">用户密码</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="password" name="password" placeholder="请输入用户密码">
-                <!--<img id="img" src="/imgs/icons/icon-visible.png" onclick="hideOrShow()">-->
-            </div>
-        </div>
-        <div class="layui-form-item" th:if="!${user}">
-            <label class="layui-form-label required">确认密码</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="password" name="confirm" 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="phone" placeholder="请输入电话号码" th:value="${user?.phone}">
-            </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="email" placeholder="请输入邮箱" th:value="${user?.email}">
-            </div>
-        </div>
-
-        <div class="layui-form-item">
-            <label class="layui-form-label">选择性别</label>
-            <div class="layui-input-inline">
-                <input type="radio" name="gender" value="1" title="男" checked><div class="layui-unselect layui-form-radio layui-form-radioed"><i class="layui-anim layui-icon"></i><div>男</div></div>
-                <input type="radio" name="gender" value="2" title="女" th:checked="${user?.gender} eq 2"><div class="layui-unselect layui-form-radio"><i class="layui-anim layui-icon"></i><div>女</div></div>
-            </div>
-        </div>
-        <div class="layui-form-item layui-form-text">
-            <label class="layui-form-label">备注</label>
-            <div class="layui-input-block">
-                <textarea placeholder="请输入内容" class="layui-textarea" name="remark">[[${user?.remark}]]</textarea>
-            </div>
-        </div>
+    <form th:action="@{/app/config/app}">
+        <input type="hidden" name="id" th:if="${app}" th:value="${app?.id}"/>
+        <div class="timo-detail-title">基本信息</div>
+        <table class="layui-table timo-detail-table">
+            <tbody>
+            <tr>
+                <th>应用 ID</th>
+                <td>
+                    <div class="layui-form-item" th:if="!${app}">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="appId"  placeholder="请输入应用 ID" required th:value="${app?.appId}">
+                        </div>
+                    </div>
+                    <div class="layui-form-item" th:if="${app}">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="appId"  placeholder="请输入应用 ID" disabled="disabled" th:value="${app?.appId}">
+                        </div>
+                    </div>
+                </td>
+                <th>应用名</th>
+                <td >
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="appName"  placeholder="请输入应用名" required th:value="${app?.appName}">
+                        </div>
+                    </div>
+                </td>
+                <th>是否启用</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="enable"  placeholder="请输入是否启用" required th:value="${app?.enable}">
+                        </div>
+                    </div>
+                </td>
+            </tr>
+            <tr>
+                <th>所属环境</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="env"  placeholder="请输入应用所属环境" required th:value="${app?.env}">
+                        </div>
+                    </div>
+                </td>
+                <th>应用类型</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="appType"  placeholder="请输入应用类型" required th:value="${app?.appType}">
+                        </div>
+                    </div>
+                </td>
+                <th>应用描述</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="description"  placeholder="请输入应用描述" required th:value="${app?.description}">
+                        </div>
+                    </div>
+                </td>
+            </tr>
+            <tr>
+                <th>应用仓库</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="appRepo"  placeholder="请输入应用仓库" required th:value="${app?.appRepo}">
+                        </div>
+                    </div>
+                </td>
+                <th>仓库分支</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="branch"  placeholder="请输入仓库分支" required th:value="${app?.branch}">
+                        </div>
+                    </div>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+        <div class="timo-detail-title">构建配置</div>
+        <table class="layui-table timo-detail-table">
+            <tbody>
+            <tr>
+                <th>代码目录</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="env"  placeholder="请输入应用所属环境" required th:value="${app?.env}">
+                        </div>
+                    </div>
+                </td>
+                <th>编译目录</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="appType"  placeholder="请输入应用类型" required th:value="${app?.appType}">
+                        </div>
+                    </div>
+                </td>
+                <th>可执行文件名</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="description"  placeholder="请输入应用描述" required th:value="${app?.description}">
+                        </div>
+                    </div>
+                </td>
+            </tr>
+            <tr>
+                <th>Dockerfile</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="appRepo"  placeholder="请输入应用仓库" required th:value="${app?.appRepo}">
+                        </div>
+                    </div>
+                </td>
+            </tr>
+            <tr>
+                <th>仓库名字</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="repoAuthName"  placeholder="请输入仓库名字" required th:value="${app?.buildConfig?.repoAuthConfig?.name}">
+                        </div>
+                    </div>
+                </td>
+                <th>编译器名字</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="compilerName"  placeholder="请输入编译器名字" required th:value="${app?.buildConfig?.compilerConfig?.name}">
+                        </div>
+                    </div>
+                </td>
+                <th>打包名字</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="packerName"  placeholder="请输入打包名字" required th:value="${app?.buildConfig?.packerConfig?.name}">
+                        </div>
+                    </div>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+        <div class="timo-detail-title">部署配置</div>
+        <table class="layui-table timo-detail-table">
+            <tbody>
+            <tr>
+                <th>机器 ID</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="appName"  placeholder="请输入机器 ID" required th:value="${app?.appName}">
+                        </div>
+                    </div>
+                </td>
+                <th>机器地址</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="appName"  placeholder="请输入机器地址" required th:value="${app?.appName}">
+                        </div>
+                    </div>
+                </td>
+                <th>打包类型</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="appName"  placeholder="请输入打包类型" required th:value="${app?.appName}">
+                        </div>
+                    </div>
+                </td>
+            </tr>
+            <tr>
+                <th>Docker 配置</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="appName"  placeholder="请输入 Docker 配置" required th:value="${app?.appName}">
+                        </div>
+                    </div>
+                </td>
+                <th>启动目录</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="appName"  placeholder="请输入启动目录" required th:value="${app?.appName}">
+                        </div>
+                    </div>
+                </td>
+                <th>启动脚本</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="appName"  placeholder="请输入启动脚本" required th:value="${app?.appName}">
+                        </div>
+                    </div>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+        <div class="timo-detail-title">运行配置</div>
+        <table class="layui-table timo-detail-table">
+            <tbody>
+            <tr>
+                <th>HTTP 端口</th>
+                <td>
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="httpPort"  placeholder="请输入应用的 HTTP 端口" th:value="${app?.runningConfig?.httpPort}">
+                        </div>
+                    </div>
+                </td>
+                <th>健康检查地址</th>
+                <td >
+                    <div class="layui-form-item">
+                        <div class="layui-input-inline">
+                            <input class="layui-input" type="text" name="healthCheck"  placeholder="请输入健康检查 URI" required th:value="${app?.runningConfig?.healthCheck}">
+                        </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>
@@ -74,27 +243,7 @@
 </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:src="@{/lib/zTree_v3/js/jquery.ztree.core.min.js}"></script>
-<script type="text/javascript" th:src="@{/js/timoTree.js}"></script>
 <script type="text/javascript">
-    // 树形菜单
-    $.fn.selectTree();
-</script>
-<script type="text/javascript">
-    var img = document.getElementById("img");
-    var passwd = document.getElementById("LAY-user-login-password");
-
-    function hideOrShow() {
-        if (passwd.type == "password") {
-            passwd.type = "text";
-             // 闭眼图片
-            img.src = "../layui/images/icon-invisible.png";
-        } else {
-            passwd.type = "password";
-             // 睁眼图片
-            img.src = "../layui/images/icon-visible.png";
-        }
-    }
 </script>
 </body>
 </html>

+ 39 - 11
dmaster/src/main/resources/templates/app/config/app/detail.html

@@ -7,26 +7,44 @@
         <table class="layui-table timo-detail-table">
             <tbody>
             <tr>
-                <th>应用</th>
+                <th>应用 ID</th>
                 <td th:text="${app.appId}"></td>
-                <th>描述</th>
-                <td th:text="${app.description}"></td>
-                <th>类型</th>
+                <th>应用名称</th>
+                <td th:text="${app.appName}"></td>
+                <th>是否启用</th>
+                <td th:text="${app.enable}"></td>
+            </tr>
+            <tr>
+                <th>所属环境</th>
+                <td th:text="${app.env}"></td>
+                <th>应用类型</th>
                 <td th:text="${app.appType}"></td>
+                <th>应用描述</th>
+                <td th:text="${app.description}"></td>
             </tr>
             <tr>
-                <th>仓库</th>
+                <th>应用仓库</th>
                 <td th:text="${app.appRepo}"></td>
-                <th>分支</th>
+                <th>仓库分支</th>
                 <td th:text="${app.branch}"></td>
-                <th>环境</th>
-                <td th:text="${app.env}"></td>
             </tr>
             </tbody>
         </table>
         <div class="timo-detail-title">构建配置</div>
         <table class="layui-table timo-detail-table">
             <tbody>
+            <tr>
+                <th>代码目录</th>
+                <td th:text="${app.dirname}"></td>
+                <th>编译目录</th>
+                <td th:text="${app.compileHome}"></td>
+                <th>可执行文件名</th>
+                <td th:text="${app.execBinName}"></td>
+            </tr>
+            <tr>
+                <th>Dockerfile</th>
+                <td th:text="${app.dockerfile}"></td>
+            </tr>
             <tr>
                 <th>仓库类型</th>
                 <td th:text="${app.buildConfig.repoAuthConfig.type}"></td>
@@ -56,9 +74,19 @@
         <div class="timo-detail-title">部署配置</div>
         <table class="layui-table timo-detail-table">
             <tbody>
-            <tr>
-                <th>仓库</th>
-                <td th:text="${app.appRepo}"></td>
+            <tr th:each="item:${app.deployConfigs}">
+                <th>机器 ID</th>
+                <td th:text="${item.machineId}"></td>
+                <th>机器地址</th>
+                <td th:text="${item.machineIpv4}"></td>
+                <th>打包类型</th>
+                <td th:text="${item.packerType}"></td>
+                <th th:if="${item?.packerType} != 'docker'">启动目录</th>
+                <td th:if="${item?.packerType} != 'docker'" th:text="${item.startHome}"></td>
+                <th th:if="${item?.packerType} != 'docker'">启动脚本</th>
+                <td th:if="${item?.packerType} != 'docker'" th:text="${item.startScript}"></td>
+                <th th:if="${item?.packerType} eq 'docker'">docker 配置</th>
+                <td th:if="${item?.packerType} eq 'docker'" th:text="${item.dockerConfig}"></td>
             </tr>
             </tbody>
         </table>

+ 44 - 32
dmaster/src/main/resources/templates/app/config/app/index.html

@@ -9,43 +9,45 @@
     <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>
-        <a th:href="@{/system/user/export}"><i class="fa fa-download"></i></a>
+        <a th:href="@{/app/config/app/export}"><i class="fa fa-download"></i></a>
     </div>
     <div class="layui-card-body">
         <div class="layui-row timo-card-screen put-row">
-            <div class="pull-left layui-form-pane timo-search-box">
-                <div class="layui-inline">
-                    <label class="layui-form-label">环境</label>
-                    <div class="layui-input-block timo-search-status">
-                        <select class="timo-search-select" name="status" mo:dict="SEARCH_STATUS"
-                                mo-selected="${param.status}"></select>
+            <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 class="layui-inline">
-                    <label class="layui-form-label">应用 ID</label>
-                    <div class="layui-input-block">
-                        <input type="text" name="username" th:value="${param.appId}" placeholder="请输入应用 ID"
-                               autocomplete="off" class="layui-input">
+                    <div class="layui-inline timo-search-box">
+                        <label class="layui-form-label">应用</label>
+                        <div class="layui-input-block">
+                            <input type="text" name="appName" th:value="${param.appName}" placeholder="请输入应用名"
+                                   autocomplete="off" class="layui-input">
+                        </div>
+                    </div>
+                    <div class="layui-inline">
+                        <button class="layui-btn timo-search-btn">
+                            <i class="fa fa-search"></i>
+                        </button>
                     </div>
-                </div>
-                <div class="layui-inline">
-                    <button class="layui-btn timo-search-btn">
-                        <i class="fa fa-search"></i>
-                    </button>
                 </div>
             </div>
             <div class="pull-right screen-btn-group">
                 <div class="btn-group-right">
-                    <button class="layui-btn open-popup" data-title="添加应用" th:attr="data-url=@{/system/user/add}"
-                            data-size="auto">
+                    <button class="layui-btn open-popup" data-title="添加应用" th:attr="data-url=@{/app/config/app/add}"
+                            data-size="1200,600">
                         <i class="fa fa-plus"></i> 添加
                     </button>
                     <div class="btn-group">
                         <button class="layui-btn">操作<span class="caret"></span></button>
                         <dl class="layui-nav-child layui-anim layui-anim-upbit">
-                            <dd><a class="ajax-status" th:href="@{/system/user/status/ok}">启用</a></dd>
-                            <dd><a class="ajax-status" th:href="@{/system/user/status/freezed}">冻结</a></dd>
-                            <dd><a class="ajax-status" th:href="@{/system/user/status/delete}">删除</a></dd>
+                            <dd><a class="ajax-status" th:href="@{/app/config/app/ok}">启用</a></dd>
+                            <dd><a class="ajax-status" th:href="@{/app/config/app/freezed}">冻结</a></dd>
+                            <dd><a class="ajax-status" th:href="@{/app/config/app/delete}">删除</a></dd>
                         </dl>
                     </div>
                 </div>
@@ -59,8 +61,8 @@
                         <label class="timo-checkbox"><input type="checkbox">
                             <i class="layui-icon layui-icon-ok"></i></label>
                     </th>
-                    <th class="sortable" data-field="appId">应用 ID</th>
-                    <th class="sortable" data-field="description">描述</th>
+                    <th class="sortable" data-field="appName">应用</th>
+                    <th class="sortable" data-field="env">环境</th>
                     <th class="sortable" data-field="branch">分支</th>
                     <th class="sortable" data-field="dirname">应用目录</th>
                     <th class="sortable" data-field="appType">应用类型</th>
@@ -72,20 +74,20 @@
                 <tr th:each="item:${list}">
                     <td><label class="timo-checkbox"><input type="checkbox" th:value="${item.appId}">
                         <i class="layui-icon layui-icon-ok"></i></label></td>
-                    <td th:text="${item.appId}">应用 ID</td>
-                    <td th:text="${item.description}">描述</td>
+                    <td th:text="${item.appName}">应用名</td>
+                    <td th:text="${item.env}">环境</td>
                     <td th:text="${item.branch}">分支</td>
                     <td th:text="${item.dirname}">应用目录</td>
                     <td th:text="${item.appType}">应用类型</td>
                     <td th:text="${item.runningConfig.httpPort}">HTTP 端口</td>
                     <td>
-                        <a class="open-popup" data-title="拷贝" th:attr="data-url=@{'/app/config/app/edit/'+${item.appId}}"
+                        <a class="open-popup" data-title="拷贝" th:attr="data-url=@{'/app/config/app/edit/'+${item.id}}"
                            data-size="480,320" href="#">拷贝</a>
                         <a class="open-popup" data-title="应用详细信息" th:attr="data-url=@{'/app/config/app/detail/'+${item.appId}}"
-                           data-size="1000,600" href="#">详细</a>
-                        <a class="open-popup" data-title="编辑" th:attr="data-url=@{'/app/config/app/edit/'+${item.appId}}"
-                           data-size="1000,600" href="#">编辑</a>
-                        <a class="ajax-delete" th:attr="data-msg='您是否删除'+${item.appId}"
+                           data-size="1200,600" href="#">详细</a>
+                        <a class="open-popup" data-title="编辑" th:attr="data-url=@{'/app/config/app/edit/'+${item.id}}"
+                           data-size="1200,600" href="#">编辑</a>
+                        <a class="ajax-delete" th:attr="data-msg='您是否删除'+${item.id}"
                            th:href="@{/api/app/config/app(ids=${item.appId})}">删除</a>
                     </td>
                 </tr>
@@ -95,6 +97,16 @@
         <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 getPageByEnv() {
+        var selectedOption = $("#getPageByEnv option:selected")
+        var param = selectedOption.text()
+        url = '?env=' + param
+        window.location.href = window.location.pathname + url;
+    }
+</script>
 </body>
 </html>

+ 7 - 78
dmaster/src/main/resources/templates/app/log.html

@@ -1,87 +1,16 @@
 <!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})"></head>
+<html xmlns:th="http://www.thymeleaf.org">
+<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="pull-left layui-form-pane timo-search-box">
-                <div class="layui-inline">
-                    <label class="layui-form-label">环境</label>
-                    <div class="layui-input-block timo-search-status">
-                        <select class="timo-search-select" name="status" mo:dict="SEARCH_STATUS"
-                                mo-selected="${param.env}"></select>
-                    </div>
-                </div>
-                <div class="layui-inline">
-                    <label class="layui-form-label">应用</label>
-                    <div class="layui-input-block">
-                        <input type="text" name="appId" th:value="${param.appId}" placeholder="请输入应用"
-                               autocomplete="off" class="layui-input">
-                    </div>
-                </div>
-                <div class="layui-inline">
-                    <button class="layui-btn timo-search-btn">
-                        <i class="fa fa-search"></i>
-                    </button>
-                </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="appId">应用</th>
-                    <th class="sortable" data-field="branch">分支</th>
-                    <th class="sortable" data-field="commitId">版本</th>
-                    <th class="sortable" data-field="commitTime">提交时间</th>
-                    <th class="sortable" data-field="result">构建结果</th>
-                    <th class="sortable" data-field="buildTime">构建时间</th>
-                    <th class="sortable" data-field="buildBy">构建用户</th>
-                    <th>操作</th>
-                </tr>
-                </thead>
-                <tbody>
-                <tr th:each="item:${list}">
-                    <td><label class="timo-checkbox"><input type="checkbox" th:value="${item.appId}">
-                        <i class="layui-icon layui-icon-ok"></i></label></td>
-                    <td>
-                        <a class="open-popup" data-title="应用配置详情" data-size="1000,600" href="#"
-                           th:text="${item.appId}" th:attr="data-url=@{'/app/config/app/detail/'+${item.appId}}"></a>
-                    </td>
-                    <td th:text="${item.branch}">分支</td>
-                    <td th:text="${item.commitId}">版本</td>
-                    <td th:text="${item.commitTime}">提交时间</td>
-                    <td>
-                        <a class="open-popup" data-title="构建结果" data-size="800,600" href="#"
-                           th:text="${item.buildResult}" th:attr="data-url=@{'/app/log/build/'+${item.buildLogId} + '/result'}"></a>
-                    </td>
-                    <td th:text="${item.buildTime}">构建时间</td>
-                    <td th:text="${item.buildBy}">构建用户</td>
-                    <td>
-                        <a class="ajax-post" th:href="@{'/api/app/bd/update?appId='+${item.appId}}">更新</a>
-                        <a class="ajax-post" th:href="@{'/api/app/bd/build?appId='+${item.appId}}">构建</a>
-                        <a class="open-popup" data-title="应用部署" th:attr="data-url=@{'/app/deploy/' + ${item.buildLogId}}"
-                           data-size="1000,600" href="#">部署</a>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
+    <div class="layui-bg-gray" style="padding: 30px;">
+        <div class="layui-card-body">
+            <p th:text="${msg}"></p>
         </div>
-        <div th:replace="/common/fragment :: page"></div>
     </div>
 </div>
 <script th:replace="/common/template :: script"></script>
-<script type="text/javascript">
-</script>
 </body>
 </html>

+ 1 - 1
dmaster/src/main/resources/templates/common/fragment.html

@@ -7,7 +7,7 @@
             <div class="page-info">
                 <span>显示 [[${(page.number*page.size)+1}]]/[[${(page.number*page.size)+page.numberOfElements}]] 条,共 [[${page.totalElements}]] 条记录</span>
                 <select class="timo-select page-number">
-                    <option th:value="${num*10}" th:selected="${page.size} eq ${num*10}" th:each="num:${#numbers.sequence(1,3)}">[[${num*10}]] 条/页</option>
+                    <option th:value="${num*10}" th:selected="${page.size} eq ${num*10}" th:each="num:${#numbers.sequence(1,10,3)}">[[${num*10}]] 条/页</option>
                 </select>
             </div>
         </div>

+ 24 - 2
dmaster/src/test/java/cn/reghao/autodop/dmaster/app/entity/AppDeployingTest.java

@@ -3,6 +3,7 @@ package cn.reghao.autodop.dmaster.app.entity;
 import cn.reghao.autodop.dmaster.DmasterApplication;
 import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
 import cn.reghao.autodop.dmaster.app.entity.config.deploy.DeployConfig;
+import cn.reghao.autodop.dmaster.app.repository.AppBuildingRepository;
 import cn.reghao.autodop.dmaster.app.repository.AppDeployingRepository;
 import cn.reghao.autodop.dmaster.app.repository.config.AppOrchestrationRepository;
 import cn.reghao.autodop.dmaster.machine.entity.MachineInfo;
@@ -29,10 +30,31 @@ class AppDeployingTest {
     @Autowired
     private MachineInfoRepository machineInfoRepository;
     @Autowired
-    private AppDeployingRepository appDeployingRepository;
+    private AppBuildingRepository buildingRepository;
+    @Autowired
+    private AppDeployingRepository deployingRepository;
+
+    @Test
+    public void appBuilding() {
+        List<AppOrchestration> apps = appOrchestrationRepository.findAll();
+        List<AppBuilding> list = new ArrayList<>();
+        for (AppOrchestration app : apps) {
+            if (!app.getEnable()) {
+                continue;
+            }
+
+            AppBuilding entity = buildingRepository.findByAppId(app.getAppId());
+            if (entity != null) {
+                continue;
+            }
+
+            list.add(new AppBuilding(app));
+        }
+        buildingRepository.saveAll(list);
+    }
 
     @Test
-    public void test() {
+    public void appDeploying() {
         List<AppOrchestration> apps = appOrchestrationRepository.findAll();
         List<AppDeploying> appDeployings = new ArrayList<>();
         for (AppOrchestration app : apps) {