Browse Source

One panel, one instance;
Enable/disable kanban in panel instance

sunyj 8 years ago
parent
commit
f0cee36ec6
20 changed files with 478 additions and 285 deletions
  1. 1 1
      kanban-auth/src/main/java/com/uas/kanban/SecurityConfiguration.java
  2. 12 0
      kanban-common/src/main/java/com/uas/kanban/base/BaseDao.java
  3. 32 28
      kanban-console/README.md
  4. 1 15
      kanban-console/src/main/java/com/uas/kanban/controller/PanelInstanceController.java
  5. 15 0
      kanban-console/src/main/java/com/uas/kanban/dao/KanbanDao.java
  6. 38 0
      kanban-console/src/main/java/com/uas/kanban/dao/PanelDao.java
  7. 24 4
      kanban-console/src/main/java/com/uas/kanban/dao/PanelInstanceDao.java
  8. 14 0
      kanban-console/src/main/java/com/uas/kanban/dao/ParameterDao.java
  9. 102 0
      kanban-console/src/main/java/com/uas/kanban/dao/UserPanelDao.java
  10. 0 23
      kanban-console/src/main/java/com/uas/kanban/model/Kanban.java
  11. 95 60
      kanban-console/src/main/java/com/uas/kanban/model/PanelInstance.java
  12. 64 0
      kanban-console/src/main/java/com/uas/kanban/model/UserPanel.java
  13. 0 8
      kanban-console/src/main/java/com/uas/kanban/service/KanbanService.java
  14. 1 26
      kanban-console/src/main/java/com/uas/kanban/service/PanelInstanceService.java
  15. 2 2
      kanban-console/src/main/java/com/uas/kanban/service/PanelService.java
  16. 1 15
      kanban-console/src/main/java/com/uas/kanban/service/impl/KanbanServiceImpl.java
  17. 52 87
      kanban-console/src/main/java/com/uas/kanban/service/impl/PanelInstanceServiceImpl.java
  18. 20 10
      kanban-console/src/main/java/com/uas/kanban/service/impl/PanelServiceImpl.java
  19. 1 2
      kanban-console/src/main/java/com/uas/kanban/service/impl/ParameterServiceImpl.java
  20. 3 4
      kanban-console/src/main/webapp/WEB-INF/views/console.html

+ 1 - 1
kanban-auth/src/main/java/com/uas/kanban/SecurityConfiguration.java

@@ -36,7 +36,7 @@ public class SecurityConfiguration extends WebMvcConfigurerAdapter {
         // 添加管理员才可访问的路径
         // 用户、面板管理
         securityInterceptor.addAdminPatterns("/user/save*/**", "/user/update*/**", "/user/delete*/**", "/user/get*/**",
-                "/panel/**");
+                "/panel/save*/**", "/panel/update*/**", "/panel/delete*/**");
         // 看板设计
         securityInterceptor.addAdminPatterns("/kanban/**", "/board");
         // 参数

+ 12 - 0
kanban-common/src/main/java/com/uas/kanban/base/BaseDao.java

@@ -553,6 +553,18 @@ public class BaseDao<T extends BaseEntity> {
         return query.get();
     }
 
+    /**
+     * 根据指定的 field 和值获取数据
+     *
+     * @param <K>   值的类型
+     * @param field 指定的field
+     * @param value 指定 field 的值
+     * @return 查询结果
+     */
+    public <K> T findOneBy(@NotEmpty("field") String field, @NotEmpty("value") K value) {
+        return createQuery().field(field).equal(value).get();
+    }
+
     /**
      * 根据指定的 field 和值获取数据
      *

+ 32 - 28
kanban-console/README.md

@@ -725,13 +725,6 @@
         <td>内容</td>
         <td>&lt;content&gt;...&lt;/content&gt;</td>
     </tr>
-    <tr>
-        <td>enabled</td>
-        <td>Boolean</td>
-        <td>✘</td>
-        <td>是否启用,默认为 true</td>
-        <td>true</td>
-    </tr>
     <tr>
         <td>panelCode</td>
         <td>String</td>
@@ -788,20 +781,6 @@
         <td>4个通用属性</td>
         <td colspan="4">大部分表均含有该部分属性,请参照[通用属性数据字典](#通用属性数据字典)</td>
     </tr>
-    <tr>
-        <td>name</td>
-        <td>String</td>
-        <td>✘</td>
-        <td>名称</td>
-        <td>产线面板</td>
-    </tr>
-    <tr>
-        <td>iconCls</td>
-        <td>String</td>
-        <td>✔</td>
-        <td>图标样式</td>
-        <td>grid-shortcut</td>
-    </tr>
     <tr>
         <td>switchFrequency</td>
         <td>Number</td>
@@ -820,7 +799,7 @@
         <td>parameters</td>
         <td>JSONArray</td>
         <td>✔</td>
-        <td>参数,具体字段请参照[数据字典](#参数数据字典)</td>
+        <td>参数,具体字段请参照[参数数据字典](#参数数据字典)</td>
         <td>
           [{
             "createTime": 1508399982885,
@@ -854,18 +833,43 @@
         </td>
     </tr>
     <tr>
-        <td>panelCode</td>
+        <td>relatedKanben</td>
         <td>String</td>
         <td>✘</td>
-        <td>面板 code</td>
+        <td>关联的看板 code,具体字段请参照[关联看板数据字典](#关联看板数据字典)</td>
         <td>5DE18FCEF14</td>
     </tr>
+</table>
+
+## <span id="关联看板数据字典">关联看板数据字典</span>
+<table border=0 cellpadding=5 cellspacing=0>
+    <tr style="color:#fff">
+        <th>名称</th>
+        <th>类型</th>
+        <th>可为空</th>
+        <th>描述</th>
+        <th>示例</th>
+    </tr>
     <tr>
-        <td>userCode</td>
+        <td>code</td>
         <td>String</td>
         <td>✘</td>
-        <td>用户 code</td>
-        <td>5DE18FCEF14</td>
+        <td>数据的唯一标识</td>
+        <td>4EC324CA714</td>
+    </tr>
+    <tr>
+        <td>name</td>
+        <td>String</td>
+        <td>✘</td>
+        <td>名称</td>
+        <td>产线看板</td>
+    </tr>
+    <tr>
+        <td>enabled</td>
+        <td>Boolean</td>
+        <td>✘</td>
+        <td>是否启用,默认为 true</td>
+        <td>true</td>
     </tr>
 </table>
 
@@ -891,7 +895,7 @@
         <td>面板实例 code</td>
     </tr>
     <tr>
-        <td>kanbanCode</td>
+        <td>relatedKanban</td>
         <td>String</td>
         <td>看板 code,可为空,为空时解析第一个看板数据</td>
     </tr>

+ 1 - 15
kanban-console/src/main/java/com/uas/kanban/controller/PanelInstanceController.java

@@ -12,7 +12,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
 
 import javax.servlet.http.HttpServletRequest;
-import java.util.List;
 import java.util.Map;
 
 /**
@@ -62,21 +61,8 @@ public class PanelInstanceController extends BaseController<PanelInstance> {
      */
     @RequestMapping("/get/byPanel/{panelCode}")
     @ResponseBody
