Переглянути джерело

Merge remote-tracking branch 'origin/master'

Administrator 4 роки тому
батько
коміт
ff0bc29f1c
33 змінених файлів з 1981 додано та 22 видалено
  1. 11 0
      boman-api/boman-api-system/src/main/java/com/boman/system/api/RemoteDeptService.java
  2. 27 0
      boman-api/boman-api-system/src/main/java/com/boman/system/api/RemoteMenuService.java
  3. 27 0
      boman-api/boman-api-system/src/main/java/com/boman/system/api/RemoteRoleDataService.java
  4. 14 0
      boman-api/boman-api-system/src/main/java/com/boman/system/api/RemoteUserService.java
  5. 1 1
      boman-api/boman-api-web-core/src/main/java/com/boman/web/core/api/RemoteObjService.java
  6. 3 0
      boman-api/boman-domain/src/main/java/com.boman.domain/GenTable.java
  7. 1 2
      boman-api/boman-domain/src/main/java/com.boman.domain/SysRoleData.java
  8. 15 0
      boman-api/boman-domain/src/main/java/com.boman.domain/exception/UnSuchFunctionException.java
  9. 5 0
      boman-common/boman-common-core/src/main/java/com/boman/common/core/constant/ServiceNameConstants.java
  10. 1 1
      boman-common/boman-common-core/src/main/java/com/boman/common/core/utils/obj/ObjectUtils.java
  11. 11 0
      boman-modules/boman-system/src/main/java/com/boman/system/controller/SysDeptController.java
  12. 8 0
      boman-modules/boman-system/src/main/java/com/boman/system/controller/SysMenuController.java
  13. 9 1
      boman-modules/boman-system/src/main/java/com/boman/system/controller/SysRoleDataController.java
  14. 10 0
      boman-modules/boman-system/src/main/java/com/boman/system/controller/SysUserController.java
  15. 10 1
      boman-modules/boman-system/src/main/java/com/boman/system/mapper/SysRoleDataMapper.java
  16. 4 0
      boman-modules/boman-system/src/main/java/com/boman/system/mapper/SysUserMapper.java
  17. 9 0
      boman-modules/boman-system/src/main/java/com/boman/system/service/ISysDeptService.java
  18. 9 1
      boman-modules/boman-system/src/main/java/com/boman/system/service/ISysRoleDataService.java
  19. 5 0
      boman-modules/boman-system/src/main/java/com/boman/system/service/ISysUserService.java
  20. 33 0
      boman-modules/boman-system/src/main/java/com/boman/system/service/impl/SysDeptServiceImpl.java
  21. 12 1
      boman-modules/boman-system/src/main/java/com/boman/system/service/impl/SysRoleDataServiceImpl.java
  22. 7 0
      boman-modules/boman-system/src/main/java/com/boman/system/service/impl/SysUserServiceImpl.java
  23. 13 4
      boman-modules/boman-system/src/main/resources/mapper/system/SysRoleDataMapper.xml
  24. 7 0
      boman-modules/boman-system/src/main/resources/mapper/system/SysUserMapper.xml
  25. 12 0
      boman-web-core/src/main/java/com/boman/web/core/utils/ColumnUtils.java
  26. 147 0
      ruoyi-ui/src/components/FormItemComponent/index.vue
  27. 664 0
      ruoyi-ui/src/components/ItemComponent/index.vue
  28. 128 0
      ruoyi-ui/src/components/StandardTable/index.vue
  29. 341 0
      ruoyi-ui/src/components/listModalComponent/index.vue
  30. 435 0
      ruoyi-ui/src/views/activiti/modeler/index.vue
  31. 0 6
      ruoyi-ui/src/views/system/editing/index.vue
  32. 1 3
      ruoyi-ui/src/views/system/permissions/index.vue
  33. 1 1
      ruoyi-ui/src/views/system/role/fz-index.vue

+ 11 - 0
boman-api/boman-api-system/src/main/java/com/boman/system/api/RemoteDeptService.java

@@ -6,6 +6,8 @@ import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 
+import java.util.List;
+
 /**
  * @author shiqian
  * @date 2021年04月07日 10:31
@@ -21,5 +23,14 @@ public interface RemoteDeptService {
      */
     @GetMapping(value = "/dept/getById/{id}")
     SysDept getById(@PathVariable("id") Long id);
+
+    /**
+     * 功能描述: 拿到部门下所有的部门
+     *
+     * @param deptId deptId
+     * @return com.boman.common.core.web.domain.AjaxResult
+     */
+    @GetMapping("/dept/list/children/depts/{deptId}")
+    List<SysDept> listChildrenDepts(@PathVariable(value = "deptId") Long deptId);
 }
 

+ 27 - 0
boman-api/boman-api-system/src/main/java/com/boman/system/api/RemoteMenuService.java

@@ -0,0 +1,27 @@
+package com.boman.system.api;
+
+import com.boman.common.core.constant.ServiceNameConstants;
+import com.boman.system.api.domain.SysMenu;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+
+import java.util.List;
+
+/**
+ * @author shiqian
+ * @date 2021年04月07日 10:31
+ **/
+@FeignClient(contextId = "remoteMenuService", value = ServiceNameConstants.SYSTEM_SERVICE)
+public interface RemoteMenuService {
+
+    /**
+     * 功能描述: 根据userId查找此人的所有菜单
+     *
+     * @param userId userId
+     * @return java.util.List<com.boman.system.api.domain.SysMenu>
+     */
+    @GetMapping("/menu/listMenusByUserId/{userId}")
+    List<SysMenu> listMenusByUserId(@PathVariable("userId") Long userId);
+}
+

+ 27 - 0
boman-api/boman-api-system/src/main/java/com/boman/system/api/RemoteRoleDataService.java

@@ -0,0 +1,27 @@
+package com.boman.system.api;
+
+import com.boman.common.core.constant.ServiceNameConstants;
+import com.boman.domain.SysRoleData;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+/**
+ * @author shiqian
+ * @date 2021年04月07日 10:31
+ **/
+@FeignClient(contextId = "remoteRoleDataService", value = ServiceNameConstants.SYSTEM_SERVICE)
+public interface RemoteRoleDataService {
+
+    /**
+     * 功能描述: 根据userId查找此人的所有菜单
+     *
+     * @param idList idList
+     * @return java.util.List<com.boman.system.api.domain.SysMenu>
+     */
+    @PostMapping(value = "/roleData/listByRoleIdList")
+    List<SysRoleData> listByRoleIdList(@RequestBody List<Long> idList);
+}
+

+ 14 - 0
boman-api/boman-api-system/src/main/java/com/boman/system/api/RemoteUserService.java

@@ -1,5 +1,6 @@
 package com.boman.system.api;
 
+import com.boman.system.api.domain.SysUser;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -7,6 +8,10 @@ import com.boman.common.core.constant.ServiceNameConstants;
 import com.boman.common.core.domain.R;
 import com.boman.system.api.factory.RemoteUserFallbackFactory;
 import com.boman.system.api.model.LoginUser;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
 
 /**
  * 用户服务
@@ -24,4 +29,13 @@ public interface RemoteUserService
      */
     @GetMapping(value = "/user/info/{username}")
     public R<LoginUser> getUserInfo(@PathVariable("username") String username);
+
+    /**
+     * 部门下所有人
+     *
+     * @param deptIdList deptIdList
+     * @return 结果
+     */
+    @PostMapping("/user/listByDeptId")
+    List<SysUser> listByDeptId(@RequestBody List<Long> deptIdList);
 }

+ 1 - 1
boman-api/boman-api-web-core/src/main/java/com/boman/web/core/api/RemoteObjService.java

@@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.PathVariable;
  * @author shiqian
  * @date 2021年04月07日 10:31
  **/