-    public List<PanelInstance> getByPanelCode(@PathVariable("panelCode") String panelCode, HttpServletRequest request) {
+    public PanelInstance getByPanelCode(@PathVariable("panelCode") String panelCode, HttpServletRequest request) {
         return panelInstanceService.getByPanelCode(panelCode);
     }
 
-    /**
-     * 将实例保存到桌面
-     *
-     * @param json    json格式的数据
-     * @param request request
-     * @return 保存的实例
-     */
-    @RequestMapping("/save/toDesktop")
-    @ResponseBody
-    public PanelInstance saveToDesktop(@NotEmpty("json") String json, HttpServletRequest request) {
-        return panelInstanceService.saveToDesktop(json);
-    }
-
 }

+ 15 - 0
kanban-console/src/main/java/com/uas/kanban/dao/KanbanDao.java

@@ -1,9 +1,14 @@
 package com.uas.kanban.dao;
 
+import com.uas.kanban.annotation.NotEmpty;
 import com.uas.kanban.base.BaseDao;
 import com.uas.kanban.model.Kanban;
+import org.mongodb.morphia.query.Query;
 import org.springframework.stereotype.Component;
 
+import java.util.Collections;
+import java.util.List;
+
 /**
  * 看板
  *
@@ -18,4 +23,14 @@ public class KanbanDao extends BaseDao<Kanban> {
         return "看板";
     }
 
+    /**
+     * 获取指定面板的看板
+     *
+     * @param panelCode 所指定的面板 code
+     * @return 看板
+     */
+    public List<Kanban> findByPanelCode(@NotEmpty("panelCode") String panelCode) {
+        return findListBy("panelCode", Collections.singletonList(panelCode));
+    }
+
 }

+ 38 - 0
kanban-console/src/main/java/com/uas/kanban/dao/PanelDao.java

@@ -1,9 +1,18 @@
 package com.uas.kanban.dao;
 
+import com.uas.kanban.annotation.NotEmpty;
 import com.uas.kanban.base.BaseDao;
 import com.uas.kanban.model.Panel;
+import com.uas.kanban.model.User;
+import com.uas.kanban.support.SystemSession;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 /**
  * 面板
  *
@@ -13,6 +22,35 @@ import org.springframework.stereotype.Component;
 @Component
 public class PanelDao extends BaseDao<Panel> {
 
+    @Autowired
+    private UserPanelDao userPanelDao;
+
+    @Override
+    protected Map<String, Object> globalFilter() {
+        User user = SystemSession.checkUser();
+        // 管理员可查看所有面板
+        if (user.getRole() == User.Role.Admin) {
+            return null;
+        }
+        List<String> panelCodes = userPanelDao.findAllPanelCodes();
+        if (panelCodes == null) {
+            panelCodes = new ArrayList<>();
+        }
+        Map<String, Object> filters = new HashMap<>();
+        // 普通用户只能操作自己的实例
+        filters.put("code in", panelCodes);
+        return filters;
+    }
+
+    @Override
+    public Panel checkExist(@NotEmpty("code") String code) throws IllegalStateException {
+        Panel panel = findOne(code);
+        if (panel == null) {
+            throw new IllegalStateException(collectionSimpleName() + "不存在或未分配:" + code);
+        }
+        return panel;
+    }
+
     @Override
     protected String collectionSimpleName() {
         return "面板";

+ 24 - 4
kanban-console/src/main/java/com/uas/kanban/dao/PanelInstanceDao.java

@@ -1,12 +1,15 @@
 package com.uas.kanban.dao;
 
+import com.uas.kanban.annotation.NotEmpty;
 import com.uas.kanban.base.BaseDao;
 import com.uas.kanban.model.PanelInstance;
-import com.uas.kanban.model.User;
+import com.uas.kanban.model.UserPanel;
 import com.uas.kanban.support.SystemSession;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -18,12 +21,15 @@ import java.util.Map;
 @Component
 public class PanelInstanceDao extends BaseDao<PanelInstance> {
 
+    @Autowired
+    private UserPanelDao userPanelDao;
+
     @Override
     protected Map<String, Object> globalFilter() {
-        User user = SystemSession.checkUser();
+        List<String> userPanelCodes = userPanelDao.findAllCodes();
         Map<String, Object> filters = new HashMap<>();
-        // 普通用户只能操作自己的实例
-        filters.put("userCode", user.getCode());
+        // 所有用户只能操作自己的实例
+        filters.put("userPanelCode in", userPanelCodes);
         return filters;
     }
 
@@ -31,4 +37,18 @@ public class PanelInstanceDao extends BaseDao<PanelInstance> {
     protected String collectionSimpleName() {
         return "面板实例";
     }
+
+    /**
+     * 获取指定面板的实例
+     *
+     * @param panelCode 所指定的面板 code
+     * @return 面板实例
+     */
+    public PanelInstance findByPanelCode(@NotEmpty("panelCode") String panelCode) {
+        UserPanel userPanel = userPanelDao.findByUserCodeAndPanelCode(SystemSession.getUser().getCode(), panelCode);
+        if (userPanel == null) {
+            return null;
+        }
+        return findOneBy("userPanelCode", userPanel.getCode());
+    }
 }

+ 14 - 0
kanban-console/src/main/java/com/uas/kanban/dao/ParameterDao.java

@@ -1,9 +1,13 @@
 package com.uas.kanban.dao;
 
+import com.uas.kanban.annotation.NotEmpty;
 import com.uas.kanban.base.BaseDao;
 import com.uas.kanban.model.Parameter;
 import org.springframework.stereotype.Component;
 
+import java.util.Collections;
+import java.util.List;
+
 /**
  * 参数
  *
@@ -18,4 +22,14 @@ public class ParameterDao extends BaseDao<Parameter> {
         return "参数";
     }
 
+    /**
+     * 获取指定面板的参数
+     *
+     * @param panelCode 所指定的面板 code
+     * @return 参数
+     */
+    public List<Parameter> findByPanelCode(@NotEmpty("panelCode") String panelCode) {
+        return findListBy("panelCode", Collections.singletonList(panelCode));
+    }
+
 }

+ 102 - 0
kanban-console/src/main/java/com/uas/kanban/dao/UserPanelDao.java

@@ -0,0 +1,102 @@
+package com.uas.kanban.dao;
+
+import com.uas.kanban.annotation.NotEmpty;
+import com.uas.kanban.base.BaseDao;
+import com.uas.kanban.model.User;
+import com.uas.kanban.model.UserPanel;
+import com.uas.kanban.support.SystemSession;
+import com.uas.kanban.util.CollectionUtils;
+import org.mongodb.morphia.query.Query;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 用户面板(存储用户可查看的面板)
+ *
+ * @author sunyj
+ * @since 2017/10/18 14:21
+ */
+@Component
+public class UserPanelDao extends BaseDao<UserPanel> {
+
+    @Override
+    protected Map<String, Object> globalFilter() {
+        User user = SystemSession.checkUser();
+        Map<String, Object> filters = new HashMap<>();
+        // 普通用户只能查看已分配给自己的面板
+        filters.put("userCode", user.getCode());
+        return filters;
+    }
+
+    @Override
+    protected String collectionSimpleName() {
+        return "用户面板";
+    }
+
+    /**
+     * 获取所有 code
+     *
+     * @return code
+     */
+    public List<String> findAllCodes() {
+        Query<UserPanel> query = createQuery();
+        try {
+            return findField(query, "code", String.class);
+        } catch (NoSuchFieldException e) {
+            throw new IllegalStateException(e.getMessage(), e);
+        }
+    }
+
+    /**
+     * 获取用户所能查看的面板 code
+     *
+     * @return 面板 code
+     */
+    public List<String> findAllPanelCodes() {
+        Query<UserPanel> query = createQuery();
+        try {
+            return findField(query, "panelCode", String.class);
+        } catch (NoSuchFieldException e) {
+            throw new IllegalStateException(e.getMessage(), e);
+        }
+    }
+
+    /**
+     * 根据指定的用户 code 和面板 code 查询数据
+     *
+     * @param userCode  用户 code
+     * @param panelCode 面板 code
+     * @return 查询结果
+     */
+    public UserPanel findByUserCodeAndPanelCode(@NotEmpty("userCode") String userCode, @NotEmpty("panelCode") String panelCode) {
+        Query<UserPanel> query = createQuery();
+        Map<String, Object> filters = new HashMap<>();
+        filters.put("userCode", userCode);
+        filters.put("panelCode", panelCode);
+        filter(query, filters);
+        List<UserPanel> userPanels = find(query);
+        if (CollectionUtils.isEmpty(userPanels)) {
+            return null;
+        } else if (userPanels.size() > 1) {
+            throw new IllegalStateException("存在不止一条数据");
+        }
+        return userPanels.get(0);
+    }
+
+    /**
+     * 删除某个用户的数据,指定的面板除外
+     *
+     * @param userCode   用户 code
+     * @param panelCodes 面板 code
+     * @return 修改的数据条数
+     */
+    public int deleteExcept(@NotEmpty("userCode") String userCode, @NotEmpty("panelCodes") List<String> panelCodes) {
+        Map<String, Object> filters = new HashMap<>();
+        filters.put("userCode", userCode);
+        filters.put("panelCode nin", panelCodes);
+        return delete(filters);
+    }
+}

+ 0 - 23
kanban-console/src/main/java/com/uas/kanban/model/Kanban.java