-@FeignClient(contextId = "remoteObjService", value = ServiceNameConstants.SYSTEM_SERVICE)
+@FeignClient(contextId = "remoteObjService", value = ServiceNameConstants.WEB_CORE_SERVICE)
 public interface RemoteObjService {
 
     /**

+ 3 - 0
boman-api/boman-domain/src/main/java/com.boman.domain/GenTable.java

@@ -11,6 +11,9 @@ public class GenTable extends BaseEntity
 {
     private static final long serialVersionUID = 1L;
 
+    /** 查询 */
+    public static final String Q = "Q";
+
     /** 编号 */
     private Long Id;
 

+ 1 - 2
boman-modules/boman-system/src/main/java/com/boman/system/domain/SysRoleData.java → boman-api/boman-domain/src/main/java/com.boman.domain/SysRoleData.java

@@ -1,6 +1,5 @@
-package com.boman.system.domain;
+package com.boman.domain;
 
-import com.boman.common.core.web.domain.BaseEntity;
 import java.util.Date;
 
 /**

+ 15 - 0
boman-api/boman-domain/src/main/java/com.boman.domain/exception/UnSuchFunctionException.java

@@ -0,0 +1,15 @@
+package com.boman.domain.exception;
+
+/**
+ * @author shiqian
+ * @date 2021年04月21日 15:44
+ **/
+public class UnSuchFunctionException extends RuntimeException{
+
+    public UnSuchFunctionException(){}
+
+    public UnSuchFunctionException(String errorMsg){
+        super(errorMsg);
+    }
+
+}

+ 5 - 0
boman-common/boman-common-core/src/main/java/com/boman/common/core/constant/ServiceNameConstants.java

@@ -26,4 +26,9 @@ public class ServiceNameConstants
      * 代生成服务的serviceid
      */
     public static final String GEN_SERVICE = "boman-gen";
+
+    /**
+     * boman-web-core
+     */
+    public static final String WEB_CORE_SERVICE = "boman-web-core";
 }

+ 1 - 1
boman-common/boman-common-core/src/main/java/com/boman/common/core/utils/obj/ObjectUtils.java

@@ -244,7 +244,7 @@ public class ObjectUtils {
      */
     public static <T, R> List<R> map(List<T> input, Function<T, R> function) {
         return requireNonNull(input, "list is null")
-                .stream().map(function).collect(Collectors.toList());
+                .stream().map(function).distinct().collect(Collectors.toList());
     }
 
 

+ 11 - 0
boman-modules/boman-system/src/main/java/com/boman/system/controller/SysDeptController.java

@@ -68,6 +68,17 @@ public class SysDeptController extends BaseController
         return AjaxResult.success(depts);
     }
 
+    /**
+     * 功能描述: 根据deptId查找部门下的所有部门
+     *
+     * @param deptId deptId
+     * @return com.boman.common.core.web.domain.AjaxResult
+     */
+    @GetMapping("/list/children/depts/{deptId}")
+    public List<SysDept> listChildrenDepts(@PathVariable(value = "deptId") Long deptId) {
+        return deptService.listChildrenDepts(deptId);
+    }
+
     /**
      * 根据部门编号获取详细信息
      */

+ 8 - 0
boman-modules/boman-system/src/main/java/com/boman/system/controller/SysMenuController.java

@@ -48,6 +48,14 @@ public class SysMenuController extends BaseController
         return AjaxResult.success(menus);
     }
 
+    /**
+     * 获取某人的所有菜单
+     */
+    @GetMapping("/listMenusByUserId/{userId}")
+    public List<SysMenu> list(@PathVariable Long userId) {
+        return menuService.selectMenuList(new SysMenu(), userId);
+    }
+
     /**
      * 根据菜单编号获取详细信息
      */

+ 9 - 1
boman-modules/boman-system/src/main/java/com/boman/system/controller/SysRoleDataController.java

@@ -21,7 +21,7 @@ import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
-import com.boman.system.domain.SysRoleData;
+import com.boman.domain.SysRoleData;
 
 
 /**
@@ -72,6 +72,14 @@ public class SysRoleDataController extends BaseController
         return AjaxResult.success(sysRoleDataService.selectSysRoleDataById(id));
     }
 
+    /**
+     * 获取角色权限数据详细信息
+     */
+    @PostMapping(value = "/listByRoleIdList")
+    public List<SysRoleData> listByRoleIdList(@RequestBody List<Long> idList) {
+        return sysRoleDataService.listByRoleIdList(idList);
+    }
+
     /**
      * 新增角色权限数据
      */

+ 10 - 0
boman-modules/boman-system/src/main/java/com/boman/system/controller/SysUserController.java

@@ -246,4 +246,14 @@ public class SysUserController extends BaseController
         user.setUpdateBy(SecurityUtils.getUsername());
         return toAjax(userService.updateUserStatus(user));
     }
+
+    /**
+     * 部门下所有人
+     */
+//    @PreAuthorize(hasPermi = "system:user:edit")
+    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
+    @PostMapping("/listByDeptId")
+    public List<SysUser> listByDeptId(@RequestBody List<Long> deptIdList) {
+       return userService.listByDeptId(deptIdList);
+    }
 }

+ 10 - 1
boman-modules/boman-system/src/main/java/com/boman/system/mapper/SysRoleDataMapper.java

@@ -1,7 +1,8 @@
 package com.boman.system.mapper;
 
 import java.util.List;
-import com.boman.system.domain.SysRoleData;
+import com.boman.domain.SysRoleData;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * 角色权限数据Mapper接口
@@ -19,6 +20,14 @@ public interface SysRoleDataMapper
      */
     public SysRoleData selectSysRoleDataById(Long id);
 
+    /**
+     * 查询角色权限数据
+     *
+     * @param idList 角色权限数据ID
+     * @return 角色权限数据
+     */
+    List<SysRoleData> listByRoleIdList(@Param("roleIdList") List<Long> idList);
+
     /**
      * 查询角色权限数据列表
      * 

+ 4 - 0
boman-modules/boman-system/src/main/java/com/boman/system/mapper/SysUserMapper.java

@@ -110,4 +110,8 @@ public interface SysUserMapper
      * @return 结果
      */
     public SysUser checkEmailUnique(String email);
+    /**
+     * 部门下所有人
+     */
+    List<SysUser> listByDeptId(@Param("deptIdList") List<Long> deptIdList);
 }

+ 9 - 0
boman-modules/boman-system/src/main/java/com/boman/system/service/ISysDeptService.java

@@ -2,6 +2,7 @@ package com.boman.system.service;
 
 import java.util.List;
 
+import com.boman.common.core.web.domain.AjaxResult;
 import com.boman.system.api.domain.SysDept;
 import com.boman.system.domain.vo.TreeSelect;
 
@@ -107,4 +108,12 @@ public interface ISysDeptService
      * @return 结果
      */
     public int deleteDeptById(Long id);
+
+    /**
+     * 功能描述: 根据deptId查找部门下的所有部门
+     *
+     * @param deptId deptId
+     * @return com.boman.common.core.web.domain.AjaxResult
+     */
+    List<SysDept> listChildrenDepts(Long deptId);
 }

+ 9 - 1
boman-modules/boman-system/src/main/java/com/boman/system/service/ISysRoleDataService.java

@@ -1,7 +1,7 @@
 package com.boman.system.service;
 
 import java.util.List;
-import com.boman.system.domain.SysRoleData;
+import com.boman.domain.SysRoleData;
 
 /**
  * 角色权限数据Service接口
@@ -19,6 +19,14 @@ public interface ISysRoleDataService
      */
     public SysRoleData selectSysRoleDataById(Long id);
 
+    /**
+     * 查询角色权限数据
+     *
+     * @param idList 角色权限数据ID
+     * @return 角色权限数据
+     */
+    List<SysRoleData> listByRoleIdList(List<Long> idList);
+
     /**
      * 查询角色权限数据列表
      * 

+ 5 - 0
boman-modules/boman-system/src/main/java/com/boman/system/service/ISysUserService.java

@@ -165,4 +165,9 @@ public interface ISysUserService
      * @return 结果
      */
     public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName);
+
+    /**
+     * 部门下所有人
+     */
+    List<SysUser> listByDeptId(List<Long> deptIdList);
 }

+ 33 - 0
boman-modules/boman-system/src/main/java/com/boman/system/service/impl/SysDeptServiceImpl.java

@@ -4,6 +4,11 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.stream.Collectors;
+
+import com.boman.common.core.utils.obj.ObjectUtils;
+import com.boman.common.core.web.domain.AjaxResult;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang3.ArrayUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.boman.common.core.constant.UserConstants;
@@ -303,4 +308,32 @@ public class SysDeptServiceImpl implements ISysDeptService
     {
         return getChildList(list, t).size() > 0 ? true : false;
     }
+
+    /**
+     * 功能描述: 根据deptId查找部门下的所有部门
+     *
+     * @param deptId deptId
+     * @return com.boman.common.core.web.domain.AjaxResult
+     */
+    @Override
+    public List<SysDept> listChildrenDepts(Long deptId) {
+        List<SysDept> allDepts = selectDeptList(new SysDept());
+        SysDept sysDept = ObjectUtils.filterOne(allDepts, dept -> deptId.equals(dept.getId()));
+        List<SysDept> returnData = Lists.newArrayListWithCapacity(16);
+        return recursionChildrenDepts(allDepts, sysDept, returnData);
+    }
+
+    private List<SysDept> recursionChildrenDepts(List<SysDept> allDepts, SysDept sysDept, List<SysDept> returnData) {
+        // 得到子节点列表
+        List<SysDept> childList = getChildList(allDepts, sysDept);
+        returnData.addAll(childList);
+        for (SysDept tChild : childList) {
+            if (hasChild(allDepts, tChild)) {
+                recursionChildrenDepts(allDepts, tChild, returnData);
+            }
+        }
+
+        return returnData;
+    }
+
 }

+ 12 - 1
boman-modules/boman-system/src/main/java/com/boman/system/service/impl/SysRoleDataServiceImpl.java

@@ -7,7 +7,7 @@ import com.boman.common.core.utils.SecurityUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.boman.system.mapper.SysRoleDataMapper;
-import com.boman.system.domain.SysRoleData;
+import com.boman.domain.SysRoleData;
 import com.boman.system.service.ISysRoleDataService;
 
 /**
@@ -34,6 +34,17 @@ public class SysRoleDataServiceImpl implements ISysRoleDataService
         return sysRoleDataMapper.selectSysRoleDataById(id);
     }
 
+    /**
+     * 查询角色权限数据
+     *
+     * @param idList 角色权限数据ID
+     * @return 角色权限数据
+     */
+    @Override
+    public List<SysRoleData> listByRoleIdList(List<Long> idList) {
+        return sysRoleDataMapper.listByRoleIdList(idList);
+    }
+
     /**
      * 查询角色权限数据列表
      * 

+ 7 - 0
boman-modules/boman-system/src/main/java/com/boman/system/service/impl/SysUserServiceImpl.java

@@ -461,4 +461,11 @@ public class SysUserServiceImpl implements ISysUserService
         return successMsg.toString();
     }
 
+    /**
+     * 部门下所有人
+     */
+    @Override
+    public List<SysUser> listByDeptId(List<Long> deptIdList) {
+        return userMapper.listByDeptId(deptIdList);
+    }
 }

+ 13 - 4
boman-modules/boman-system/src/main/resources/mapper/system/SysRoleDataMapper.xml

@@ -4,7 +4,7 @@
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.boman.system.mapper.SysRoleDataMapper">
 
-    <resultMap type="SysRoleData" id="SysRoleDataResult">
+    <resultMap type="com.boman.domain.SysRoleData" id="SysRoleDataResult">
         <result property="id" column="id"/>
         <result property="roleId" column="role_id"/>
         <result property="roleName" column="role_name"/>
@@ -24,7 +24,7 @@
         select id, role_id, role_sort, table_name, data_scope, is_use, is_del, create_by, create_time, update_by, update_time, remark from sys_role_data
     </sql>
 
-    <select id="selectSysRoleDataList" parameterType="SysRoleData" resultMap="SysRoleDataResult">
+    <select id="selectSysRoleDataList" parameterType="com.boman.domain.SysRoleData" resultMap="SysRoleDataResult">
         select d.id, d.role_id, d.role_sort, d.table_name, d.data_scope, d.is_use, d.is_del, d.remark, r.role_name
         from sys_role_data d
         left join sys_role r on d.role_id = r.id
@@ -54,7 +54,16 @@
         where is_del = 'N' and id = #{id} order by role_sort asc
     </select>
 
-    <insert id="insertSysRoleData" parameterType="SysRoleData">
+    <select id="listByRoleIdList" resultMap="SysRoleDataResult">
+        <include refid="selectSysRoleDataVo"/>
+        where is_del = 'N' and role_id in
+        <foreach collection="roleIdList" open="(" close=")" separator="," item="id">
+            #{id}
+        </foreach>
+        order by role_sort asc
+    </select>
+
+    <insert id="insertSysRoleData" parameterType="com.boman.domain.SysRoleData">
         insert into sys_role_data
         <trim prefix="(" suffix=")" suffixOverrides=",">
             <if test="id != null">id,</if>
@@ -86,7 +95,7 @@
         </trim>
     </insert>
 
-    <update id="updateSysRoleData" parameterType="SysRoleData">
+    <update id="updateSysRoleData" parameterType="com.boman.domain.SysRoleData">
         update sys_role_data
         <trim prefix="SET" suffixOverrides=",">
             <if test="roleId != null">role_id = #{roleId},</if>

+ 7 - 0
boman-modules/boman-system/src/main/resources/mapper/system/SysUserMapper.xml

@@ -176,5 +176,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			#{id}
         </foreach> 
  	</delete>
+
+ 	<select id="listByDeptId" resultMap="SysUserResult">
+ 		select id from sys_user where dept_id in
+ 		<foreach collection="deptIdList" item="deptId" open="(" separator="," close=")">
+ 			#{deptId}
+        </foreach>
+ 	</select>
 	
 </mapper> 

+ 12 - 0
boman-web-core/src/main/java/com/boman/web/core/utils/ColumnUtils.java

@@ -7,6 +7,7 @@ import com.boman.common.core.utils.StringUtils;
 import com.boman.common.core.utils.obj.ObjectUtils;
 import com.boman.domain.GenTableColumn;
 import com.boman.domain.exception.UnknownColumnException;
+import com.google.common.base.Joiner;
 import com.google.common.collect.Lists;
 import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.ArrayUtils;
@@ -295,4 +296,15 @@ public class ColumnUtils {
             return columnType;
         }
     }
+
+    /**
+     * 连接字符串数组集合
+     *
+     * @param iterable 集合
+     * @return 连接结果
+     */
+    public static String joinList(Iterable iterable) {
+        Joiner joiner = Joiner.on(", ").skipNulls();
+        return joiner.join(iterable);
+    }
 }

+ 147 - 0
ruoyi-ui/src/components/FormItemComponent/index.vue