@@ -40,26 +40,12 @@ public class Kanban extends BaseEntity {
     @FieldProperty(nullable = false)
     private String content;
 
-    /**
-     * 是否启用
-     */
-    @FieldProperty(nullable = false)
-    private Boolean enabled;
-
     /**
      * 面板 code {@link Panel}
      */
     @FieldProperty(nullable = false)
     private String panelCode;
 
-    @Override
-    public void init() {
-        if (enabled == null) {
-            enabled = true;
-        }
-        super.init();
-    }
-
     public String getName() {
         return name;
     }
@@ -92,14 +78,6 @@ public class Kanban extends BaseEntity {
         this.content = content;
     }
 
-    public Boolean getEnabled() {
-        return enabled;
-    }
-
-    public void setEnabled(Boolean enabled) {
-        this.enabled = enabled;
-    }
-
     public String getPanelCode() {
         return panelCode;
     }
@@ -115,7 +93,6 @@ public class Kanban extends BaseEntity {
                 ", title='" + title + '\'' +
                 ", description='" + description + '\'' +
                 ", content='" + content + '\'' +
-                ", enabled=" + enabled +
                 ", panelCode='" + panelCode + '\'' +
                 "} " + super.toString();
     }

+ 95 - 60
kanban-console/src/main/java/com/uas/kanban/model/PanelInstance.java

@@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.uas.kanban.annotation.FieldProperty;
 import com.uas.kanban.base.BaseEntity;
-import com.uas.kanban.support.SystemSession;
 import com.uas.kanban.util.CollectionUtils;
 import com.uas.kanban.util.ObjectUtils;
 import org.mongodb.morphia.annotations.Embedded;
@@ -12,6 +11,7 @@ import org.mongodb.morphia.annotations.Entity;
 import org.mongodb.morphia.annotations.Index;
 import org.mongodb.morphia.annotations.Indexes;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -21,7 +21,7 @@ import java.util.List;
  * @since 2017/10/18 15:58
  */
 @Entity
-@Indexes(@Index(value = "name, userCode", unique = true))
+@Indexes(@Index(value = "name, userPanelCode", unique = true))
 public class PanelInstance extends BaseEntity {
 
     /**
@@ -35,17 +35,6 @@ public class PanelInstance extends BaseEntity {
 
     private static final long serialVersionUID = 1L;
 
-    /**
-     * 名称
-     */
-    @FieldProperty(nullable = false)
-    private String name;
-
-    /**
-     * 图标样式
-     */
-    private String iconCls;
-
     /**
      * 切换频率(秒)(面板的展示方式为 {@link Panel.Display#AutoSwitch} 时,才生效)
      */
@@ -57,11 +46,6 @@ public class PanelInstance extends BaseEntity {
     @FieldProperty(nullable = false)
     private Double refreshFrequency;
 
-    /**
-     * 是否自动生成,如果是的话,普通用户不能删除
-     */
-    private Boolean autoGenerated;
-
     /**
      * 参数
      */
@@ -69,16 +53,17 @@ public class PanelInstance extends BaseEntity {
     private JSONArray parameters;
 
     /**
-     * 面板 code {@link Panel}
+     * 看板 code 及启用状态
      */
+    @Embedded
     @FieldProperty(nullable = false)
-    private String panelCode;
+    private List<RelatedKanban> relatedKanbans;
 
     /**
-     * 用户 code {@link User}
+     * 用户面板 code {@link UserPanel}
      */
     @FieldProperty(nullable = false)
-    private String userCode;
+    private String userPanelCode;
 
     @Override
     public void init() {
@@ -88,22 +73,6 @@ public class PanelInstance extends BaseEntity {
         super.init();
     }
 
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getIconCls() {
-        return iconCls;
-    }
-
-    public void setIconCls(String iconCls) {
-        this.iconCls = iconCls;
-    }
-
     public Double getSwitchFrequency() {
         return switchFrequency;
     }
@@ -120,14 +89,6 @@ public class PanelInstance extends BaseEntity {
         this.refreshFrequency = refreshFrequency;
     }
 
-    public Boolean getAutoGenerated() {
-        return autoGenerated;
-    }
-
-    public void setAutoGenerated(Boolean autoGenerated) {
-        this.autoGenerated = autoGenerated;
-    }
-
     public JSONArray getParameters() {
         return parameters;
     }
@@ -136,33 +97,31 @@ public class PanelInstance extends BaseEntity {
         this.parameters = parameters;
     }
 
-    public String getPanelCode() {
-        return panelCode;
+    public List<RelatedKanban> getRelatedKanbans() {
+        return relatedKanbans;
     }
 
-    public void setPanelCode(String panelCode) {
-        this.panelCode = panelCode;
+    public void setRelatedKanbans(List<RelatedKanban> relatedKanbans) {
+        this.relatedKanbans = relatedKanbans;
     }
 
-    public String getUserCode() {
-        return userCode;
+    public String getUserPanelCode() {
+        // TODO sort by enabled state
+        return userPanelCode;
     }
 
-    public void setUserCode(String userCode) {
-        this.userCode = userCode;
+    public void setUserPanelCode(String userPanelCode) {
+        this.userPanelCode = userPanelCode;
     }
 
     @Override
     public String toString() {
         return "PanelInstance{" +
-                "name='" + name + '\'' +
-                ", iconCls='" + iconCls + '\'' +
-                ", switchFrequency=" + switchFrequency +
+                "switchFrequency=" + switchFrequency +
                 ", refreshFrequency=" + refreshFrequency +
-                ", autoGenerated=" + autoGenerated +
                 ", parameters=" + parameters +
-                ", panelCode='" + panelCode + '\'' +
-                ", userCode='" + userCode + '\'' +
+                ", relatedKanbans=" + relatedKanbans +
+                ", userPanelCode='" + userPanelCode + '\'' +
                 "} " + super.toString();
     }
 
@@ -181,4 +140,80 @@ public class PanelInstance extends BaseEntity {
             this.parameters = JSONObject.parseArray(JSONObject.toJSONString(parameters));
         }
     }
+
+    /**
+     * 初始化看板 code 及启用状态
+     *
+     * @param kanbans 看板
+     */
+    public void initKanbanCodes(List<Kanban> kanbans) {
+        if (CollectionUtils.isEmpty(kanbans)) {
+            return;
+        }
+        relatedKanbans = new ArrayList<>();
+        for (Kanban kanban : kanbans) {
+            RelatedKanban relatedKanban = new RelatedKanban();
+            relatedKanban.setCode(kanban.getCode());
+            relatedKanban.setEnabled(true);
+            relatedKanban.setName(kanban.getName());
+            relatedKanbans.add(relatedKanban);
+        }
+    }
+
+    /**
+     * 看板 code 及启用状态
+     */
+    public static class RelatedKanban {
+
+        /**
+         * 看板 code {@link Kanban}
+         */
+        @FieldProperty(nullable = false)
+        private String code;
+
+        /**
+         * 名称
+         */
+        @FieldProperty(nullable = false)
+        private String name;
+
+        /**
+         * 是否启用
+         */
+        @FieldProperty(nullable = false)
+        private Boolean enabled = true;
+
+        public String getCode() {
+            return code;
+        }
+
+        public void setCode(String code) {
+            this.code = code;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public Boolean getEnabled() {
+            return enabled;
+        }
+
+        public void setEnabled(Boolean enabled) {
+            this.enabled = enabled;
+        }
+
+        @Override
+        public String toString() {
+            return "RelatedKanban{" +
+                    "code='" + code + '\'' +
+                    ", name='" + name + '\'' +
+                    ", enabled=" + enabled +
+                    '}';
+        }
+    }
 }

+ 64 - 0
kanban-console/src/main/java/com/uas/kanban/model/UserPanel.java

@@ -0,0 +1,64 @@
+package com.uas.kanban.model;
+
+import com.uas.kanban.annotation.FieldProperty;
+import com.uas.kanban.base.BaseEntity;
+import org.mongodb.morphia.annotations.Entity;
+import org.mongodb.morphia.annotations.Index;
+import org.mongodb.morphia.annotations.Indexes;
+
+/**
+ * 中间表,用户面板(存储用户可查看的面板)
+ *
+ * @author sunyj
+ * @since 2017/10/20 11:12
+ */
+@Entity
+@Indexes(@Index(value = "userCode, panelCode", unique = true))
+public class UserPanel extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 用户 code {@link User}
+     */
+    @FieldProperty(nullable = false)
+    private String userCode;
+
+    /**
+     * 面板 code {@link Panel}
+     */
+    @FieldProperty(nullable = false)
+    private String panelCode;
+
+    public UserPanel() {
+    }
+
+    public UserPanel(String userCode, String panelCode) {
+        this.userCode = userCode;
+        this.panelCode = panelCode;
+    }
+
+    public String getUserCode() {
+        return userCode;
+    }
+
+    public void setUserCode(String userCode) {
+        this.userCode = userCode;
+    }
+
+    public String getPanelCode() {
+        return panelCode;
+    }
+
+    public void setPanelCode(String panelCode) {
+        this.panelCode = panelCode;
+    }
+
+    @Override
+    public String toString() {
+        return "UserPanel{" +
+                "userCode='" + userCode + '\'' +
+                ", panelCode='" + panelCode + '\'' +
+                "} " + super.toString();
+    }
+}

+ 0 - 8
kanban-console/src/main/java/com/uas/kanban/service/KanbanService.java

@@ -21,12 +21,4 @@ public interface KanbanService {
      */
     List<Kanban> getByPanelCode(@NotEmpty("panelCode") String panelCode);
 
-    /**
-     * 获取指定面板已启用的看板 code
-     *
-     * @param panelCode 所指定的面板 code
-     * @return 看板 code
-     */
-    List<String> getEnabledCodesByPanelCode(@NotEmpty("panelCode") String panelCode);
-
 }

+ 1 - 26
kanban-console/src/main/java/com/uas/kanban/service/PanelInstanceService.java

@@ -3,7 +3,6 @@ package com.uas.kanban.service;
 import com.uas.kanban.annotation.NotEmpty;
 import com.uas.kanban.model.PanelInstance;
 
-import java.util.List;
 import java.util.Map;
 
 /**
@@ -23,36 +22,12 @@ public interface PanelInstanceService {
      */
     Map<String, Object> parseData(@NotEmpty("code") String code, String kanbanCode);
 
-    /**
-     * 删除指定面板的实例
-     *
-     * @param panelCodes 所指定的面板 code
-     * @return 删除的数据条数
-     */
-    int deleteByPanelCodes(@NotEmpty("panelCodes") List<String> panelCodes);
-
     /**
      * 获取指定面板的实例
      *
      * @param panelCode 所指定的面板 code
      * @return 面板实例
      */
-    List<PanelInstance> getByPanelCode(@NotEmpty("panelCode") String panelCode);
-
-    /**
-     * 根据指定的面板和用户生成面板实例
-     *
-     * @param userCodes  所指定的用户 code
-     * @param panelCodes 所指定的面板 code
-     * @return 面板实例
-     */
-    List<PanelInstance> generateInstances(@NotEmpty("userCodes") List<String> userCodes, @NotEmpty("panelCodes") List<String> panelCodes);
+    PanelInstance getByPanelCode(@NotEmpty("panelCode") String panelCode);
 
-    /**
-     * 将实例保存到桌面
-     *
-     * @param json json格式的数据
-     * @return 保存的实例
-     */
-    PanelInstance saveToDesktop(@NotEmpty("json") String json);
 }

+ 2 - 2
kanban-console/src/main/java/com/uas/kanban/service/PanelService.java

@@ -1,7 +1,7 @@
 package com.uas.kanban.service;
 
 import com.uas.kanban.annotation.NotEmpty;
-import com.uas.kanban.model.PanelInstance;
+import com.uas.kanban.model.UserPanel;
 
 import java.util.List;
 
@@ -20,6 +20,6 @@ public interface PanelService {
      * @param panelCodes 面板 code
      * @return 面板实例
      */
-    List<PanelInstance> assignPanel(@NotEmpty("userCode") String userCode, @NotEmpty("panelCodes") List<String> panelCodes);
+    List<UserPanel> assignPanel(@NotEmpty("userCode") String userCode, @NotEmpty("panelCodes") List<String> panelCodes);
 
 }

+ 1 - 15
kanban-console/src/main/java/com/uas/kanban/service/impl/KanbanServiceImpl.java

@@ -7,11 +7,9 @@ import com.uas.kanban.dao.PanelDao;
 import com.uas.kanban.exception.OperationException;
 import com.uas.kanban.model.Kanban;
 import com.uas.kanban.service.KanbanService;
-import org.mongodb.morphia.query.Query;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -76,19 +74,7 @@ public class KanbanServiceImpl extends BaseService<Kanban> implements KanbanServ
     @Override
     public List<Kanban> getByPanelCode(@NotEmpty("panelCode") String panelCode) {
         panelDao.checkExist(panelCode);
-        return kanbanDao.findListBy("panelCode", Collections.singletonList(panelCode));
-    }
-
-    @Override
-    public List<String> getEnabledCodesByPanelCode(@NotEmpty("panelCode") String panelCode) {
-        panelDao.checkExist(panelCode);
-        Query<Kanban> query = kanbanDao.createQuery();
-        query.field("panelCode").equal(panelCode);
-        try {
-            return kanbanDao.findField(query, "code", String.class);
-        } catch (NoSuchFieldException e) {
-            throw new IllegalStateException(e.getMessage(), e);
-        }
+        return kanbanDao.findByPanelCode(panelCode);
     }
 
 }

+ 52 - 87
kanban-console/src/main/java/com/uas/kanban/service/impl/PanelInstanceServiceImpl.java

@@ -3,20 +3,22 @@ package com.uas.kanban.service.impl;
 import com.alibaba.fastjson.JSONObject;
 import com.uas.kanban.annotation.NotEmpty;
 import com.uas.kanban.base.BaseService;
-import com.uas.kanban.dao.*;
+import com.uas.kanban.dao.KanbanDao;
+import com.uas.kanban.dao.PanelDao;
+import com.uas.kanban.dao.PanelInstanceDao;
+import com.uas.kanban.dao.UserPanelDao;
 import com.uas.kanban.exception.OperationException;
 import com.uas.kanban.model.*;
-import com.uas.kanban.service.KanbanService;
 import com.uas.kanban.service.PanelInstanceService;
 import com.uas.kanban.service.ParameterService;
 import com.uas.kanban.support.DataSourceManager;
 import com.uas.kanban.support.KanbanParser;
+import com.uas.kanban.support.SystemSession;
 import com.uas.kanban.util.CollectionUtils;
 import com.uas.kanban.util.ObjectUtils;
 import com.uas.kanban.util.StringUtils;
 import me.chyxion.jdbc.NewbieJdbcSupport;
 import org.dom4j.DocumentException;
-import org.mongodb.morphia.query.Query;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -45,13 +47,7 @@ public class PanelInstanceServiceImpl extends BaseService<PanelInstance> impleme
     private KanbanDao kanbanDao;
 
     @Autowired
-    private ParameterDao parameterDao;
-
-    @Autowired
-    private DataSourceDao dataSourceDao;
-
-    @Autowired
-    private KanbanService kanbanService;
+    private UserPanelDao userPanelDao;
 
     @Autowired
     private ParameterService parameterService;
@@ -95,7 +91,7 @@ public class PanelInstanceServiceImpl extends BaseService<PanelInstance> impleme
      * @return 生成的参数
      */
     private List<Parameter> generateParameters(@NotEmpty("panelInstance") PanelInstance panelInstance) {
-        String panelCode = panelInstance.getPanelCode();
+        String panelCode = userPanelDao.checkExist(panelInstance.getUserPanelCode()).getPanelCode();
         Panel panel = panelDao.checkExist(panelCode);
         String dataSourceCode = panel.getDataSourceCode();
         List<Parameter> parameters = parameterService.getByPanelCode(panelCode);
@@ -166,47 +162,21 @@ public class PanelInstanceServiceImpl extends BaseService<PanelInstance> impleme
         return update(json);
     }
 
-    @Override
-    public int deleteAll() throws OperationException {
-        // 需要检查实例是否是自动生成的,难以检查
-        throw new OperationException("不支持的操作");
-    }
-
-    @Override
-    public int deleteOne(@NotEmpty("code") String code) throws OperationException {
-        PanelInstance panelInstance = panelInstanceDao.findOne(code);
-        if (panelInstance != null) {
-            Boolean autoGenerated = panelInstance.getAutoGenerated();
-            if (autoGenerated != null && autoGenerated) {
-                throw new OperationException("不可删除该实例");
-            }
-        }
-        return super.deleteOne(code);
-    }
-
-    @Override
-    public int delete(@NotEmpty("codes") List<String> codes) throws OperationException {
-        List<PanelInstance> panelInstances = panelInstanceDao.findIn(codes);
-        if (CollectionUtils.isEmpty(panelInstances)) {
-            return 0;
-        }
-        for (PanelInstance panelInstance : panelInstances) {
-            Boolean autoGenerated = panelInstance.getAutoGenerated();
-            if (autoGenerated != null && autoGenerated) {
-                throw new OperationException("不可删除实例:" + panelInstance.getCode());
-            }
-        }
-        return super.delete(codes);
-    }
-
     @Override
     public Map<String, Object> parseData(@NotEmpty("code") String code, String kanbanCode) {
         PanelInstance panelInstance = panelInstanceDao.checkExist(code);
-        Panel panel = panelDao.checkExist(panelInstance.getPanelCode());
-        List<String> enabledKanbanCodes = kanbanService.getEnabledCodesByPanelCode(panel.getCode());
-        if (CollectionUtils.isEmpty(enabledKanbanCodes)) {
+        Panel panel = panelDao.checkExist(userPanelDao.checkExist(panelInstance.getUserPanelCode()).getPanelCode());
+        List<PanelInstance.RelatedKanban> relatedKanbans = panelInstance.getRelatedKanbans();
+        if (CollectionUtils.isEmpty(relatedKanbans)) {
             throw new IllegalStateException("面板下没有看板");
         }
+        // 只保留已启用的看板
+        List<String> enabledKanbanCodes = new ArrayList<>();
+        for (PanelInstance.RelatedKanban relatedKanban : relatedKanbans) {
+            if (relatedKanban.getEnabled() != null && relatedKanban.getEnabled()) {
+                enabledKanbanCodes.add(relatedKanban.getCode());
+            }
+        }
         // 如果指定了看板,则解析该看板,否则解析该面板下的第一个看板
         if (!StringUtils.isEmpty(kanbanCode)) {
             if (!enabledKanbanCodes.contains(kanbanCode)) {
@@ -239,7 +209,7 @@ public class PanelInstanceServiceImpl extends BaseService<PanelInstance> impleme
         Map<String, Object> result = new HashMap<>();
         Map<String, Object> instance = new HashMap<>();
         instance.put("parameters", parameters);
-        instance.put("kanbanCodes", enabledKanbanCodes);
+        instance.put("enabledKanbanCodes", enabledKanbanCodes);
         instance.put("display", panel.getDisplay());
         instance.put("switchFrequency", panelInstance.getSwitchFrequency());
         instance.put("refreshFrequency", panelInstance.getRefreshFrequency());
@@ -252,42 +222,43 @@ public class PanelInstanceServiceImpl extends BaseService<PanelInstance> impleme
     }
 
     @Override
-    public int deleteByPanelCodes(@NotEmpty("panelCodes") List<String> panelCodes) {
-        Query<PanelInstance> query = panelInstanceDao.createQuery().field("panelCode").in(panelCodes);
-        return panelInstanceDao.delete(query);
-    }
-
-    @Override
-    public List<PanelInstance> getByPanelCode(@NotEmpty("panelCode") String panelCode) {
+    public PanelInstance getByPanelCode(@NotEmpty("panelCode") String panelCode) {
         panelDao.checkExist(panelCode);
-        return panelInstanceDao.findListBy("panelCode", Collections.singletonList(panelCode));
-    }
-
-    @Override
-    public List<PanelInstance> generateInstances(@NotEmpty("userCodes") List<String> userCodes, @NotEmpty("panelCodes") List<String> panelCodes) {
-        List<PanelInstance> panelInstances = new ArrayList<>();
-        for (String panelCode : panelCodes) {
-            Panel panel = panelDao.checkExist(panelCode);
-            PanelInstance panelInstance = new PanelInstance();
-            panelInstance.setName(panel.getName());
-            panelInstance.setIconCls(panel.getIconCls());
-            panelInstance.setAutoGenerated(true);
-            panelInstance.setPanelCode(panelCode);
-            initSwitchFrequence(panelInstance);
-            panelInstance.toParameters(generateParameters(panelInstance));
-            for (String userCode : userCodes) {
-                // TODO generateInstances
-                // TODO implement batch save
-                try {
-                    PanelInstance panelInstanceClone = ObjectUtils.clone(panelInstance);
-                    panelInstanceClone.setUserCode(userCode);
-                    panelInstances.add(panelInstanceDao.save(panelInstanceClone));
-                } catch (ClassNotFoundException | IOException e) {
-                    throw new IllegalStateException("深克隆对象时失败", e);
+        PanelInstance panelInstance = panelInstanceDao.findByPanelCode(panelCode);
+        if (panelInstance == null) {
+            User user = SystemSession.getUser();
+            String userCode = user.getCode();
+            UserPanel userPanel = userPanelDao.findByUserCodeAndPanelCode(userCode, panelCode);
+            // 管理员可以查看所有面板,不必先分配,但是想要保存实例,就需要先建立关联
+            if (userPanel == null) {
+                if (user.getRole() == User.Role.Admin) {
+                    userPanel = userPanelDao.save(new UserPanel(userCode, panelCode));
+                }else{
+                    throw new IllegalArgumentException("用户未分配该面板");
                 }
             }
+            panelInstance = generateInstance(userPanel);
         }
-        return panelInstances;
+        return panelInstance;
+    }
+
+    /**
+     * 根据指定的用户面板生成面板实例
+     *
+     * @param userPanel 所指定的用户面板
+     * @return 面板实例
+     */
+    private PanelInstance generateInstance(@NotEmpty("userPanel") UserPanel userPanel) {
+        String panelCode = userPanel.getPanelCode();
+        Panel panel = panelDao.checkExist(panelCode);
+        PanelInstance panelInstance = new PanelInstance();
+        panelInstance.setUserPanelCode(userPanel.getCode());
+        initSwitchFrequence(panelInstance);
+        panelInstance.toParameters(generateParameters(panelInstance));
+        List<Kanban> kanbans = kanbanDao.findByPanelCode(panelCode);
+        panelInstance.initKanbanCodes(kanbans);
+        panelInstanceDao.save(panelInstance);
+        return panelInstance;
     }
 
     /**
@@ -297,7 +268,7 @@ public class PanelInstanceServiceImpl extends BaseService<PanelInstance> impleme
      */
     private void initSwitchFrequence(@NotEmpty("panelInstance") PanelInstance panelInstance)
             throws IllegalArgumentException {
-        Panel panel = panelDao.checkExist(panelInstance.getPanelCode());
+        Panel panel = panelDao.checkExist(userPanelDao.checkExist(panelInstance.getUserPanelCode()).getPanelCode());
         switch (panel.getDisplay()) {
             case AutoSwitch:
                 if (panelInstance.getSwitchFrequency() == null) {
@@ -312,10 +283,4 @@ public class PanelInstanceServiceImpl extends BaseService<PanelInstance> impleme
         }
     }
 
-    @Override
-    public PanelInstance saveToDesktop(@NotEmpty("json") String json) {
-        // TODO save to desktop
-        return null;
-    }
-
 }

+ 20 - 10
kanban-console/src/main/java/com/uas/kanban/service/impl/PanelServiceImpl.java

@@ -4,17 +4,16 @@ import com.uas.kanban.annotation.NotEmpty;
 import com.uas.kanban.base.BaseService;
 import com.uas.kanban.dao.DataSourceDao;
 import com.uas.kanban.dao.PanelDao;
+import com.uas.kanban.dao.UserPanelDao;
 import com.uas.kanban.exception.OperationException;
 import com.uas.kanban.model.Panel;
-import com.uas.kanban.model.PanelInstance;
-import com.uas.kanban.model.User;
+import com.uas.kanban.model.UserPanel;
 import com.uas.kanban.service.PanelInstanceService;
 import com.uas.kanban.service.PanelService;
-import com.uas.kanban.support.SystemSession;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Collections;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -32,6 +31,9 @@ public class PanelServiceImpl extends BaseService<Panel> implements PanelService
     @Autowired
     private DataSourceDao dataSourceDao;
 
+    @Autowired
+    private UserPanelDao userPanelDao;
+
     @Autowired
     private PanelInstanceService panelInstanceService;
 
@@ -40,10 +42,7 @@ public class PanelServiceImpl extends BaseService<Panel> implements PanelService
         // TODO generate PanelInstance
         Panel panel = panelDao.parse(json);
         dataSourceDao.checkExist(panel.getDataSourceCode());
-        panel = panelDao.save(panel);
-        User user = SystemSession.checkUser();
-        assignPanel(user.getCode(), Collections.singletonList(panel.getCode()));
-        return panel;
+        return panelDao.save(panel);
     }
 
     @Override
@@ -89,8 +88,19 @@ public class PanelServiceImpl extends BaseService<Panel> implements PanelService
     }
 
     @Override
-    public List<PanelInstance> assignPanel(@NotEmpty("userCode") String userCode, @NotEmpty("panelCodes") List<String> panelCodes) {
+    public List<UserPanel> assignPanel(@NotEmpty("userCode") String userCode, @NotEmpty("panelCodes") List<String> panelCodes) {
+        List<UserPanel> userPanels = new ArrayList<>();
+        for (String panelCode : panelCodes) {
+            // 如果已存在用户看板,不必再进行关联
+            UserPanel userPanel = userPanelDao.findByUserCodeAndPanelCode(userCode, panelCode);
+            if (userPanel == null) {
+                userPanel = userPanelDao.save(new UserPanel(userCode, panelCode));
+            }
+            userPanels.add(userPanel);
+        }
+        // 重新分配面板时,删除旧的
+        userPanelDao.deleteExcept(userCode, panelCodes);
         // delete user's PanelInstance before generating new instances?
-        return panelInstanceService.generateInstances(Collections.singletonList(userCode), panelCodes);
+        return userPanels;
     }
 }

+ 1 - 2
kanban-console/src/main/java/com/uas/kanban/service/impl/ParameterServiceImpl.java

@@ -11,7 +11,6 @@ import com.uas.kanban.util.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -110,7 +109,7 @@ public class ParameterServiceImpl extends BaseService<Parameter> implements Para
     @Override
     public List<Parameter> getByPanelCode(@NotEmpty("panelCode") String panelCode) {
         panelDao.checkExist(panelCode);
-        return parameterDao.findListBy("panelCode", Collections.singletonList(panelCode));
+        return parameterDao.findByPanelCode(panelCode);
     }
 
 }

+ 3 - 4
kanban-console/src/main/webapp/WEB-INF/views/console.html

@@ -82,17 +82,16 @@
         </ol>
         <strong><li class="title">面板实例</li></strong>
         <ol>
-            <li><a target="_blank">panelInstance/update?json={"code":"50C2C15A411","name": "name", "iconCls":"grid-shortcut","parameters":[{"code":"5061DFD0811","type":"String","defaultOptionalValueIndex":1,"inputMode":"DropDownBox","name":"参数1","optionalValues":["值1","值2"],"value":"值2", "panelCode": "4EC2735D343"},{"code":"5061E8A3812","type":"Number","defaultOptionalValueIndex":1,"inputMode":"DropDownBox","name":"参数2","optionalValues":[12,32],"value":12.0, "panelCode": "4EC2735D343"}],"panelCode":"50C01D61F19","userCode":"50C01D61F11","switchFrequency":5000,"refreshFrequency":5000}</a></li>
-            <li><a target="_blank">panelInstance/updatePart?json={"code":"50C2C15A411","name": "name", "iconCls":"grid-shortcut","parameters":[{"code":"5061DFD0811","type":"String","defaultOptionalValueIndex":1,"inputMode":"DropDownBox","name":"参数1","optionalValues":["值1","值2"],"value":"值2", "panelCode": "4EC2735D343"},{"code":"5061E8A3812","type":"Number","defaultOptionalValueIndex":1,"inputMode":"DropDownBox","name":"参数2","optionalValues":[12,32],"value":12.0, "panelCode": "4EC2735D343"}],"panelCode":"50C01D61F19","userCode":"50C01D61F11","refreshFrequency":5000}</a></li>
+            <li><a target="_blank">panelInstance/update?json={"code":"50C2C15A411","parameters":[{"code":"5061DFD0811","type":"String","defaultOptionalValueIndex":1,"inputMode":"DropDownBox","name":"参数1","optionalValues":["值1","值2"],"value":"值2", "panelCode": "4EC2735D343"},{"code":"5061E8A3812","type":"Number","defaultOptionalValueIndex":1,"inputMode":"DropDownBox","name":"参数2","optionalValues":[12,32],"value":12.0, "panelCode": "4EC2735D343"}],"panelCode":"50C01D61F19","userCode":"50C01D61F11","switchFrequency":5000,"refreshFrequency":5000}</a></li>
+            <li><a target="_blank">panelInstance/updatePart?json={"code":"50C2C15A411","parameters":[{"code":"5061DFD0811","type":"String","defaultOptionalValueIndex":1,"inputMode":"DropDownBox","name":"参数1","optionalValues":["值1","值2"],"value":"值2", "panelCode": "4EC2735D343"},{"code":"5061E8A3812","type":"Number","defaultOptionalValueIndex":1,"inputMode":"DropDownBox","name":"参数2","optionalValues":[12,32],"value":12.0, "panelCode": "4EC2735D343"}],"panelCode":"50C01D61F19","userCode":"50C01D61F11","refreshFrequency":5000}</a></li>
             <li><a target="_blank">panelInstance/delete/4EC2735D343</a></li>
             <li><a target="_blank">panelInstance/delete/byCodes?codes=53E04542411&codes=53E04631812</a></li>
             <li><a target="_blank">panelInstance/get/all</a></li>
             <li><a target="_blank">panelInstance/get/4EC2735D343</a></li>
             <li><a target="_blank">panelInstance/get?page=1&size=10</a></li>
             <br/>
-            <li><a target="_blank">panelInstance/parseData/4F6BDFB4213?kanbanCode=4EC2735D343</a></li>
+            <li><a target="_blank">panelInstance/parseData/4F6BDFB4213?relatedKanban=4EC2735D343</a></li>
             <li><a target="_blank">panelInstance/get/byPanel/4EC2735D343</a></li>
-            <li><a target="_blank">panelInstance/save/toDesktop?json={"code":"50C2C15A411","name": "name", "iconCls":"grid-shortcut","parameters":[{"code":"5061DFD0811","type":"String","defaultOptionalValueIndex":1,"inputMode":"DropDownBox","name":"参数1","optionalValues":["值1","值2"],"value":"值2", "panelCode": "4EC2735D343"},{"code":"5061E8A3812","type":"Number","defaultOptionalValueIndex":1,"inputMode":"DropDownBox","name":"参数2","optionalValues":[12,32],"value":12.0, "panelCode": "4EC2735D343"}],"panelCode":"50C01D61F19","userCode":"50C01D61F11","switchFrequency":5000,"refreshFrequency":5000}</a></li>
         </ol>
     </ol>
 </div>