@@ -0,0 +1,147 @@
+<template>
+  <div class="FormComponent">
+      <div
+      class="FormItemComponent"
+      :style="setWidth"
+    >
+      <div
+        v-for="(item,index) in dataColRol"
+        :key="index"
+        class="FormItemComponent-item"
+        :style="setDiv(item)"
+      >
+        <component
+          :is="item.component"
+          :ref="'component_'+index"
+          :index="index"
+          :items="item.item"
+          :readonly="readonly"
+          @inputChange="inputChange"
+        />
+      </div>
+    </div>
+    <p v-if="buttonType">
+      <Button type="primary" @click="search">搜索</Button>
+      <Button type="fcdefault" @click="reset">重置</Button>
+    </p>
+  </div>
+</template>
+<script>
+import Vue from "vue";
+// import layoutAlgorithm from "../__utils__/layoutAlgorithm";
+export default {
+  name: "FormItemComponent",
+  props: {
+    formItemLists: {
+      type: Array,
+      default() {
+        return [];
+      }
+    },
+    buttonType: {
+      type: Boolean,
+      default() {
+        return true;
+      }
+    },
+    defaultColumn: {
+      type: Number,
+      default: 4
+    },
+    readonly: {
+      type: Boolean,
+      default: false
+    }
+  },
+  computed: {
+    // 通过layoutAlgorithm算法得到对应的位置坐标
+    dataColRol() {
+      // const list = layoutAlgorithm(this.defaultColumn, this.currentFormList);
+      // return Object.keys(list).reduce((temp, current) => {
+      //   // 计算显示行数
+      //   list[current].component = Vue.extend(list[current].component);
+      //   temp.push(list[current]);
+      //   return temp;
+      // }, []);
+    },
+    // 计算属性的 div 的坐标起始点
+    setDiv() {
+      return item =>
+        ` grid-column:${item.x}/${item.col + item.x};grid-row:${
+          item.y
+        }/${item.y + item.row};`;
+    },
+    // 计算属性的 div的排列格式
+    setWidth() {
+      // `this` 指向 vm 实例
+      const columns = Number(this.defaultColumn) || 4;
+      return `grid-template-columns: repeat(${columns},${100 / columns}%`;
+    }
+  },
+  watch: {
+    formItemLists() {
+      this.currentFormList = this.formItemLists.concat([]);
+    }
+  },
+  data() {
+    return {
+      // defaultColumn:4,  //默认一行4列
+      formData: {}, //保存form中输入数据
+      currentFormList: []
+    };
+  },
+  created() {
+    this.currentFormList = this.formItemLists.concat([]);
+  },
+  methods: {
+    inputChange(value, items, type) {
+      //有数据改变时
+      // if(Object.prototype.toString.call(value) === '[object Array]' && (!value[0] || !value[1])){
+      //   delete this.formData[items.filed]
+      // }else{
+      //   this.formData[items.filed] = value
+      // }
+      if (type && type === "select") {
+        this.formData[items.slotfiled] = value;
+      } else {
+        this.formData[items.filed] = value;
+      }
+      this.$emit("formChange", this.formData);
+    },
+    search() {
+      this.$emit("search", this.formData);
+    },
+    reset() {
+      this.formData = {};
+      this.currentFormList = this.currentFormList.concat([]);
+      this.$emit("search", this.formData);
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+.FormComponent {
+  padding: 2px 10px 10px 10px;
+  border: 1px solid rgba(228, 228, 228, 1);
+}
+
+.FormComponent > p {
+  padding-left: 108px;
+  margin-top: 10px;
+  display: flex;
+  width: 300px;
+
+  > button {
+    margin-right: 10px;
+  }
+}
+.FormItemComponent > div {
+  /*border:1px solid #fff;*/
+  box-sizing: border-box;
+}
+.FormItemComponent {
+  display: grid;
+  grid-template-columns: repeat(4, 25%);
+  grid-auto-rows: minmax(auto);
+}
+</style>

+ 664 - 0
ruoyi-ui/src/components/ItemComponent/index.vue

@@ -0,0 +1,664 @@
+<template>
+  <div class="ItemComponentRoot" v-if="!_items.hidden">
+    <span class="itemLabel">
+      <span v-if="_items.required" class="label-tip">*</span>
+      {{ _items.title }}:
+    </span>
+    <div class="itemComponent">
+      <Input
+        v-if="_items.type === 'input'"
+        v-model="_items.value"
+        :type="_items.props.type"
+        :clearable="_items.props.clearable"
+        :disabled="_items.props.disabled"
+        :readonly="_items.props.readonly"
+        :rows="_items.props.rows"
+        :autosize="_items.props.autosize"
+        :number="_items.props.number"
+        :autofocus="_items.props.autofocus"
+        :placeholder="_items.props.placeholder"
+        :size="_items.props.size"
+        :maxlength="_items.props.maxlength"
+        :icon="_items.props.icon"
+        :regx="_items.props.regx"
+        on-click="inputClick"
+        on-blur="inputBlur"
+        @on-change="inputChange"
+        @on-enert="inputEnter"
+        @on-focus="inputFocus"
+        @on-keyup="inputKeyUp"
+        @on-keydown="inputKeyDown"
+        @on-keypress="inputKeyPress"
+        @on-regx-check="inputRegxCheck"
+      />
+
+      <Checkbox
+        v-if="_items.type === 'checkbox'"
+        v-model="_items.value"
+        :disabled="_items.props.disabled"
+        :size="_items.props.size"
+        :circle="_items.props.circle"
+        @on-change="checkBoxChange"
+      />
+
+      <Select
+        v-if="_items.type === 'select'"
+        v-model="_items.value"
+        :clearable="_items.props.clearable"
+        :multiple="_items.props.multiple"
+        :multiple-type="_items.props.multipleType"
+        :disabled="_items.props.disabled"
+        :placeholder="_items.props.placeholder"
+        :not-found-text="_items.props['not-found-text']"
+        :label-in-value="_items.props['label-in-value']"
+        :placement="_items.props.placement"
+        :transfer="_items.props.transfer"
+        @on-change="selectChange"
+        @on-clear="selectClear"
+        @on-open-change="selectOpenChange"
+      >
+        <Option
+          v-for="item in _items.options"
+          :key="item.value"
+          :value="item.value"
+          :disabled="item.disabled"
+          :label="item.label"
+        >{{ item.label }}</Option>
+      </Select>
+
+      <i-switch v-if="_items.type === 'Switch'" v-model="_items.value" @on-change="SwitchChange" />
+
+      <DatePicker
+        v-if="_items.type === 'DatePicker'"
+        v-model="_items.value"
+        :type="_items.props.type"
+        :transfer="_items.props.transfer"
+        :format="_items.props.format"
+        :placement="_items.props.placement"
+        :placeholder="_items.props.placeholder"
+        :options="_items.props.options"
+        :open="_items.props.open"
+        :confirm="_items.props.confirm"
+        :size="_items.props.size"
+        :disabled="_items.props.disabled"
+        :clearable="_items.props.clearable"
+        :readonly="_items.props.readonly"
+        :editable="_items.props.editable"
+        @on-change="($event,event,instance) => datePickerChange(_items.value=$event,event,instance,_items.props.type)"
+        @on-clear="datePickerClear"
+      />
+
+      <DropMultiSelectFilter
+        v-if="_items.type === 'DropDownSelectFilter' && !_items.props.single"
+        :data="_items.props.data"
+        :single="_items.props.single"
+        :total-row-count="_items.props.totalRowCount"
+        :page-size="_items.props.pageSize"
+        :auto-data="_items.props.AutoData"
+        :disabled="_items.props.disabled"
+        :hidecolumns="_items.props.hidecolumns"
+        :data-empty-message="_items.props.dataEmptyMessage"
+        :default-selected="_items.props.defaultSelected"
+        :transfer="_items.props.transfer"
+        :columnsKey="_items.props.columnsKey"
+        :showColnameKey="_items.props.showColnameKey"
+        :placeholder="_items.props.placeholder"
+        @on-fkrp-selected="fkrpSelected"
+        @on-page-change="pageChange"
+        @on-input-value-change="inputValueChange"
+        @on-focus="fkrpSelectedInputFocus"
+        @on-blur="fkrpSelectedInputBlur"
+        @on-keyup="fkrpSelectedInputKeyup"
+        @on-keydown="fkrpSelectedInputKeydown"
+        @on-popper-show="fkrpSelectedPopperShow"
+        @on-popper-hide="fkrpSelectedPopperHide"
+        @on-clear="fkrpSelectedClear"
+      />
+
+      <DropDownSelectFilter
+        v-if="_items.type === 'DropDownSelectFilter' && _items.props.single"
+        :data="_items.props.data"
+        :single="_items.props.single"
+        :total-row-count="_items.props.totalRowCount"
+        :page-size="_items.props.pageSize"
+        :auto-data="_items.props.AutoData"
+        :disabled="_items.props.disabled"
+        :hidecolumns="_items.props.hidecolumns"
+        :data-empty-message="_items.props.dataEmptyMessage"
+        :default-selected="_items.props.defaultSelected"
+        :transfer="_items.props.transfer"
+        :columnsKey="_items.props.columnsKey"
+        :showColnameKey="_items.props.showColnameKey"
+        :placeholder="_items.props.placeholder"
+        @on-fkrp-selected="fkrpSelected"
+        @on-page-change="pageChange"
+        @on-input-value-change="inputValueChange"
+        @on-focus="fkrpSelectedInputFocus"
+        @on-blur="fkrpSelectedInputBlur"
+        @on-keyup="fkrpSelectedInputKeyup"
+        @on-keydown="fkrpSelectedInputKeydown"
+        @on-popper-show="fkrpSelectedPopperShow"
+        @on-popper-hide="fkrpSelectedPopperHide"
+        @on-clear="fkrpSelectedClear"
+      />
+      <div class="complex-input" v-if="_items.type === 'selectInput'">
+        <Input
+          v-model="_items.value"
+          :readonly="_items.props.readonly"
+          @on-change="inputChange"
+          @on-enert="inputEnter"
+          @on-focus="inputFocus"
+          @on-keyup="inputKeyUp"
+          @on-keydown="inputKeyDown"
+          @on-keypress="inputKeyPress"
+          @on-regx-check="inputRegxCheck"
+        >
+          <Select
+            v-if="_items.slot"
+            v-model="_items.slotValue"
+            slot="prepend"
+            style="width: 60px"
+            :transfer="true"
+            @on-change="selectChange"
+          >
+            <Option :value="0">指定</Option>
+            <Option :value="1">不限次数</Option>
+          </Select>
+        </Input>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+// import dataProp from "../config/props.config";
+export default {
+  name: "ItemComponent",
+  props: {
+    items: {
+      type: Object,
+      default() {
+        return {};
+      }
+    }
+  },
+  computed: {
+    _items() {
+      // 将设置的props和默认props进行assign
+      const item = JSON.parse(JSON.stringify(this.items));
+      // const item = this.items;
+      item.props = Object.assign(
+        {},
+        // dataProp[item.type].props,
+        this.items.props
+      );
+      item.event = Object.assign({}, this.items.event);
+      if (item.type === "DatePicker") {
+        if (
+          item.props.type === "datetimerange" ||
+          item.props.type === "daterange"
+        ) {
+          if (!item.value) {
+            item.value = [];
+          }
+        } else {
+          item.value = new Date();
+        }
+      }
+      return item;
+    }
+  },
+  methods: {
+    valueChange(type) {
+      // 值发生改变时触发  只要是item中的value改变就触发该方法,是为了让父组件数据同步
+      if(type&&type==='select'){
+        this.$emit("inputChange", this._items.slotValue, this._items,type);
+      }else{
+         this.$emit("inputChange", this._items.value, this._items);
+      }
+
+      // this.$emit("inputChange", this._items.value, this._items);
+    },
+    // Switch
+    SwitchChange() {
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "change") &&
+        typeof this._items.event.change === "function"
+      ) {
+        this._items.event.change(event);
+      }
+    },
+
+    // input event
+    inputChange(event, $this) {
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "change") &&
+        typeof this._items.event.change === "function"
+      ) {
+        this._items.event.change(event, $this);
+      }
+    },
+    inputEnter(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "enter") &&
+        typeof this._items.event.enter === "function"
+      ) {
+        this._items.event.enter(event, $this);
+      }
+    },
+    inputClick(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "click") &&
+        typeof this._items.event.click === "function"
+      ) {
+        this._items.event.click(event, $this);
+      }
+    },
+    inputFocus(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "focus") &&
+        typeof this._items.event.focus === "function"
+      ) {
+        this._items.event.focus(event, $this);
+      }
+    },
+    inputBlur(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "blur") &&
+        typeof this._items.event.blur === "function"
+      ) {
+        this._items.event.blur(event, $this);
+      }
+    },
+    inputKeyUp(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "keyup") &&
+        typeof this._items.event.keyup === "function"
+      ) {
+        this._items.event.keyup(event, $this);
+      }
+    },
+    inputKeyDown(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "keydown") &&
+        typeof this._items.event.keydown === "function"
+      ) {
+        this._items.event.keydown(event, $this);
+      }
+    },
+    inputKeyPress(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "keypress") &&
+        typeof this._items.event.keypress === "function"
+      ) {
+        this._items.event.keypress(event, $this);
+      }
+    },
+    inputRegxCheck(value, $this, errorValue) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "regxCheck") &&
+        typeof this._items.event.regxCheck === "function"
+      ) {
+        this._items.event.regxCheck(value, $this, errorValue);
+      }
+    },
+
+    // checkbox event
+    checkBoxChange(value, $this) {
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "change") &&
+        typeof this._items.event.change === "function"
+      ) {
+        this._items.event.change(value, $this);
+      }
+    },
+
+    // select input
+    selectChange(value, $this) {
+      if (this._items.type === "selectInput") {
+        this._items.slotValue = value;
+        this.valueChange("select");
+      } else {
+        this._items.value = value;
+        this.valueChange();
+      }
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "change") &&
+        typeof this._items.event.change === "function"
+      ) {
+        this._items.event.change(value, $this);
+      }
+    },
+    selectClear($this) {
+      this._items.value = null;
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "clear") &&
+        typeof this._items.event.clear === "function"
+      ) {
+        this._items.event.clear($this);
+      }
+    },
+    selectOpenChange(value, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "openChange") &&
+        typeof this._items.event.openChange === "function"
+      ) {
+        this._items.event.openChange(value, $this);
+      }
+    },
+    // datepick event
+    datePickerChange(value, type, $this) {
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "change") &&
+        typeof this._items.event.change === "function"
+      ) {
+        this._items.event.change(value, $this);
+      }
+    },
+    datePickerClear($this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "clear") &&
+        typeof this._items.event.clear === "function"
+      ) {
+        this._items.event.clear($this);
+      }
+    },
+
+    // TimePicker event
+    timePickerChange(value, timeType, $this) {
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "change") &&
+        typeof this._items.event.change === "function"
+      ) {
+        this._items.event.change(value, $this);
+      }
+    },
+    timePickerClear($this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "clear") &&
+        typeof this._items.event.clear === "function"
+      ) {
+        this._items.event.clear($this);
+      }
+    },
+
+    // fkrpSelected event
+    fkrpSelected(value, $this) {
+      this._items.value = value;
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "fkrpSelected"
+        ) &&
+        typeof this._items.event.fkrpSelected === "function"
+      ) {
+        this._items.event.fkrpSelected(value, $this);
+      }
+    },
+    inputValueChange(value, $this) {
+      this._items.value = value;
+      // this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "inputValueChange"
+        ) &&
+        typeof this._items.event.inputValueChange === "function"
+      ) {
+        this._items.event.inputValueChange(value, $this);
+      }
+    },
+    fkrpSelectedClear($this) {
+      this._items.value = undefined;
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "clear") &&
+        typeof this._items.event.clear === "function"
+      ) {
+        this._items.event.clear($this);
+      }
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "inputValueChange"
+        ) &&
+        typeof this._items.event.inputValueChange === "function"
+      ) {
+        this._items.event.inputValueChange("", $this);
+      }
+    },
+    pageChange(value, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "pageChange") &&
+        typeof this._items.event.pageChange === "function"
+      ) {
+        this._items.event.pageChange(value, $this);
+      }
+    },
+    fkrpSelectedInputFocus(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "focus") &&
+        typeof this._items.event.focus === "function"
+      ) {
+        this._items.event.focus(event, $this);
+      }
+    },
+    fkrpSelectedInputBlur(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "blur") &&
+        typeof this._items.event.blur === "function"
+      ) {
+        this._items.event.blur(event, $this);
+      }
+    },
+    fkrpSelectedInputKeyup(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "keyup") &&
+        typeof this._items.event.keyup === "function"
+      ) {
+        this._items.event.keyup(event, $this);
+      }
+    },
+    fkrpSelectedInputKeydown(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "keydown") &&
+        typeof this._items.event.keydown === "function"
+      ) {
+        this._items.event.keydown(event, $this);
+      }
+    },
+    fkrpSelectedPopperShow($this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "on-show") &&
+        typeof this._items.event["on-show"] === "function"
+      ) {
+        this._items.event["on-show"]($this);
+      }
+    },
+    fkrpSelectedPopperHide($this) {
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "on-popper-hide"
+        ) &&
+        typeof this._items.event["on-popper-hide"] === "function"
+      ) {
+        this._items.event["on-popper-hide"]($this);
+      }
+    },
+
+    // AttachFilter event
+    attachFilterChange(value, $this) {
+      this._items.value = value;
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "popper-value"
+        ) &&
+        typeof this._items.event["popper-value"] === "function"
+      ) {
+        this._items.event["popper-value"]($this, value, "change", this.index);
+      }
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "inputValueChange"
+        ) &&
+        typeof this._items.event.inputValueChange === "function"
+      ) {
+        this._items.event.inputValueChange(value, $this);
+      }
+    },
+    attachFilterSelected(row, $this) {
+      this._items.value = row.label;
+      this._items.props.selected = row.value;
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "popper-value"
+        ) &&
+        typeof this._items.event["popper-value"] === "function"
+      ) {
+        this._items.event["popper-value"](
+          $this,
+          row.label,
+          row.value,
+          this.index
+        );
+      }
+    },
+    attachFilterInputFocus(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "focus") &&
+        typeof this._items.event.focus === "function"
+      ) {
+        this._items.event.focus(event, $this);
+      }
+    },
+    attachFilterInputBlur(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "blur") &&
+        typeof this._items.event.blur === "function"
+      ) {
+        this._items.event.blur(event, $this);
+      }
+    },
+    attachFilterInputKeyup(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "keyup") &&
+        typeof this._items.event.keyup === "function"
+      ) {
+        this._items.event.keyup(event, $this);
+      }
+    },
+    attachFilterInputKeydown(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "keydown") &&
+        typeof this._items.event.keydown === "function"
+      ) {
+        this._items.event.keydown(event, $this);
+      }
+    },
+    attachFilterPopclick(event, row, targName, $this) {
+      if (targName !== "I" && event !== 1) {
+        // 打开弹窗
+
+        $this.showModal = true;
+        if (event !== 0) {
+          console.log(row.label);
+          this.filterDate = JSON.parse(row.label);
+        }
+      } else if (
+        targName === "I" &&
+        Object.prototype.hasOwnProperty.call(this._items.event, "on-delete") &&
+        typeof this._items.event["on-delete"] === "function"
+      ) {
+        this._items.event["on-delete"]($this, this._items, row.key, this.index);
+      }
+    },
+    attachFilterClear(event, $this) {
+      this._items.value = "";
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "popper-value"
+        ) &&
+        typeof this._items.event["popper-value"] === "function"
+      ) {
+        this._items.event["popper-value"]($this, "", [], this.index);
+      }
+    },
+    attachFilterPopperShow($this) {
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "popper-show"
+        ) &&
+        typeof this._items.event["popper-show"] === "function"
+      ) {
+        this._items.event["popper-show"]($this, this._items, this.index);
+      }
+    },
+    attachFilterOk($this) {
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "popper-value"
+        ) &&
+        typeof this._items.event["popper-value"] === "function"
+      ) {
+        if ($this._data.IN > 0) {
+          let value = `已经选中${$this._data.IN}条数据`;
+          this._items.value = value;
+          this.valueChange();
+          this._items.event["popper-value"](
+            $this,
+            value,
+            $this._data.IN,
+            this.index
+          );
+        }
+      }
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+.ItemComponentRoot {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  padding-top: 8px;
+
+  .itemLabel {
+    width: 100px;
+    margin-right: 8px;
+    text-align: right;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    display: inline-block;
+  }
+
+  .itemComponent {
+    flex: 1;
+    overflow: hidden;
+  }
+  .label-tip {
+    color: red;
+    font-size: 16px;
+    vertical-align: middle;
+    position: relative;
+    top: -1px;
+    right: 3px;
+  }
+}
+</style>

+ 128 - 0
ruoyi-ui/src/components/StandardTable/index.vue

@@ -0,0 +1,128 @@
+<template>
+  <div class="StandardTable">
+    <Page
+      v-if="showPage"
+     class="page"
+     :total="total"
+     show-total
+     show-sizer
+     show-elevator
+     transfer
+     :page-size="pageSize"
+     :current="currentPage"
+     :page-size-opts="pageSizeOpts"
+     v-on="standardTableEvent"
+    />
+
+    <div 
+      class="table"
+      v-if="showTable"
+    >
+      <Table
+        ref="table"
+        class="table"
+        :total="total"
+        :columns="columns"
+        :height = true
+        :data="data"
+        :border="border"
+        highlight-row
+        v-on="standardTableEvent"
+      >
+      </Table>
+
+
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  name:'StandardTable',
+  props:{
+    //事件回调
+    standardTableEvent:{
+      type:Object,
+      default() {
+        return {}
+      }
+    },
+    //分页属性
+    showPage:{  //控制分页是否展示
+      type:Boolean,
+      default:true
+    },
+    total:{
+      type:Number,
+      default:0
+    },
+    currentPage:{
+      type:Number,
+      default:1
+    },
+    pageSize:{
+      type:Number,
+      default:10
+    },
+    pageSizeOpts:{
+      type:Array,
+      default () {
+        return [10,20,30,40]
+      }
+    },
+
+    //表格属性
+    showTable:{  //控制表格是否展示
+      type:Boolean,
+      default:true
+    },
+    columns:{
+      type:Array,
+      default() {
+        return [];
+      }
+    },
+    data:{
+      type:Array,
+      default() {
+        return [];
+      }
+    },
+    border:{
+      type: Boolean,
+      default: false
+    }
+  },
+  watch:{
+    data () {
+      this.$refs.table.$el.getElementsByClassName('burgeon-table-body')[0].scrollTop = 0
+    }
+  },
+  methods:{
+  }
+}
+</script>
+<style lang="scss" scoped>
+.StandardTable{
+  display: flex;
+  overflow: hidden;
+  flex-direction: column;
+  .page{
+    margin-bottom: 8px;
+  }
+  
+  .table{
+    flex: 1;
+    overflow: hidden;
+    position: relative;
+    .noData{
+      position:absolute;
+      height: 200px;
+      top: 50%;
+      left: 50%;
+      margin-top: -90px;
+      margin-left: -80px;
+    }
+  }
+}
+</style>
+

+ 341 - 0
ruoyi-ui/src/components/listModalComponent/index.vue

@@ -0,0 +1,341 @@
+// 列表模型块组件
+<template>
+  <div class="listModalComponent" :class="(active && readonly)?'active':null" @click="ckeckModal">
+    <div class="preview" @mouseout="mouseout" :style="`backgroundImage:url(${items.url?items.url:''})`">
+      <!-- <img :src="items.url?items.url:''" alt=""> -->
+
+      <div class="more" v-show="!readonly" >
+        <Poptip trigger="click" placement="bottom-end" :width="100" ref="poptip" @mouseout.native.stop="">
+            <span class="dot"></span>
+            <span class="dot"></span>
+            <span class="dot"></span>
+
+            <ul slot="content" class="options">
+              <li @click="releaseProcess" v-if="items.status === 0 || items.status === 2">发布流程</li>
+              <li @click="editingProcess" v-if="items.status === 0">编辑流程</li>
+              <li @click="copyProcess" v-if="items.status === 0 || items.status === 2 ">复制流程</li>
+              <li @click="deleteProcess" v-if="items.status === 0 || items.status === 2 ">删除流程</li>
+              <li @click="stopProcess" v-if="items.status === 1">停用流程</li>
+              <li @click="previewProcess">预览</li>
+            </ul>
+        </Poptip>
+      </div>
+    </div>
+    <div class="info">
+      <p class="infoTitle">{{items.name}}</p>
+      <p>
+        <span class="creatTime">创建时间:{{items.createTime}}</span>
+      </p>
+
+      <span class="status" :class="statusClass">{{statusName}}</span>
+    </div>
+
+
+  </div>
+</template>
+<script>
+// import {DispatchEvent} from '../__utils__/dispatchEvent'
+import {  mapMutations } from 'vuex';
+export default {
+  name:'listModalComponent',
+  props:{
+    items:{
+      type:Object,
+      default () {
+        return {
+          name:'模型名称',
+          url:'',  //缩略图base64数据
+          createTime:'2019-03-18',
+          status:1,  //已发布是1  未发布是2
+        }
+      }
+    },
+    readonly:{
+      type:Boolean,
+      default: false
+    }
+  },
+  data () {
+    return {
+      active:false
+    }
+  },
+  computed:{
+    statusName () {
+      let str = ''
+      switch (this.items.status) {
+        case -1:
+          str = '已删除';
+          break;
+        case 0:
+          str = '未发布';
+          break;
+        case 1:
+          str = '已发布';
+          break;
+        case 2:
+          str = '已停用';
+          break;
+        case 3:
+          str = '草稿';
+          break;
+
+      }
+      return str
+    },
+    statusClass () {
+      return [{
+        'published':this.items.status === 1,
+        'notRelease':this.items.status === 0,
+        'stop':this.items.status === 2
+      }]
+    }
+  },
+  watch:{
+    readonly () {
+      this.active = false
+    }
+  },
+  methods:{
+    ...mapMutations(['currentChange','changeKeepAliveArray']),
+    mouseout () {
+      this.$refs.poptip.handleClose()
+    },
+    releaseProcess () {  //发布流程
+      this.$refs.poptip.handleClose()
+      this.$network.post('/p/cs/module/publish', {id:this.items.id}).then((res) => {
+        if(typeof this.items.event.queryLists === 'function'){
+          this.items.event.queryLists()
+        }
+      })
+    },
+    editingProcess () { //编辑流程
+      this.$refs.poptip.handleClose()
+      this.changeKeepAliveArray(['TemplateManagementLists'])
+      this.$router.push({ path: `/TemplateManagementNew/${this.items.id}` })
+      this.currentChange({
+        path:'/TemplateManagementLists'
+      });
+    },
+    deleteProcess () {  //删除流程
+      this.$refs.poptip.handleClose()
+      this.$network.post('/p/cs/module/remove', {id:this.items.id}).then((res) => {
+        if(typeof this.items.event.queryLists === 'function'){
+          this.items.event.queryLists()
+        }
+      })
+    },
+    stopProcess () {  //停用流程
+      this.$refs.poptip.handleClose()
+      this.$network.post('/p/cs/module/unpublish', {id:this.items.id}).then((res) => {
+        if(typeof this.items.event.queryLists === 'function'){
+          this.items.event.queryLists()
+        }
+      })
+    },
+    copyProcess () {  //复制流程
+      this.$refs.poptip.handleClose()
+      this.$network.post('/p/cs/module/copy', {id:this.items.id}).then((res) => {
+        if(res.data.resultCode === 0){
+          this.changeKeepAliveArray(['TemplateManagementLists'])
+          this.$router.push({ path: `/TemplateManagementNew/${res.data.data.id}` })
+          this.currentChange({
+            path:'/TemplateManagementLists'
+          });
+        }
+      })
+    },
+    previewProcess () { //预览流程
+      this.$refs.poptip.handleClose()
+      this.changeKeepAliveArray(['TemplateManagementLists'])
+      this.$router.push({ path: `/TemplateManagementNew/${this.items.id}/1` })
+      this.currentChange({
+        path:'/TemplateManagementLists'
+      });
+    },
+
+    ckeckModal () {  //选择流程
+      if(this.readonly){
+        this.active = !this.active
+        // DispatchEvent('modalClick',{
+        //   detail:{
+        //     items:this.items,
+        //     value:this.active
+        //   }
+        // })
+      }
+
+    }
+  }
+}
+</script>
+<style lang="scss" >
+.listModalComponent{
+  height:220px;
+  background:rgba(255,255,255,1);
+  box-shadow:0px 1px 5px 0px rgba(0,0,0,0.1)!important;
+  border-radius:4px;
+  cursor: pointer;
+  display: flex;
+  flex-direction: column;
+  border-radius:4px;
+  position: relative;
+
+  &.active{
+    border: 1px solid #5982E7;
+  }
+
+  .info{
+    height: 62px;
+    padding: 10px 0 8px 12px;
+    position: relative;
+
+    .infoTitle{
+      height: 20px;
+      font-size: 15px;
+      font-family: PingFangSC-Medium;
+      font-weight: 500;
+      color: #515a6e;
+      line-height: 20px;
+      margin-bottom: 6px;
+    }
+
+    >p:last-child{
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      span{
+        font-size:12px;
+        font-family:PingFangSC-Regular;
+        font-weight:400;
+        color:rgba(81,90,110,1);
+        line-height:16px;
+      }
+    }
+
+    span.status{
+      position: absolute;
+      right: 0;
+      bottom: 8px;
+      width:75px;
+      height:24px;
+      background:#B4B4B4;
+      border-radius:12px 0px 0px 12px;
+      color: white;
+      text-align: center;
+      line-height: 24px;
+      font-size:12px;
+      font-family:PingFangSC-Regular,PingFang SC;
+      font-weight:400;
+
+      &.published{
+        background:rgba(9, 161, 85, 1)
+      }
+
+      &.notRelease{
+        background:#B4B4B4
+      }
+
+      &.stop{
+        background: #ED4014;
+      }
+    }
+
+  }
+
+  .preview{
+    flex: 1;
+    border-radius:4px 4px 0px 0px;
+    overflow: hidden;
+    text-align: center;
+    background-size: contain;
+    background-repeat: no-repeat;
+    background-position: center;
+    img{
+      // width: 100%;
+      height: 100%;
+    }
+
+    &:hover{
+      // transform: translateY(-4px);
+      img{
+
+      }
+      .more{
+        display: block;
+      }
+    }
+
+    .more{
+      width: 40px;
+      height: 24px;
+      position: absolute;
+      top: 12px;
+      right: 12px;
+      background: white;
+      box-shadow:0px 1px 5px 0px rgba(0,0,0,0.1);
+      border-radius:4px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      display: none;
+
+    .burgeon-poptip{
+      width: 100%;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      .burgeon-poptip-body{
+        padding: 5px 0;
+      }
+      .burgeon-poptip-rel{
+        display: flex;
+        width: 100%;
+        height: 100%;
+        align-items: center;
+        justify-content: center;
+      }
+
+      .burgeon-poptip-popper{
+        min-width: auto;
+      }
+    }
+
+
+    .dot{
+      width: 4px;
+      height: 4px;
+      background: rgba(51, 51, 51, 1);
+      border-radius: 50%;
+      display: inline-block;
+      margin-right: 4px;
+
+      &:last-child{
+        margin-right: 0;
+      }
+    }
+
+    .options{
+        li{
+          height: 29px;
+          display: flex;
+          align-items: center;
+          padding-left: 16px;
+          font-size:12px;
+          font-family:PingFangSC-Regular;
+          font-weight:400;
+          color:rgba(81,90,110,1);
+
+          &:hover{
+            background: rgba(243, 243, 243, 1);
+          }
+        }
+      }
+    }
+  }
+  &:hover{
+     transform: translateY(-4px);
+  }
+}
+</style>

+ 435 - 0
ruoyi-ui/src/views/activiti/modeler/index.vue

@@ -0,0 +1,435 @@
+<template>
+  <div class="TemplateManagementLists">
+    <div class="listContent">
+      <p class="title">模版管理</p>
+      <p class="buttonLists">
+        <Button type="primary" @click="searchData.page = 1;queryLists()">查询</Button>
+        <Button type="fcdefault" :disabled="listsStatus === 1" @click="addTemplate">新建模板</Button>
+        <Button type="fcdefault" v-if="listsStatus === 0" @click="templateMigration">模版迁移</Button>
+        <Button type="fcdefault" v-if="listsStatus === 1" @click="removeMigration">取消迁移</Button>
+        <Button type="fcdefault" v-if="listsStatus === 1" @click="perform">执行</Button>
+        <Button type="fcdefault" v-if="listsStatus === 1" @click="performAll">执行全部</Button>
+      </p>
+      <Alert show-icon closable v-if="listsStatus === 1">依次单击模板可进行多选模板</Alert>
+      <FormItemComponent
+        class="form"
+        :formItemLists="formLists"
+        :buttonType="false"
+        @formChange="formChange"
+      ></FormItemComponent>
+
+      <StandardTable
+        class="table"
+        :currentPage="searchData.page"
+        :pageSize="searchData.pageSize"
+        :pageSizeOpts="[20,40,60,80]"
+        :total="total"
+        :showTable="false"
+        :standardTableEvent="standardTableEvent"
+      >
+      </StandardTable>
+
+      <div class="list">
+        <FormItemComponent
+          class="listsForm"
+          :formItemLists="listsConfig"
+          :buttonType="false"
+          :readonly="listsStatus === 1"
+        ></FormItemComponent>
+
+        <div  class="noData" v-if="listsConfig.length == 0" >
+          <span>
+            暂无模版
+          </span>
+        </div>
+      </div>
+    </div>
+
+    <!-- 模版迁移弹窗 -->
+    <Modal
+      v-model="migrationModel"
+      title="模版迁移"
+      mask
+      :width="440"
+      :mask-closable="false"
+      >
+      <div class="migrationModelContent">
+        <p>
+          <Input v-model="serverUrl"  placeholder="请输入目标服务器地址" style="width: 320px" />
+        </p>
+      </div>
+
+      <p slot="footer">
+        <Button :loading="performloading" @click="migrationModel = false">取消</Button>
+        <Button :loading="performloading" type="primary" @click="performConfirm">确定</Button>
+      </p>
+    </Modal>
+  </div>
+</template>
+<script>
+import FormItemComponent from '@/components/FormItemComponent';
+import ItemComponent from '@/components/ItemComponent';
+import StandardTable from '@/components/StandardTable';
+import listModalComponent from '@/components/listModalComponent'
+// import router from '../config/router.config'
+import {  mapMutations,mapState } from 'vuex';
+export default {
+  name:'TemplateManagementLists',
+  components:{FormItemComponent,StandardTable},
+  data () {
+    return {
+      // 状态  0为搜索状态,1为模版迁移状态
+      listsStatus:0,
+      //表单配置
+      formLists:[
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'input',
+            title:'模型名称',
+            filed:'name',
+            event:{
+              'keydown': (event) => {
+                if(event.keyCode === 13){
+                  this.searchData.page = 1
+                  this.queryLists()
+                }
+              }
+            }
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'select',
+            title:'模版状态',
+            filed:'status',
+            options: [
+              { value: 1, label: '已发布'},
+              { value: 0, label: '未发布'},
+              { value: 2, label: '已停用'}
+            ],
+            props:{
+              multiple: true,
+              multipleType: true
+            },
+            value:[0,1]
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'DatePicker',
+            title:'创建时间',
+            filed:'createTime',
+            value:[]
+          }
+        }
+      ],
+      //查询条件
+      searchData:{
+        page:1,
+        pageSize:20,
+        createTime:[],
+        status: [0,1]
+      },
+
+      //分页数据
+      total:0,
+      standardTableEvent:{
+        'on-change':(page) => {
+          this.searchData.page = page
+          this.queryLists()
+        },
+        'on-page-size-change':(pageSize) => {
+          this.searchData.page = 1
+          this.searchData.pageSize = pageSize
+          this.queryLists()
+        }
+      },
+      listsConfig:[  //列表数据
+      ],
+
+      // 迁移数据
+      selectModal:[],  //选中的迁移模版
+      migrationModel:false, //控制模版迁移弹窗
+      serverUrl:null,  //目标服务地址
+      migrationType:null,  //0为执行  1为执行全部
+      performloading:false
+
+    }
+  },
+  computed:{
+    ...mapState({
+      currentMenu:(state) =>{
+        return  state.currentMenu
+      }
+    })
+  },
+  watch:{
+    listsStatus () {
+      if(this.listsStatus === 0){
+        this.selectModal = []
+      }
+    }
+  },
+  methods:{
+    ...mapMutations(['currentChange','changeKeepAliveArray']),
+    formChange (data) {  //表单数据修改时,修改searchData数据
+      if(data.status){
+        this.formLists[0].item.value = data.name
+        this.formLists[1].item.value = data.status
+        this.formLists[2].item.value = data.createTime
+        // this.formLists = this.formLists.concat([])
+      }
+      this.searchData = Object.assign({},this.searchData,data)
+      if(Object.prototype.toString.call(this.searchData.status) === '[object Array]' && this.searchData.status.length === 0){
+        delete this.searchData.searchStatus
+        delete this.searchData.status
+      }
+
+      // this.queryLists()
+    },
+    queryLists () {  //查询列表
+      if(this.searchData.status && this.searchData.status.indexOf('bSelect-all') >= 0){
+        this.searchData.searchStatus = []
+      }else{
+        this.searchData.searchStatus = this.searchData.status
+      }
+
+      if(this.searchData.createTime && this.searchData.createTime[0] && this.searchData.createTime[1]){
+        this.searchData.startTime = new Date(this.searchData.createTime[0]).format('yyyy-MM-dd hh:mm')
+        this.searchData.endTime = new Date(this.searchData.createTime[1]).format('yyyy-MM-dd hh:mm')
+      }else{
+        this.searchData.startTime = ''
+        this.searchData.endTime = ''
+      }
+
+      let obj = Object.assign({},this.searchData)
+      delete obj.createTime
+      delete obj.status
+      this.$network.post('/p/cs/module/search', obj).then((res) => {
+        if(res.data.resultCode !== 0){
+          return
+        }
+        let data = res.data.data
+        this.total = data.total
+
+        this.listsConfig = data.records.reduce((arr,item) => {
+          let items = {
+            event:{
+              queryLists:() => {
+                this.queryLists()
+              }
+            }
+          }
+          items = Object.assign(items,item)
+          arr.push({
+            row:1,
+            col:1,
+            component:listModalComponent,
+            item:items
+          })
+          return arr
+        },[])
+      });
+    },
+    addTemplate () {  //新建模版
+      this.changeKeepAliveArray(['TemplateManagementLists'])
+      // router.push({ path: '/TemplateManagementNew/-1' })
+      this.currentChange({
+        path:'/TemplateManagementLists'
+      });
+    },
+    templateMigration () { //模版迁移
+      this.listsStatus = 1
+    },
+    removeMigration () {  //取消迁移
+      this.listsStatus = 0
+    },
+    modalClick (event) {  //模版点击
+      let value = event.detail.value
+      let items = event.detail.items
+      if(value){
+        this.selectModal.push(items.id)
+      }else{
+        this.selectModal.splice(this.selectModal.findIndex(item => item === items.id), 1)
+      }
+    },
+    perform () {  //执行迁移
+      if(this.selectModal.length === 0){
+        this.$Modal.fcWarning({
+          title:'警告',
+          content:'请选择需要迁移的模版!',
+          mask:true
+        })
+        return
+      }
+      this.migrationType = 0
+      this.serverUrl = null
+      this.migrationModel = true
+
+    },
+    performAll () {  //迁移全部
+      this.migrationType = 1
+      this.serverUrl = null
+      this.migrationModel = true
+    },
+    performConfirm () {  //模版迁移确认
+      let obj = {}
+      if(!(this.serverUrl.startsWith('http://') || this.serverUrl.startsWith('https://'))){
+        this.$Modal.fcWarning({
+          title:'警告',
+          content:'目标服务器地址必须以http://或者https://开头',
+          mask:true
+        })
+        return
+      }
+      this.performloading = true
+      if(this.migrationType === 0){  //执行选中模版
+        obj = {
+          moduleIds:this.selectModal.join(',')
+        }
+      }else{  //执行所有模版
+        if(this.searchData.createTime && this.searchData.createTime[0] && this.searchData.createTime[1]){
+          this.searchData.startTime = new Date(this.searchData.createTime[0]).format('yyyy-MM-dd hh:mm')
+          this.searchData.endTime = new Date(this.searchData.createTime[1]).format('yyyy-MM-dd hh:mm')
+        }else{
+          this.searchData.startTime = ''
+          this.searchData.endTime = ''
+        }
+
+        obj = Object.assign({},this.searchData)
+      }
+
+      obj.url = this.serverUrl
+      this.$network.post('/p/cs/module/migrate', obj)
+        .then((res) => {
+          if(res.data.resultCode === 0){
+            this.$Modal.fcSuccess({
+              title:'成功',
+              content:res.data.resultMsg,
+              onOk: () => {
+                this.queryLists()
+                this.listsStatus = 0
+                this.migrationModel = false
+                this.performloading = false
+              }
+            })
+
+          }else{
+            this.performloading = false
+          }
+
+        })
+    }
+  },
+  created () {
+    //判断首页跳转状态,修改查询条件
+    let status = Number(this.$route.query.status)
+    if(status){
+      this.searchData.status = [status]
+      this.formLists[1].item.value = [status]
+      this.formLists = this.formLists.concat([])
+    }
+    this.queryLists()
+  },
+  mounted () {
+    // 监听modal的点击事件
+    window.addEventListener('modalClick',this.modalClick)
+  },
+  beforeDestroy () {
+    window.removeEventListener('modalClick', this.modalClick);
+  },
+  activated () {
+    this.queryLists()
+  }
+}
+</script>
+<style lang="scss" >
+.TemplateManagementLists{
+  display: flex;
+  flex-direction: column;
+  .listContent{
+    background: white;
+    flex: 1;
+    padding: 16px;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+
+    .title{
+      font-size:18px;
+      font-family:PingFangSC-Medium;
+      font-weight:500;
+      color:rgba(81,90,110,1);
+      line-height:24px;
+      margin-bottom: 16px;
+    }
+
+    .buttonLists{
+      margin-bottom: 10px;
+      >button{
+        width: 90px;
+        margin-right: 10px;
+      }
+    }
+    .form{
+      margin-bottom: 16px;
+    }
+
+    .list{
+      flex: 1;
+      margin-right: -16px;
+      overflow: auto;
+      position: relative;
+      .listsForm{
+        border: none;
+        padding: 0;
+        margin-left: 5px;
+        margin-top: 5px;
+
+        .FormItemComponent-item{
+          margin-right: 16px;
+          margin-bottom: 20px;
+        }
+      }
+
+      .noData{
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        width: 280px;
+        height: 292px;
+        margin-top: -146px;
+        margin-left: -140px;
+        // background-image: url('../assets/img/nodata.png');
+        background-size: cover;
+
+        >span{
+          position: absolute;
+          bottom: 40px;
+          left: 20px;
+          display: inline-block;
+          width: 240px;
+          height: 40px;
+          text-align: center;
+        }
+      }
+    }
+
+  }
+}
+
+.migrationModelContent{
+  height: 115px;
+  padding: 30px 44px 17px 44px;
+  box-sizing: border-box;
+}
+</style>

+ 0 - 6
ruoyi-ui/src/views/system/editing/index.vue

@@ -27,16 +27,12 @@
            </el-row>
          </el-form>
        </el-collapse-item>
-
-
      </el-collapse>
     </div>
   </div>
 </template>
-
 <script>
  import { getTableQuery, delMenutab, getQueryList, geteditindeTab, tableSubimt, tableSubimtanit, addbjectSave} from '@/api/system/table.js';
- // import { getTableQuery, getQueryList,geteditindeTab, tableSubimt, tableSubimtanit, addbjectSave } from '@/src/api/system/editing.js';
   export default {
       name: "index",
       data() {
@@ -45,7 +41,6 @@
            title:'单表1',
            // 查询参数
            queryParams: {
-
            },
            labletit:'查询参数1233',
            num:0,
@@ -206,7 +201,6 @@
 
              this.$router.go(-1)
            }
-
            // this.msgSuccess("反提交成功");
            // this.open = false;
            // this.getList();

+ 1 - 3
ruoyi-ui/src/views/system/permissions/index.vue

@@ -77,7 +77,6 @@
            @pagination="getDeptTreeselect"
          />
         </div>
-
       </el-col>
     </el-row>
 
@@ -198,7 +197,6 @@
     },
 
     created() {
-
       this.getDicts("role_data").then(response => {
         this.statusOptions = response.data;
         this.relationType = response.data
@@ -229,7 +227,7 @@
       /** 查询角色列表 */
       getList() {
         this.loading = true;
-        this.roleList = []
+        this.roleList = []   
         listRole(this.addDateRange(this.queryParams, this.dateRange)).then(
           response => {
             if(response.rows.length !==0){

+ 1 - 1
ruoyi-ui/src/views/system/role/fz-index.vue

@@ -41,7 +41,7 @@
       <el-col :span="19" class="roleContr">
         <div class="roleContrBox">
           <el-col :span="7">
-            <div class="searContLeft">
+            <div class="searContLeft">  
               <el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
             </div>
           </el-col>