Browse Source

fix:补充提交

Zn 1 year ago
parent
commit
c9ff8fda95
47 changed files with 3446 additions and 96 deletions
  1. 11 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysBpmNodeScriptController.java
  2. 104 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDragTableStyleController.java
  3. 11 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
  4. 9 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
  5. 166 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDragTableStyle.java
  6. 7 0
      ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysBpmNodeScriptMapper.java
  7. 61 0
      ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDragTableStyleMapper.java
  8. 7 0
      ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
  9. 7 0
      ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java
  10. 7 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/ISysBpmNodeScriptService.java
  11. 62 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDragTableStyleService.java
  12. 7 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java
  13. 7 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
  14. 5 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysBpmNodeScriptServiceImpl.java
  15. 101 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDragTableStyleServiceImpl.java
  16. 5 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
  17. 5 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
  18. 5 0
      ruoyi-system/src/main/resources/mapper/system/SysBpmNodeScriptMapper.xml
  19. 101 0
      ruoyi-system/src/main/resources/mapper/system/SysDragTableStyleMapper.xml
  20. 7 0
      ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
  21. 12 0
      ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml
  22. 51 1
      ruoyi-system/src/main/resources/sql/initialize_sys_tenant_menu.json
  23. 3 3
      ruoyi-ui/.env.development
  24. 44 0
      ruoyi-ui/src/api/bussiness/bpmExcuteProcess.js
  25. 50 0
      ruoyi-ui/src/api/system/btn.js
  26. 44 0
      ruoyi-ui/src/api/system/style.js
  27. BIN
      ruoyi-ui/src/assets/images/background2.jpg
  28. 498 0
      ruoyi-ui/src/components/kFormDesign/OptionsEdit.vue
  29. 11 2
      ruoyi-ui/src/components/updateModule/k-form-design/packages/components/KFormDesign/module/formItemProperties.vue
  30. 1 0
      ruoyi-ui/src/components/updateModule/k-form-design/packages/components/KFormItem/index.vue
  31. 1 0
      ruoyi-ui/src/utils/bpmn/formDataValidate.js
  32. 13 0
      ruoyi-ui/src/utils/other.js
  33. 45 0
      ruoyi-ui/src/utils/sqlString.js
  34. 0 1
      ruoyi-ui/src/views/bpmprocess/scriptManage.vue
  35. 1 1
      ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementNormalTask.vue
  36. 1 1
      ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementUnusualTasks.vue
  37. 11 1
      ruoyi-ui/src/views/system/bpmnPro/components/Toolbar/tools/Save.vue
  38. 54 1
      ruoyi-ui/src/views/system/bpmnPro/components/bo-utils/getNodeMsg.js
  39. 859 0
      ruoyi-ui/src/views/system/excuteBtnMange/index.vue
  40. 15 2
      ruoyi-ui/src/views/system/fromModel/index.vue
  41. 18 0
      ruoyi-ui/src/views/system/selectOptionsMange/index.vue
  42. 72 15
      ruoyi-ui/src/views/tableMange/components/StyleFormPanel.vue
  43. 60 6
      ruoyi-ui/src/views/tableMange/index.vue
  44. 465 0
      ruoyi-ui/src/views/tableMange/styleMange/index.vue
  45. 74 0
      ruoyi-ui/src/views/tablelist/commonTable/BtnMenu.vue
  46. 346 57
      ruoyi-ui/src/views/tablelist/commonTable/listInfo.vue
  47. 2 5
      ruoyi-ui/vue.config.js

+ 11 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysBpmNodeScriptController.java

@@ -2,6 +2,8 @@ package com.ruoyi.web.controller.system;
 
 import java.util.List;
 import javax.servlet.http.HttpServletResponse;
+
+import com.ruoyi.common.annotation.Anonymous;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -110,4 +112,13 @@ public class SysBpmNodeScriptController extends BaseController
     {
         return toAjax(sysBpmNodeScriptService.deleteSysBpmNodeScriptByIds(ids));
     }
+
+    /**
+     *  根据scriptKey获取流程节点脚本详细信息
+     */
+    @Anonymous
+    @GetMapping("/selectSysBpmNodeScriptByScriptKey/{scriptKey}")
+    public AjaxResult selectSysBpmNodeScriptByScriptKey(@PathVariable("scriptKey") String scriptKey){
+        return success(sysBpmNodeScriptService.selectSysBpmNodeScriptByScriptKey(scriptKey));
+    }
 }

+ 104 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDragTableStyleController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.system;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+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.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.system.domain.SysDragTableStyle;
+import com.ruoyi.system.service.ISysDragTableStyleService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 动态格样式模板Controller
+ * 
+ * @author ruoyi
+ * @date 2023-11-07
+ */
+@RestController
+@RequestMapping("/system/style")
+public class SysDragTableStyleController extends BaseController
+{
+    @Autowired
+    private ISysDragTableStyleService sysDragTableStyleService;
+
+    /**
+     * 查询动态格样式模板列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:style:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysDragTableStyle sysDragTableStyle)
+    {
+        startPage();
+        List<SysDragTableStyle> list = sysDragTableStyleService.selectSysDragTableStyleList(sysDragTableStyle);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出动态格样式模板列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:style:export')")
+    @Log(title = "动态格样式模板", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SysDragTableStyle sysDragTableStyle)
+    {
+        List<SysDragTableStyle> list = sysDragTableStyleService.selectSysDragTableStyleList(sysDragTableStyle);
+        ExcelUtil<SysDragTableStyle> util = new ExcelUtil<SysDragTableStyle>(SysDragTableStyle.class);
+        util.exportExcel(response, list, "动态格样式模板数据");
+    }
+
+    /**
+     * 获取动态格样式模板详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:style:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(sysDragTableStyleService.selectSysDragTableStyleById(id));
+    }
+
+    /**
+     * 新增动态格样式模板
+     */
+    @PreAuthorize("@ss.hasPermi('system:style:add')")
+    @Log(title = "动态格样式模板", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody SysDragTableStyle sysDragTableStyle)
+    {
+        return toAjax(sysDragTableStyleService.insertSysDragTableStyle(sysDragTableStyle));
+    }
+
+    /**
+     * 修改动态格样式模板
+     */
+    @PreAuthorize("@ss.hasPermi('system:style:edit')")
+    @Log(title = "动态格样式模板", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody SysDragTableStyle sysDragTableStyle)
+    {
+        return toAjax(sysDragTableStyleService.updateSysDragTableStyle(sysDragTableStyle));
+    }
+
+    /**
+     * 删除动态格样式模板
+     */
+    @PreAuthorize("@ss.hasPermi('system:style:remove')")
+    @Log(title = "动态格样式模板", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(sysDragTableStyleService.deleteSysDragTableStyleByIds(ids));
+    }
+}

+ 11 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java

@@ -2,6 +2,8 @@ package com.ruoyi.web.controller.system;
 
 import java.util.List;
 import javax.servlet.http.HttpServletResponse;
+
+import com.ruoyi.common.annotation.Anonymous;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
@@ -263,4 +265,13 @@ public class SysRoleController extends BaseController
         ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
         return ajax;
     }
+
+    /**
+     * 根据角色权限字符查询该角色下是否存在真实用户
+     */
+    @Anonymous
+    @GetMapping("/selectUserByRoleKey/{roleKeys}")
+    public AjaxResult selectUserByRoleKey(@PathVariable("roleKeys") List<String> roleKeys){
+        return AjaxResult.success(roleService.selectUserByRoleKey(roleKeys));
+    }
 }

+ 9 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java

@@ -282,4 +282,13 @@ public class SysUserController extends BaseController
     public AjaxResult selectAllUser(){
         return AjaxResult.success(userService.selectAllUser());
     }
+
+    /**
+     * 查询这组用户中是否存在真实用户
+     */
+    @Anonymous
+    @GetMapping("/selectUserByUserIds/{userIds}")
+    public AjaxResult selectUserByUserIds(@PathVariable("userIds") List<Long> userIds){
+        return AjaxResult.success(userService.selectUserByUserIds(userIds));
+    }
 }

+ 166 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDragTableStyle.java

@@ -0,0 +1,166 @@
+package com.ruoyi.system.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 动态格样式模板对象 sys_drag_table_style
+ * 
+ * @author ruoyi
+ * @date 2023-11-07
+ */
+public class SysDragTableStyle extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 编号 */
+    private Long id;
+
+    /** 样式key(唯一) */
+    @Excel(name = "样式key", readConverterExp = "唯=一")
+    private String styleKey;
+
+    /** 样式名称 */
+    @Excel(name = "样式名称")
+    private String styleName;
+
+    /** 样式类型 */
+    @Excel(name = "样式类型")
+    private Long styleType;
+
+    /** 样式代码 */
+    @Excel(name = "样式代码")
+    private String styleCode;
+
+    /** 样式描述 */
+    @Excel(name = "样式描述")
+    private String styleDescription;
+
+    /** 样式状态(0正常 1停用) */
+    @Excel(name = "样式状态", readConverterExp = "0=正常,1=停用")
+    private String styleStatus;
+
+    /** 删除标志(0:否;1:是) */
+    private String delFlag;
+
+    /** 创建者ID */
+    @Excel(name = "创建者ID")
+    private Long createById;
+
+    /** 更新者ID */
+    @Excel(name = "更新者ID")
+    private Long updateById;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+    public void setStyleKey(String styleKey) 
+    {
+        this.styleKey = styleKey;
+    }
+
+    public String getStyleKey() 
+    {
+        return styleKey;
+    }
+    public void setStyleName(String styleName) 
+    {
+        this.styleName = styleName;
+    }
+
+    public String getStyleName() 
+    {
+        return styleName;
+    }
+    public void setStyleType(Long styleType) 
+    {
+        this.styleType = styleType;
+    }
+
+    public Long getStyleType() 
+    {
+        return styleType;
+    }
+    public void setStyleCode(String styleCode) 
+    {
+        this.styleCode = styleCode;
+    }
+
+    public String getStyleCode() 
+    {
+        return styleCode;
+    }
+    public void setStyleDescription(String styleDescription) 
+    {
+        this.styleDescription = styleDescription;
+    }
+
+    public String getStyleDescription() 
+    {
+        return styleDescription;
+    }
+    public void setStyleStatus(String styleStatus) 
+    {
+        this.styleStatus = styleStatus;
+    }
+
+    public String getStyleStatus() 
+    {
+        return styleStatus;
+    }
+    public void setDelFlag(String delFlag) 
+    {
+        this.delFlag = delFlag;
+    }
+
+    public String getDelFlag() 
+    {
+        return delFlag;
+    }
+    public void setCreateById(Long createById) 
+    {
+        this.createById = createById;
+    }
+
+    public Long getCreateById() 
+    {
+        return createById;
+    }
+    public void setUpdateById(Long updateById) 
+    {
+        this.updateById = updateById;
+    }
+
+    public Long getUpdateById() 
+    {
+        return updateById;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("styleKey", getStyleKey())
+            .append("styleName", getStyleName())
+            .append("styleType", getStyleType())
+            .append("styleCode", getStyleCode())
+            .append("styleDescription", getStyleDescription())
+            .append("styleStatus", getStyleStatus())
+            .append("delFlag", getDelFlag())
+            .append("createBy", getCreateBy())
+            .append("createById", getCreateById())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateById", getUpdateById())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 7 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysBpmNodeScriptMapper.java

@@ -58,4 +58,11 @@ public interface SysBpmNodeScriptMapper
      * @return 结果
      */
     int deleteSysBpmNodeScriptByIds(Long[] ids);
+
+    /**
+     * 根据scriptKey查询流程节点脚本
+     * @param scriptKey 唯一标识
+     * @return
+     */
+    SysBpmNodeScript selectSysBpmNodeScriptByScriptKey(String scriptKey);
 }

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDragTableStyleMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.system.mapper;
+
+import java.util.List;
+import com.ruoyi.system.domain.SysDragTableStyle;
+
+/**
+ * 动态格样式模板Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2023-11-07
+ */
+public interface SysDragTableStyleMapper 
+{
+    /**
+     * 查询动态格样式模板
+     * 
+     * @param id 动态格样式模板主键
+     * @return 动态格样式模板
+     */
+    SysDragTableStyle selectSysDragTableStyleById(Long id);
+
+    /**
+     * 查询动态格样式模板列表
+     * 
+     * @param sysDragTableStyle 动态格样式模板
+     * @return 动态格样式模板集合
+     */
+    List<SysDragTableStyle> selectSysDragTableStyleList(SysDragTableStyle sysDragTableStyle);
+
+    /**
+     * 新增动态格样式模板
+     * 
+     * @param sysDragTableStyle 动态格样式模板
+     * @return 结果
+     */
+    int insertSysDragTableStyle(SysDragTableStyle sysDragTableStyle);
+
+    /**
+     * 修改动态格样式模板
+     * 
+     * @param sysDragTableStyle 动态格样式模板
+     * @return 结果
+     */
+    int updateSysDragTableStyle(SysDragTableStyle sysDragTableStyle);
+
+    /**
+     * 删除动态格样式模板
+     * 
+     * @param id 动态格样式模板主键
+     * @return 结果
+     */
+    int deleteSysDragTableStyleById(Long id);
+
+    /**
+     * 批量删除动态格样式模板
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteSysDragTableStyleByIds(Long[] ids);
+}

+ 7 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java

@@ -136,4 +136,11 @@ public interface SysUserMapper
      * 根据租户编号查询用户编号
      */
     Long[] selectUserIdByTenantIds(Long[] tenantIds);
+
+    /**
+     * 查询这组用户中是否存在真实用户
+     * @param userIds
+     * @return
+     */
+    int selectUserByUserIds(List<Long> userIds);
 }

+ 7 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java

@@ -59,4 +59,11 @@ public interface SysUserRoleMapper
      * @return 结果
      */
     public int deleteUserRoleInfos(@Param("roleId") Long roleId, @Param("userIds") Long[] userIds);
+
+    /**
+     * 根据角色权限字符查询该角色下是否存在真实用户
+     * @param roleKeys
+     * @return
+     */
+    int selectUserByRoleKey(List<String> roleKeys);
 }

+ 7 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysBpmNodeScriptService.java

@@ -58,4 +58,11 @@ public interface ISysBpmNodeScriptService
      * @return 结果
      */
     int deleteSysBpmNodeScriptById(Long id);
+
+    /**
+     * 根据scriptKey查询流程节点脚本
+     * @param scriptKey 唯一标识
+     * @return
+     */
+    SysBpmNodeScript selectSysBpmNodeScriptByScriptKey(String scriptKey);
 }

+ 62 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDragTableStyleService.java

@@ -0,0 +1,62 @@
+package com.ruoyi.system.service;
+
+import com.ruoyi.system.domain.SysDragTableStyle;
+
+import java.util.List;
+
+/**
+ * 动态格样式模板Service接口
+ * 
+ * @author ruoyi
+ * @date 2023-11-07
+ */
+public interface ISysDragTableStyleService 
+{
+    /**
+     * 查询动态格样式模板
+     * 
+     * @param id 动态格样式模板主键
+     * @return 动态格样式模板
+     */
+    SysDragTableStyle selectSysDragTableStyleById(Long id);
+
+    /**
+     * 查询动态格样式模板列表
+     * 
+     * @param sysDragTableStyle 动态格样式模板
+     * @return 动态格样式模板集合
+     */
+    List<SysDragTableStyle> selectSysDragTableStyleList(SysDragTableStyle sysDragTableStyle);
+
+    /**
+     * 新增动态格样式模板
+     * 
+     * @param sysDragTableStyle 动态格样式模板
+     * @return 结果
+     */
+    int insertSysDragTableStyle(SysDragTableStyle sysDragTableStyle);
+
+    /**
+     * 修改动态格样式模板
+     * 
+     * @param sysDragTableStyle 动态格样式模板
+     * @return 结果
+     */
+    int updateSysDragTableStyle(SysDragTableStyle sysDragTableStyle);
+
+    /**
+     * 批量删除动态格样式模板
+     * 
+     * @param ids 需要删除的动态格样式模板主键集合
+     * @return 结果
+     */
+    int deleteSysDragTableStyleByIds(Long[] ids);
+
+    /**
+     * 删除动态格样式模板信息
+     * 
+     * @param id 动态格样式模板主键
+     * @return 结果
+     */
+    int deleteSysDragTableStyleById(Long id);
+}

+ 7 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java

@@ -178,4 +178,11 @@ public interface ISysRoleService
      * @return 结果
      */
     public int insertAuthUsers(Long roleId, Long[] userIds);
+
+    /**
+     * 根据角色权限字符查询该角色下是否存在真实用户
+     * @param roleKeys
+     * @return
+     */
+    int selectUserByRoleKey(List<String> roleKeys);
 }

+ 7 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java

@@ -209,4 +209,11 @@ public interface ISysUserService
      */
     List<SysUser> selectAllUser();
 
+    /**
+     * 查询这组用户中是否存在真实用户
+     * @param userIds
+     * @return
+     */
+    int selectUserByUserIds(List<Long> userIds);
+
 }

+ 5 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysBpmNodeScriptServiceImpl.java

@@ -98,4 +98,9 @@ public class SysBpmNodeScriptServiceImpl implements ISysBpmNodeScriptService
     {
         return sysBpmNodeScriptMapper.deleteSysBpmNodeScriptById(id);
     }
+
+    @Override
+    public SysBpmNodeScript selectSysBpmNodeScriptByScriptKey(String scriptKey) {
+        return sysBpmNodeScriptMapper.selectSysBpmNodeScriptByScriptKey(scriptKey);
+    }
 }

+ 101 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDragTableStyleServiceImpl.java

@@ -0,0 +1,101 @@
+package com.ruoyi.system.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.SecurityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.system.mapper.SysDragTableStyleMapper;
+import com.ruoyi.system.domain.SysDragTableStyle;
+import com.ruoyi.system.service.ISysDragTableStyleService;
+
+/**
+ * 动态格样式模板Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2023-11-07
+ */
+@Service
+public class SysDragTableStyleServiceImpl implements ISysDragTableStyleService 
+{
+    @Autowired
+    private SysDragTableStyleMapper sysDragTableStyleMapper;
+
+    /**
+     * 查询动态格样式模板
+     * 
+     * @param id 动态格样式模板主键
+     * @return 动态格样式模板
+     */
+    @Override
+    public SysDragTableStyle selectSysDragTableStyleById(Long id)
+    {
+        return sysDragTableStyleMapper.selectSysDragTableStyleById(id);
+    }
+
+    /**
+     * 查询动态格样式模板列表
+     * 
+     * @param sysDragTableStyle 动态格样式模板
+     * @return 动态格样式模板
+     */
+    @Override
+    public List<SysDragTableStyle> selectSysDragTableStyleList(SysDragTableStyle sysDragTableStyle)
+    {
+        return sysDragTableStyleMapper.selectSysDragTableStyleList(sysDragTableStyle);
+    }
+
+    /**
+     * 新增动态格样式模板
+     * 
+     * @param sysDragTableStyle 动态格样式模板
+     * @return 结果
+     */
+    @Override
+    public int insertSysDragTableStyle(SysDragTableStyle sysDragTableStyle)
+    {
+        sysDragTableStyle.setCreateTime(DateUtils.getNowDate());
+        sysDragTableStyle.setCreateById(SecurityUtils.getUserId());
+        sysDragTableStyle.setCreateBy(SecurityUtils.getUsername());
+        return sysDragTableStyleMapper.insertSysDragTableStyle(sysDragTableStyle);
+    }
+
+    /**
+     * 修改动态格样式模板
+     * 
+     * @param sysDragTableStyle 动态格样式模板
+     * @return 结果
+     */
+    @Override
+    public int updateSysDragTableStyle(SysDragTableStyle sysDragTableStyle)
+    {
+        sysDragTableStyle.setUpdateTime(DateUtils.getNowDate());
+        sysDragTableStyle.setUpdateById(SecurityUtils.getUserId());
+        sysDragTableStyle.setUpdateBy(SecurityUtils.getUsername());
+        return sysDragTableStyleMapper.updateSysDragTableStyle(sysDragTableStyle);
+    }
+
+    /**
+     * 批量删除动态格样式模板
+     * 
+     * @param ids 需要删除的动态格样式模板主键
+     * @return 结果
+     */
+    @Override
+    public int deleteSysDragTableStyleByIds(Long[] ids)
+    {
+        return sysDragTableStyleMapper.deleteSysDragTableStyleByIds(ids);
+    }
+
+    /**
+     * 删除动态格样式模板信息
+     * 
+     * @param id 动态格样式模板主键
+     * @return 结果
+     */
+    @Override
+    public int deleteSysDragTableStyleById(Long id)
+    {
+        return sysDragTableStyleMapper.deleteSysDragTableStyleById(id);
+    }
+}

+ 5 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java

@@ -394,4 +394,9 @@ public class SysRoleServiceImpl implements ISysRoleService {
         }
         return userRoleMapper.batchUserRole(list);
     }
+
+    @Override
+    public int selectUserByRoleKey(List<String> roleKeys) {
+        return userRoleMapper.selectUserByRoleKey(roleKeys);
+    }
 }

+ 5 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java

@@ -546,4 +546,9 @@ public class SysUserServiceImpl implements ISysUserService
     public List<SysUser> selectAllUser() {
         return userMapper.selectAllUser();
     }
+
+    @Override
+    public int selectUserByUserIds(List<Long> userIds) {
+        return userMapper.selectUserByUserIds(userIds);
+    }
 }

+ 5 - 0
ruoyi-system/src/main/resources/mapper/system/SysBpmNodeScriptMapper.xml

@@ -96,4 +96,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{id}
         </foreach>
     </update>
+
+    <select id="selectSysBpmNodeScriptByScriptKey" parameterType="String" resultMap="SysBpmNodeScriptResult">
+        <include refid="selectSysBpmNodeScriptVo"/>
+        where script_key = #{scriptKey}
+    </select>
 </mapper>

+ 101 - 0
ruoyi-system/src/main/resources/mapper/system/SysDragTableStyleMapper.xml

@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.system.mapper.SysDragTableStyleMapper">
+    
+    <resultMap type="SysDragTableStyle" id="SysDragTableStyleResult">
+        <result property="id"    column="id"    />
+        <result property="styleKey"    column="style_key"    />
+        <result property="styleName"    column="style_name"    />
+        <result property="styleType"    column="style_type"    />
+        <result property="styleCode"    column="style_code"    />
+        <result property="styleDescription"    column="style_description"    />
+        <result property="styleStatus"    column="style_status"    />
+        <result property="delFlag"    column="del_flag"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createById"    column="create_by_id"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateById"    column="update_by_id"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectSysDragTableStyleVo">
+        select id, style_key, style_name, style_type, style_code, style_description, style_status, del_flag, create_by, create_by_id, create_time, update_by, update_by_id, update_time from sys_drag_table_style
+    </sql>
+
+    <select id="selectSysDragTableStyleList" parameterType="SysDragTableStyle" resultMap="SysDragTableStyleResult">
+        <include refid="selectSysDragTableStyleVo"/>
+        where del_flag = '0'
+            <if test="styleKey != null  and styleKey != ''"> and style_key = #{styleKey}</if>
+            <if test="styleName != null  and styleName != ''"> and style_name like concat('%', #{styleName}, '%')</if>
+            <if test="styleType != null "> and style_type = #{styleType}</if>
+            <if test="styleCode != null  and styleCode != ''"> and style_code = #{styleCode}</if>
+            <if test="styleDescription != null  and styleDescription != ''"> and style_description = #{styleDescription}</if>
+            <if test="styleStatus != null  and styleStatus != ''"> and style_status = #{styleStatus}</if>
+            <if test="createById != null "> and create_by_id = #{createById}</if>
+            <if test="updateById != null "> and update_by_id = #{updateById}</if>
+             order by create_time desc
+    </select>
+    
+    <select id="selectSysDragTableStyleById" parameterType="Long" resultMap="SysDragTableStyleResult">
+        <include refid="selectSysDragTableStyleVo"/>
+        where id = #{id}
+    </select>
+        
+    <insert id="insertSysDragTableStyle" parameterType="SysDragTableStyle">
+        insert into sys_drag_table_style
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="styleKey != null">style_key,</if>
+            <if test="styleName != null">style_name,</if>
+            <if test="styleType != null">style_type,</if>
+            <if test="styleCode != null">style_code,</if>
+            <if test="styleDescription != null">style_description,</if>
+            <if test="styleStatus != null">style_status,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createById != null">create_by_id,</if>
+            <if test="createTime != null">create_time,</if>
+            del_flag
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="styleKey != null">#{styleKey},</if>
+            <if test="styleName != null">#{styleName},</if>
+            <if test="styleType != null">#{styleType},</if>
+            <if test="styleCode != null">#{styleCode},</if>
+            <if test="styleDescription != null">#{styleDescription},</if>
+            <if test="styleStatus != null">#{styleStatus},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createById != null">#{createById},</if>
+            <if test="createTime != null">#{createTime},</if>
+            '0'
+         </trim>
+    </insert>
+
+    <update id="updateSysDragTableStyle" parameterType="SysDragTableStyle">
+        update sys_drag_table_style
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="styleKey != null">style_key = #{styleKey},</if>
+            <if test="styleName != null">style_name = #{styleName},</if>
+            <if test="styleType != null">style_type = #{styleType},</if>
+            <if test="styleCode != null">style_code = #{styleCode},</if>
+            <if test="styleDescription != null">style_description = #{styleDescription},</if>
+            <if test="styleStatus != null">style_status = #{styleStatus},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateById != null">update_by_id = #{updateById},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <update id="deleteSysDragTableStyleById" parameterType="Long">
+        update sys_drag_table_style set del_flag = '2' where id = #{id}
+    </update>
+
+    <update id="deleteSysDragTableStyleByIds" parameterType="String">
+        update sys_drag_table_style set del_flag = '2' where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </update>
+</mapper>

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

@@ -314,5 +314,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 			#{tenantId}
 		</foreach>
 	</select>
+
+	<select id="selectUserByUserIds" resultType="int">
+		select count(1) from sys_user where `status` = '0' and del_flag = '0' and user_id in
+		<foreach collection="list" item="userId" open="(" close=")" separator=",">
+			#{userId}
+		</foreach>
+	</select>
 	
 </mapper> 

+ 12 - 0
ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml

@@ -41,4 +41,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  	        #{userId}
             </foreach> 
 	</delete>
+
+	<select id="selectUserByRoleKey" resultType="int">
+		SELECT count(1) from sys_user where `status` = '0' and del_flag = '0' and user_id in
+			(
+				select user_id from sys_user_role where role_id in (
+					select role_id from sys_role where `status` = '0' and del_flag = '0' and role_key in
+					<foreach collection="list" item="roleKey" open="(" close=")" separator=",">
+						#{roleKey}
+					</foreach>
+				)
+			)
+	</select>
 </mapper> 

+ 51 - 1
ruoyi-system/src/main/resources/sql/initialize_sys_tenant_menu.json

@@ -906,7 +906,7 @@
         "updateTime": null,
         "remark": null,
         "menuId": 1109,
-        "menuName": "租户字典管理",
+        "menuName": "字典管理",
         "parentName": null,
         "parentId": 1,
         "orderNum": 10,
@@ -973,5 +973,55 @@
         "children": [],
         "tenantName": null,
         "tenantId": null
+    },
+    {
+        "createBy": null,
+        "createTime": "2023-10-11 09:28:10",
+        "updateBy": null,
+        "updateTime": null,
+        "remark": null,
+        "menuId": 3811,
+        "menuName": "联动表格",
+        "parentName": null,
+        "parentId": 1103,
+        "orderNum": 5,
+        "path": "relateTable",
+        "component": "relateTable/index",
+        "query": null,
+        "isFrame": "1",
+        "isCache": "0",
+        "menuType": "C",
+        "visible": "0",
+        "status": "0",
+        "perms": "",
+        "icon": "bpmn-icon-call-activity",
+        "children": [],
+        "tenantName": null,
+        "tenantId": null
+    },
+    {
+        "createBy": null,
+        "createTime": "2023-10-11 09:28:10",
+        "updateBy": null,
+        "updateTime": null,
+        "remark": null,
+        "menuId": 3806,
+        "menuName": "动态表格",
+        "parentName": null,
+        "parentId": 1103,
+        "orderNum": 6,
+        "path": "relateTableEdit",
+        "component": "relateTable/relateTableEdit",
+        "query": null,
+        "isFrame": "1",
+        "isCache": "0",
+        "menuType": "C",
+        "visible": "1",
+        "status": "0",
+        "perms": "",
+        "icon": "#",
+        "children": [],
+        "tenantName": null,
+        "tenantId": null
     }
 ]

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

@@ -11,10 +11,10 @@ VUE_APP_BASE_API = '/dev-api'
 VUE_CLI_BABEL_TRANSPILE_MODULES = true
 
 #数据引擎模块IP
-VUE_APP_BASE_API2 = 'http://192.168.110.59:8099/'
+VUE_APP_BASE_API2 = 'http://192.168.110.76:8099/'
 
 #表单引擎模块IP
-VUE_APP_BASE_API3 = 'http://192.168.110.59:8088/'
+VUE_APP_BASE_API3 = 'http://192.168.110.76:8088/'
 
 #流程引擎模块IP
-VUE_APP_BASE_API4 = 'http://192.168.110.59:8055/'
+VUE_APP_BASE_API4 = 'http://192.168.110.76:8055/'

+ 44 - 0
ruoyi-ui/src/api/bussiness/bpmExcuteProcess.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询流程执行任务表列表
+export function listProcess(query) {
+  return request({
+    url: '/system/process/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询流程执行任务表详细
+export function getProcess(id) {
+  return request({
+    url: '/system/process/' + id,
+    method: 'get'
+  })
+}
+
+// 新增流程执行任务表
+export function addProcess(data) {
+  return request({
+    url: '/system/process',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改流程执行任务表
+export function updateProcess(data) {
+  return request({
+    url: '/system/process',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除流程执行任务表
+export function delProcess(id) {
+  return request({
+    url: '/system/process/' + id,
+    method: 'delete'
+  })
+}

+ 50 - 0
ruoyi-ui/src/api/system/btn.js

@@ -0,0 +1,50 @@
+import request from '@/utils/request'
+
+// 查询格绑定的自定义按钮列表
+// btnParentId:0 
+export function listBtn(query) {
+  return request({
+    url: '/system/btn/list',
+    method: 'get',
+    params: query,
+    baseURL:process.env.VUE_APP_BASE_API3
+  })
+}
+
+// 查询格绑定的自定义按钮详细
+export function getBtn(id) {
+  return request({
+    url: '/system/btn/' + id,
+    method: 'get',
+    baseURL:process.env.VUE_APP_BASE_API3
+  })
+}
+
+// 新增格绑定的自定义按钮
+export function addBtn(data) {
+  return request({
+    url: '/system/btn',
+    method: 'post',
+    data: data,
+    baseURL:process.env.VUE_APP_BASE_API3
+  })
+}
+
+// 修改格绑定的自定义按钮
+export function updateBtn(data) {
+  return request({
+    url: '/system/btn',
+    method: 'put',
+    data: data,
+    baseURL:process.env.VUE_APP_BASE_API3
+  })
+}
+
+// 删除格绑定的自定义按钮
+export function delBtn(id) {
+  return request({
+    url: '/system/btn/' + id,
+    method: 'delete',
+    baseURL:process.env.VUE_APP_BASE_API3
+  })
+}

+ 44 - 0
ruoyi-ui/src/api/system/style.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询动态格样式模板列表
+export function listStyle(query) {
+  return request({
+    url: '/system/style/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询动态格样式模板详细
+export function getStyle(id) {
+  return request({
+    url: '/system/style/' + id,
+    method: 'get'
+  })
+}
+
+// 新增动态格样式模板
+export function addStyle(data) {
+  return request({
+    url: '/system/style',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改动态格样式模板
+export function updateStyle(data) {
+  return request({
+    url: '/system/style',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除动态格样式模板
+export function delStyle(id) {
+  return request({
+    url: '/system/style/' + id,
+    method: 'delete'
+  })
+}

BIN
ruoyi-ui/src/assets/images/background2.jpg


+ 498 - 0
ruoyi-ui/src/components/kFormDesign/OptionsEdit.vue

@@ -0,0 +1,498 @@
+<template>
+  <div class="option-edit-wrap">
+    <el-button
+      type="info"
+      size="default"
+      icon="el-icon-edit"
+      @click="editHandler"
+    >
+    </el-button>
+    <el-dialog
+      title="设置下拉选项数据"
+      :visible.sync="isShow"
+      width="50%"
+      :before-close="cancleHandler"
+    >
+      <el-form
+        ref="formDataRef"
+        :model="formData"
+        :rules="rules"
+        label-width="140px"
+      >
+        <el-row type="flex" style="flex-wrap: wrap">
+          <el-col :span="12">
+            <el-form-item label="选项数据名" prop="dynamicName">
+              <el-input
+                v-model="formData.dynamicName"
+                placeholder="请输入动态数据名"
+                size="normal"
+              ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="表名" prop="tableName">
+              <el-select
+                class="mr10"
+                v-model="formData.tableName"
+                placeholder="请选择表名"
+                clearable
+                filterable
+                @change="
+                  (value) => {
+                    getFieldOptions(value);
+                  }
+                "
+              >
+                <el-option
+                  v-for="item in tableList"
+                  :key="item.tableName"
+                  :label="item.tableComment"
+                  :value="item.tableName"
+                >
+                  <span style="float: left">{{ item.tableComment }}</span>
+                  <span style="float: right; color: #8492a6; font-size: 13px">{{
+                    item.tableName
+                  }}</span>
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="描述字段(label)" prop="optLabelData">
+              <el-select
+                v-model="formData.optLabelData"
+                placeholder="请选择字段"
+                clearable
+                filterable
+              >
+                <el-option
+                  v-for="item in fieldList"
+                  :key="item.fieldName"
+                  :label="item.fieldDescription"
+                  :value="item.fieldName"
+                >
+                  <span style="float: left">{{ item.fieldDescription }}</span>
+                  <span style="float: right; color: #8492a6; font-size: 13px">{{
+                    item.fieldName
+                  }}</span>
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="值字段(value)" prop="optValueData">
+              <el-select
+                v-model="formData.optValueData"
+                placeholder="请选择字段"
+                clearable
+                filterable
+              >
+                <el-option
+                  v-for="item in fieldList"
+                  :key="item.fieldName"
+                  :label="item.fieldDescription"
+                  :value="item.fieldName"
+                >
+                  <span style="float: left">{{ item.fieldDescription }}</span>
+                  <span style="float: right; color: #8492a6; font-size: 13px">{{
+                    item.fieldName
+                  }}</span>
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <div class="filter-table-wrap">
+              <span class="title">添加数据过滤条件</span>
+              <el-table :data="filterTableData" style="width: 100%">
+                <el-table-column label="序号" type="index" width="50">
+                </el-table-column>
+                <!-- <el-table-column prop="tableName" label="表名" width="150">
+                  <template slot-scope="scope">
+                    <el-select
+                      v-model="scope.row.tableName"
+                      @change="
+                        (value) => {
+                          getFieldOptions(value, scope.row);
+                        }
+                      "
+                      placeholder="请选择"
+                    >
+                      <el-option
+                        v-for="item in tableList"
+                        :key="item.tableName"
+                        :label="item.tableComment"
+                        :value="item.tableName"
+                      >
+                        <span style="float: left">{{ item.tableComment }}</span>
+                        <span
+                          style="float: right; color: #8492a6; font-size: 13px"
+                          >{{ item.tableName }}</span
+                        >
+                      </el-option>
+                    </el-select>
+                  </template>
+                </el-table-column> -->
+                <el-table-column prop="fieldName" label="字段名" width="150">
+                  <template slot-scope="scope">
+                    <el-select
+                      v-model="scope.row.fieldName"
+                      placeholder="请选择"
+                    >
+                      <el-option
+                        v-for="item in fieldList"
+                        :key="item.fieldName"
+                        :label="item.fieldDescription"
+                        :value="item.fieldName"
+                      >
+                        <span style="float: left">{{
+                          item.fieldDescription
+                        }}</span>
+                        <span
+                          style="float: right; color: #8492a6; font-size: 13px"
+                          >{{ item.fieldName }}</span
+                        >
+                      </el-option>
+                    </el-select>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="flagValue" label="参照值" width="100">
+                  <template slot-scope="scope">
+                    <el-button
+                      type="info"
+                      size="small"
+                      icon="el-icon-edit"
+                      @click="editFlagHandler(scope.row, scope.$index)"
+                    >
+                    </el-button>
+                  </template>
+                </el-table-column>
+                <el-table-column label="操作">
+                  <template slot-scope="scope">
+                    <el-button
+                      size="mini"
+                      type="danger"
+                      icon="el-icon-delete"
+                      @click="deleteFilterItem(scope.$index)"
+                      >删除
+                    </el-button>
+                  </template>
+                </el-table-column>
+              </el-table>
+              <el-button
+                type="primary"
+                class="inline-large-button mb10"
+                icon="el-icon-plus"
+                size="mini"
+                style="width: 100%"
+                @click="addFilterHandler"
+              >
+                添加条件
+              </el-button>
+            </div>
+          </el-col>
+        </el-row>
+      </el-form>
+
+      <template #footer>
+        <span>
+          <el-button @click="cancleHandler">取消</el-button>
+          <el-button type="primary" @click="conformHandler">确认</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    <el-dialog title="编辑参照值" :visible.sync="flagShow" width="30%">
+      <el-form
+        :model="flagFormData"
+        ref="flagFormDataRef"
+        :rules="rules"
+        label-width="100px"
+        :inline="false"
+        size="normal"
+      >
+        <el-form-item label="参照类型">
+          <el-select
+            v-model="flagFormData.flagType"
+            placeholder="请选择参照类型"
+            filterable
+          >
+            <el-option
+              v-for="item in flagTypeList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item
+          prop="flagValue"
+          v-show="flagFormData.flagType == 0"
+          label="自定义值"
+        >
+          <el-input v-model="flagFormData.flagValue"></el-input>
+        </el-form-item>
+        <el-form-item
+          prop="tableField"
+          v-show="flagFormData.flagType == 1"
+          label="关联表格字段"
+        >
+          <el-select
+            class="mr10"
+            v-model="flagFormData.tableField.tableName"
+            placeholder="请选择表名"
+            clearable
+            filterable
+            @change="
+              (value) => {
+                getFieldOptions(value, flagFormData.tableField);
+              }
+            "
+          >
+            <el-option
+              v-for="item in tableList"
+              :key="item.tableName"
+              :label="item.tableComment"
+              :value="item.tableName"
+            >
+              <span style="float: left">{{ item.tableComment }}</span>
+              <span style="float: right; color: #8492a6; font-size: 13px">{{
+                item.tableName
+              }}</span>
+            </el-option>
+          </el-select>
+          <el-select
+            v-model="flagFormData.tableField.fieldName"
+            placeholder="请选择字段"
+            clearable
+            filterable
+          >
+            <el-option
+              v-for="item in flagFormData.tableField.fieldOptions"
+              :key="item.fieldName"
+              :label="item.fieldDescription"
+              :value="item.fieldName"
+            >
+              <span style="float: left">{{ item.fieldDescription }}</span>
+              <span style="float: right; color: #8492a6; font-size: 13px">{{
+                item.fieldName
+              }}</span>
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item
+          v-show="flagFormData.flagType == 2"
+          label="固定值"
+          size="normal"
+        >
+          <el-select
+            v-model="flagFormData.flagValue"
+            placeholder="请选择固定值"
+            filterable
+          >
+            <el-option
+              v-for="item in constFlagList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+
+      <template #footer>
+        <span>
+          <el-button @click="flagShow = false">取消</el-button>
+          <el-button type="primary" @click="flagConfirm">确认</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getFormName, getListName } from "@/api/dragform/form.js";
+import { mapState } from "vuex";
+import getOptionsSqlString from "@/utils/sqlString";
+export default {
+  name: "OptionsEdit",
+  props: ["options", "selectItem"],
+  components: {},
+  data() {
+    return {
+      isShow: false,
+      flagShow: false,
+      flagEditIndex: "",
+      formData: {
+        dynamicName: "", //英文字符串
+        tableName: "",
+        optLabelData: "",
+        optValueData: "",
+      },
+      filterTableData: [
+        {
+          fieldName: "",
+          flagValue: "",
+          fieldOptions: [],
+          flagFormData: {
+            flagType: 0,
+            tableField: {
+              tableName: "",
+              fieldName: "",
+              fieldOptions: [],
+            },
+            flagValue: "",
+          },
+        },
+      ],
+
+      flagFormData: {
+        flagType: 0,
+        tableField: {
+          tableName: "",
+          fieldName: "",
+          fieldOptions: [],
+        },
+        flagValue: "",
+      },
+      flagTypeList: [
+        {
+          value: 0,
+          label: "自定义",
+        },
+        // {
+        //   value: 1,
+        //   label: "关联其他字段",
+        // },
+        {
+          value: 2,
+          label: "固定值",
+        },
+      ],
+      tableList: [],
+      fieldList: [],
+      rules: {},
+      constFlagList: [
+        {
+          value: "#{USERID}",
+          label: "当前用户相关数据",
+        },
+      ],
+    };
+  },
+  computed: {
+    ...mapState({
+      databaseName: (state) => state.user.dataSource.databaseName,
+      databaseType: (state) => state.user.dataSource.databaseType,
+    }),
+  },
+  methods: {
+    // 重置条件表单数据
+    resetFlagFormData() {
+      Object.assign(this.flagFormData, {
+        flagType: 0,
+        tableField: {
+          tableName: "",
+          fieldName: "",
+          fieldOptions: [],
+        },
+        flagValue: "",
+      });
+    },
+    // 开始编辑回调
+    async editHandler() {
+      await this.getAllTable();
+      this.isShow = true;
+    },
+    // 弹窗取消回调
+    cancleHandler() {
+      this.isShow = false;
+    },
+    // 弹窗确认回调
+    conformHandler() {
+      console.log(this.formData, this.filterTableData);
+      let sql = getOptionsSqlString(this.formData, this.filterTableData);
+      let sqlData = {};
+      sqlData[this.formData.dynamicName] = sql;
+      this.$emit("setDynamicKey", this.formData.dynamicName, sqlData);
+
+      console.log(sql);
+      this.isShow = false;
+    },
+    // 获取所有表格
+    async getAllTable() {
+      let data = {
+        databaseName: this.databaseName,
+        databaseType: this.databaseType,
+      };
+      let res = await getFormName(data);
+
+      this.tableList = res.data;
+    },
+    async getFieldOptions(value, tempData) {
+      let data = {
+        databaseName: this.databaseName,
+        databaseType: this.databaseType,
+        tableName: value,
+      };
+      try {
+        let res = await getListName(data);
+        if (tempData) {
+          tempData.fieldOptions = res;
+        } else {
+          this.fieldList = res;
+        }
+      } catch (error) {
+        this.$message.error("网络异常,请稍后再试");
+      }
+    },
+    // 删除一条筛选条件
+    deleteFilterItem(index) {
+      this.filterTableData.splice(index, 1);
+    },
+    // 新增一条筛选条件
+    addFilterHandler() {
+      this.filterTableData.push({
+        // tableName: "",
+        fieldName: "",
+        flagValue: "",
+        fieldOptions: [],
+        flagFormData: {
+          flagType: 0,
+          tableField: {
+            tableName: "",
+            fieldName: "",
+            fieldOptions: [],
+          },
+          flagValue: "",
+        },
+      });
+    },
+    // 编辑参照回调
+    editFlagHandler(row, index) {
+      this.flagEditIndex = index;
+      this.flagFormData = JSON.parse(JSON.stringify(row.flagFormData));
+      this.flagShow = true;
+    },
+    // 确认参照回调
+    flagConfirm() {
+      this.filterTableData[this.flagEditIndex].flagFormData = JSON.parse(
+        JSON.stringify(this.flagFormData)
+      );
+      this.flagShow = false;
+    },
+  },
+  async mounted() {
+    console.log(this.options, this.selectItem);
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.filter-table-wrap {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+</style>

+ 11 - 2
ruoyi-ui/src/components/updateModule/k-form-design/packages/components/KFormDesign/module/formItemProperties.vue

@@ -146,6 +146,8 @@
             v-model="options.dynamicKey"
             placeholder="动态数据变量名"
           />
+          <OptionsEdit v-show="options.dynamic" @setDynamicKey="setDynamicKey" :options="options" :selectItem="selectItem"></OptionsEdit>
+          
 
           <KChangeOption v-show="!options.dynamic" v-model="options.options" />
         </a-form-item>
@@ -570,7 +572,8 @@ import KChangeOption from "../../KChangeOption/index.vue";
 import kCheckbox from "../../KCheckbox/index.vue";
 import { pluginManager } from "../../../utils/index";
 import { getListName, getFormName } from "@/api/dragform/form";
-import {getUncommonTable} from '@/utils/other'
+import { getUncommonTable } from '@/utils/other';
+import OptionsEdit from '@/components/kFormDesign/OptionsEdit.vue'
 const Input = pluginManager.getComponent("input").component;
 const InputNumber = pluginManager.getComponent("number").component;
 const Rate = pluginManager.getComponent("rate").component;
@@ -598,7 +601,8 @@ export default {
     RadioItem,
     RadioButton,
     Textarea,
-    Select
+    Select,
+    OptionsEdit
   },
   data() {
     return {
@@ -703,6 +707,11 @@ export default {
     }
   },
   methods: {
+    setDynamicKey(key,sqlData) {
+      this.options.dynamicKey = key;
+      this.options.sqlData=sqlData
+      console.log(this.options.dynamicKey,key,111);
+    },
     /**
      * 判断是否已定义
      * @param {*} value

+ 1 - 0
ruoyi-ui/src/components/updateModule/k-form-design/packages/components/KFormItem/index.vue

@@ -219,6 +219,7 @@ export default {
       if (e && e.target) {
         value = e.target.value;
       }
+      console.log(this.record);
       // 传递change事件
       this.$emit("change", value, this.record.model);
     },

+ 1 - 0
ruoyi-ui/src/utils/bpmn/formDataValidate.js

@@ -1,6 +1,7 @@
 import { customTranslate } from "@packages/additional-modules/Translate";
 
 export function formDataValidate(obj) {
+  console.log(obj);
   let res = {
     flag: true
   };

+ 13 - 0
ruoyi-ui/src/utils/other.js

@@ -34,4 +34,17 @@ export function inputDisableComplete() {
   for (var i = 0; i < inputs.length; i++) {
     inputs[i].setAttribute('autocomplete', 'off');
   }
+}
+
+/**
+ *获取字典值的对应label
+ *
+ * @param {字典值} value
+ * @param {字典数据} [dictLsit=[]]
+ * @return {*} 
+ */
+export function getDictLabel(value, dictLsit = []) {
+      return dictLsit.find((item) => {
+        return item.value == value;
+      })?.label;
 }

+ 45 - 0
ruoyi-ui/src/utils/sqlString.js

@@ -0,0 +1,45 @@
+
+export default function getOptionsSqlString(baseData, conditions) {
+  let res = {}
+  let { dynamicName, tableName, optLabelData, optValueData } = baseData
+  // res[baseData.dynamicName] = ''
+  let sqlString = 'SELECT '   //起始
+  let labelValueStr = tableName + '.' + optLabelData + ' AS `label`,' + tableName + '.' + optValueData + ' AS `value`,' + tableName + '.* FROM '      //查询字段
+  let allTable = []
+  allTable.push(tableName);
+  conditions.forEach(item => {
+    if (item.flagFormData.flagType == 1) {
+      allTable.push(item.flagFormData.tableField.tableName)
+    }
+  })
+  let set = new Set(allTable);
+  allTable = [...set];
+  console.log(allTable);
+  let tableNickNameStr = ''    //表格别名
+  allTable.forEach(item => {
+    tableNickNameStr += `${item} AS ${item} `
+  })
+  tableNickNameStr += 'WHERE '
+  // 拼接条件
+  let conditionArr = [];
+  conditions.forEach(condition => {
+    switch (condition.flagFormData.flagType) {
+      case 0://自定义
+        conditionArr.push(`${tableName}.${condition.fieldName} = ${condition.flagFormData.flagValue}`)
+        break;
+      case 1://关联其他字段
+        conditionArr.push(`${tableName}.${condition.fieldName} = #{${condition.flagFormData.tableField.tableName}.${condition.flagFormData.tableField.fieldName}}`)
+        break;
+      case 2://固定值
+        conditionArr.push(`${tableName}.${condition.fieldName} = ${condition.flagFormData.flagValue}`)
+        break;
+      default:
+        break;
+    }
+  })
+  let conditionStr = conditionArr.join(' AND ') //条件sql
+
+  return sqlString + labelValueStr + tableNickNameStr + conditionStr
+
+
+}

+ 0 - 1
ruoyi-ui/src/views/bpmprocess/scriptManage.vue

@@ -258,7 +258,6 @@ import {
 import uuid from "@/utils/bpmn/uuid";
 import Editor from "vue2-ace-editor";
 import * as monaco from "monaco-editor";
-import * as actions from "monaco-editor/esm/vs/platform/actions/common/actions";
 
 export default {
   name: "Script",

+ 1 - 1
ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementNormalTask.vue

@@ -1,7 +1,7 @@
 <template>
   <el-collapse-item name="element-normal-task">
     <template #title>
-      <collapse-title title="执行任务">
+      <collapse-title title="正常节点">
         <lucide-icon name="File" />
       </collapse-title>
     </template>

+ 1 - 1
ruoyi-ui/src/views/system/bpmnPro/components/Panel/components/ElementUnusualTasks.vue

@@ -1,7 +1,7 @@
 <template>
   <el-collapse-item name="element-unusual-tasks">
     <template #title>
-      <collapse-title title="管道节点">
+      <collapse-title title="异常节点">
         <lucide-icon name="FileX2" />
       </collapse-title>
       <number-tag :value="listeners.length" margin-left="12px" />

+ 11 - 1
ruoyi-ui/src/views/system/bpmnPro/components/Toolbar/tools/Save.vue

@@ -15,7 +15,11 @@ import xml from "highlight.js/lib/languages/xml";
 import { getProcessEngine } from "@packages/bpmn-utils/BpmnDesignerUtils";
 import EventEmitter from "@utils/EventEmitter";
 import { formDataValidate } from "@utils/formDataValidate";
-import { getNodeMsg, filterNodeMsg } from "@packages/bo-utils/getNodeMsg";
+import {
+  getNodeMsg,
+  filterNodeMsg,
+  validateNode,
+} from "@packages/bo-utils/getNodeMsg";
 import getNodeSequence from "@/utils/bpmn/getNodeSequence";
 
 import moment from "moment";
@@ -126,6 +130,12 @@ export default {
       // 获取xml标签内容标签内容
       let xmlPro = await this.getProcess("xml");
       var xmlObj = this.xmlStr2XmlObj(xmlPro);
+      let validateNodeRes = validateNode(xmlObj);
+      console.log(validateNodeRes);
+      if (!validateNodeRes.flag) {
+        this.$message.error(validateNodeRes.msg);
+        return;
+      }
 
       // 生成节点顺序
       // getNodeSequence(xmlObj);

+ 54 - 1
ruoyi-ui/src/views/system/bpmnPro/components/bo-utils/getNodeMsg.js

@@ -35,7 +35,6 @@ export function getNodeMsg(xmlObj) {
   // let moddle = getModeler.getModdle();
   // console.log(moddle);
   // return;
-  console.dir(xmlObj);
   let prefix = getProcessEngine();
   let { attributes, childNodes } = xmlObj
     .getElementsByTagName("bpmn:process")[0];
@@ -175,4 +174,58 @@ export function filterNodeMsg(oldMsg, newMsg) {
   }).map(item => item.id)
 
   return newMsg;
+}
+
+
+// 遍历节点黑名单(无用节点)  localName
+const blackArr = [
+  "definitions",
+  "process",
+  "startEvent",
+  "outgoing",
+  // "task",
+  "incoming",
+  "outgoing",
+  "sequenceFlow",
+  "endEvent",
+  "incoming",
+  "sequenceFlow",
+  "BPMNDiagram",
+  "BPMNPlane",
+  "BPMNShape",
+  "Bounds",
+  "BPMNLabel",
+  "Bounds",
+  "BPMNShape",
+  "Bounds",
+  "BPMNLabel",
+  "BPMNShape",
+  "Bounds",
+  "BPMNLabel",
+  "Bounds",
+  "BPMNEdge",
+  "waypoint",
+  "waypoint",
+  "BPMNEdge",
+  "waypoint",
+  "waypoint"
+]
+
+/**
+ * 校验节点数据
+ * @param {xml对象} xmlObj 
+ */
+export function validateNode(xmlObj) {
+  let preFix = getProcessEngine()
+  console.dir(xmlObj);
+  let res = { flag: true }, nodeList = xmlObj.all;
+  for (let index = 0; index < nodeList.length; index++) {
+    const element = nodeList[index];
+    if (blackArr.some(item => item == element.localName)) continue
+    if (!element.getAttribute(`${preFix}:NormalScriptKey`)) {
+      res.flag = false;
+      res.msg = `${element.localName}必须绑定正常节点`
+    }
+  }
+  return res
 }

+ 859 - 0
ruoyi-ui/src/views/system/excuteBtnMange/index.vue

@@ -0,0 +1,859 @@
+<template>
+  <div class="app-container">
+    <el-form
+      :model="queryParams"
+      ref="queryForm"
+      size="small"
+      :inline="true"
+      v-show="showSearch"
+    >
+      <el-form-item label="按钮组名" prop="btnGroupName">
+        <el-input
+          v-model="queryParams.btnGroupName"
+          placeholder="请输入菜单名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
+          >搜索</el-button
+        >
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+          >重置</el-button
+        >
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['system:menu:add']"
+          >新增</el-button
+        >
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="info"
+          plain
+          icon="el-icon-sort"
+          size="mini"
+          @click="toggleExpandAll"
+          >展开/折叠</el-button
+        >
+      </el-col>
+      <right-toolbar
+        :showSearch.sync="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
+    </el-row>
+
+    <el-table
+      v-if="refreshTable"
+      v-loading="loading"
+      :data="btnList"
+      row-key="id"
+      :default-expand-all="isExpandAll"
+      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+    >
+      <el-table-column
+        prop="btnGroupName"
+        label="按钮组名称"
+        :show-overflow-tooltip="true"
+        width="160"
+        align="center"
+      ></el-table-column>
+      <el-table-column prop="btnIcon" label="图标" align="center" width="100">
+        <template v-if="scope.row.btnIcon" slot-scope="scope">
+          <svg-icon :icon-class="scope.row.btnIcon" />
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="btnName"
+        label="按钮文字"
+        align="center"
+      ></el-table-column>
+      <el-table-column
+        prop="btnSort"
+        label="排序"
+        align="center"
+        width="60"
+      ></el-table-column>
+      <el-table-column
+        prop="btnHasPermi"
+        label="权限标识"
+        :show-overflow-tooltip="true"
+        align="center"
+      ></el-table-column>
+
+      <el-table-column
+        label="操作"
+        align="center"
+        class-name="small-padding fixed-width"
+      >
+        <template slot-scope="scope">
+          <el-dropdown>
+            <el-button type="warning" plain size="small">
+              处理<i class="el-icon-arrow-down el-icon--right"></i>
+            </el-button>
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item
+                ><el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-edit"
+                  @click="handleUpdate(scope.row)"
+                  v-hasPermi="['system:menu:edit']"
+                  >修改</el-button
+                ></el-dropdown-item
+              >
+              <el-dropdown-item
+                ><el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-plus"
+                  @click="handleAdd(scope.row)"
+                  v-hasPermi="['system:menu:add']"
+                  >新增</el-button
+                ></el-dropdown-item
+              >
+              <el-dropdown-item
+                ><el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleDelete(scope.row)"
+                  v-hasPermi="['system:menu:remove']"
+                  >删除</el-button
+                ></el-dropdown-item
+              >
+            </el-dropdown-menu>
+          </el-dropdown>
+
+          <!-- <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['system:menu:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-plus"
+            @click="handleAdd(scope.row)"
+            v-hasPermi="['system:menu:add']"
+          >新增</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['system:menu:remove']"
+          >删除</el-button> -->
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 添加或修改对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="680px" append-to-body>
+      <el-form
+        ref="btnGroupFormRef"
+        :model="btnGroupFormData"
+        :rules="rules"
+        label-width="100px"
+      >
+        <el-row type="flex" style="flex-wrap: wrap">
+          <el-col :span="12">
+            <el-form-item label="上级按钮" prop="btnParentId">
+              <treeselect
+                v-model="btnGroupFormData.btnParentId"
+                :options="menuOptions"
+                :normalizer="normalizer"
+                :show-count="true"
+                placeholder="选择上级按钮"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="24" v-if="btnGroupFormData.btnParentId == 0">
+            <el-form-item label="按钮组名" prop="btnGroupName">
+              <el-input
+                v-model="btnGroupFormData.btnGroupName"
+                placeholder=""
+                size="normal"
+              ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="按钮名" prop="btnName">
+              <el-input
+                v-model="btnGroupFormData.btnName"
+                placeholder=""
+                size="normal"
+              ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="按钮图标" prop="btnIcon">
+              <el-popover
+                placement="bottom-start"
+                width="460"
+                trigger="click"
+                @show="$refs['iconSelect'].reset()"
+              >
+                <IconSelect
+                  ref="iconSelect"
+                  @selected="selected"
+                  :active-icon="btnGroupFormData.icon"
+                />
+                <el-input
+                  slot="reference"
+                  v-model="btnGroupFormData.icon"
+                  placeholder="点击选择图标"
+                  readonly
+                >
+                  <svg-icon
+                    v-if="btnGroupFormData.btnIcon"
+                    slot="prefix"
+                    :icon-class="btnGroupFormData.btnIcon"
+                    style="width: 25px"
+                  />
+                  <i
+                    v-else
+                    slot="prefix"
+                    class="el-icon-search el-input__icon"
+                  />
+                </el-input>
+              </el-popover>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="排序" prop="btnSort">
+              <el-input-number
+                v-model="btnGroupFormData.btnSort"
+                controls-position="right"
+                :min="0"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="权限标识" prop="btnIcon">
+              <el-input
+                v-model="btnGroupFormData.btnHasPermi"
+                placeholder="请输入权限标识"
+                maxlength="100"
+              />
+              <span slot="label">
+                <el-tooltip
+                  content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasPermi('system:user:list')`)"
+                  placement="top"
+                >
+                  <i class="el-icon-question"></i>
+                </el-tooltip>
+                权限字符
+              </span>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="按钮类型" prop="btnType">
+              <el-select
+                v-model="btnGroupFormData.btnType"
+                placeholder="请选择按钮类型"
+                filterable
+              >
+                <el-option
+                  v-for="item in btnTypeOptions"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <div v-show="btnGroupFormData.btnType != 6">
+            <el-col :span="12">
+              <el-form-item label="绑定表单" prop="btnFormKey">
+                <el-select
+                  v-model="btnGroupFormData.btnFormKey"
+                  placeholder="请选择表单"
+                  clearable
+                  filterable
+                >
+                  <el-option
+                    v-for="item in formOptions"
+                    :key="item.fId"
+                    :label="item.dfName"
+                    :value="item.fId"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="执行流程" prop="btnTableKey">
+                <el-select
+                  v-model="btnGroupFormData.btnTableKey"
+                  placeholder="请选择执行流程"
+                  clearable
+                  filterable
+                >
+                  <el-option
+                    v-for="item in []"
+                    :key="item.fId"
+                    :label="item.dfName"
+                    :value="item.fId"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="绑定表格" prop="btnTableKey">
+                <el-select
+                  v-model="btnGroupFormData.btnTableKey"
+                  placeholder="请选择表格"
+                  clearable
+                  filterable
+                >
+                  <el-option
+                    v-for="item in tableOptions"
+                    :key="item.fId"
+                    :label="item.dfName"
+                    :value="item.fId"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="绑定脚本" prop="btnScriptKey">
+                <el-select
+                  v-model="btnGroupFormData.btnScriptKey"
+                  placeholder="请选择绑定节点"
+                  clearable
+                  filterable
+                >
+                  <el-option
+                    v-for="item in scriptOptions"
+                    :key="item.fId"
+                    :label="item.dfName"
+                    :value="item.fId"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col
+              :span="24"
+              v-show="
+                btnGroupFormData.btnType == 3 || btnGroupFormData.btnType == 7
+              "
+            >
+              <el-form-item label="跳转路由" prop="btnParams">
+                <el-input
+                  v-model="btnGroupFormData.btnParams"
+                  placeholder="请输入跳转的路由地址"
+                  size="normal"
+                ></el-input>
+              </el-form-item>
+            </el-col>
+          </div>
+
+          <!-- <el-col :span="24">
+            <div class="btn-show-condition">
+              <span class="table-title">条件编辑</span>
+              <el-table :data="conditionBtnData" style="width: 100%">
+                <el-table-column label="序号" type="index" width="50">
+                </el-table-column>
+                <el-table-column prop="tableName" label="表名" width="150">
+                  <template slot-scope="scope">
+                    <el-select
+                      v-model="scope.row.tableName"
+                      @change="conditionTableChange(scope.row)"
+                      placeholder="请选择"
+                    >
+                      <el-option
+                        v-for="item in tableList"
+                        :key="item.tableName"
+                        :label="item.tableComment"
+                        :value="item.tableName"
+                      >
+                        <span style="float: left">{{ item.tableComment }}</span>
+                        <span
+                          style="float: right; color: #8492a6; font-size: 13px"
+                          >{{ item.tableName }}</span
+                        >
+                      </el-option>
+                    </el-select>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="fieldName" label="字段名" width="150">
+                  <template slot-scope="scope">
+                    <el-select
+                      v-model="scope.row.fieldName"
+                      placeholder="请选择"
+                    >
+                      <el-option
+                        v-for="item in scope.row.fieldList"
+                        :key="item.fieldName"
+                        :label="item.fieldDescription"
+                        :value="item.fieldName"
+                      >
+                        <span style="float: left">{{
+                          item.fieldDescription
+                        }}</span>
+                        <span
+                          style="float: right; color: #8492a6; font-size: 13px"
+                          >{{ item.fieldName }}</span
+                        >
+                      </el-option>
+                    </el-select>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="condition" label="条件" width="100">
+                  <template slot-scope="scope">
+                    <el-select
+                      v-model="scope.row.condition"
+                      placeholder="请选择"
+                    >
+                      <el-option
+                        v-for="item in conditionList"
+                        :key="item.value"
+                        :label="item.label"
+                        :value="item.value"
+                      >
+                      </el-option>
+                    </el-select>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="flagValue" label="参照值" width="100">
+                  <template slot-scope="scope">
+                    <el-input
+                      v-model="scope.row.flagValue"
+                      @input="
+                        scope.row.flagValue = scope.row.flagValue.replace(
+                          /^(0+)|[^\d]+/g,
+                          ''
+                        )
+                      "
+                    ></el-input>
+                  </template>
+                </el-table-column>
+                <el-table-column label="操作">
+                  <template slot-scope="scope">
+                    <el-button
+                      size="mini"
+                      type="danger"
+                      icon="el-icon-delete"
+                      @click="deleteConditionItem(scope.$index)"
+                      >删除
+                    </el-button>
+                  </template>
+                </el-table-column>
+              </el-table>
+              <el-button
+                type="primary"
+                class="inline-large-button mb10"
+                icon="el-icon-plus"
+                size="mini"
+                style="width: 100%"
+                @click="addConditionHandler"
+              >
+                添加条件
+              </el-button>
+            </div>
+          </el-col> -->
+        </el-row>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  listMenu,
+  getMenu,
+  delMenu,
+  addMenu,
+  updateMenu,
+} from "@/api/system/menu";
+import { listBtn, addBtn, getBtn, updateBtn, delBtn } from "@/api/system/btn";
+import { listForm } from "@/api/dragform/form";
+import { listProcess } from "@/api/bpmprocess/process";
+import { listTable } from "@/api/dragform/tableList";
+import { listScript } from "@/api/bpmprocess/process";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import IconSelect from "@/components/IconSelect";
+import { v4 as uuidv4 } from "uuid";
+
+export default {
+  name: "ExcuteBtnMange",
+  dicts: ["sys_show_hide", "sys_normal_disable"],
+  components: { Treeselect, IconSelect },
+  data() {
+    return {
+      // 记录编辑状态
+      editType: true, //true:新增   false:修改
+      // 遮罩层
+      loading: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 菜单表格树数据
+      btnList: [],
+      // 菜单树选项
+      menuOptions: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 是否展开,默认全部折叠
+      isExpandAll: false,
+      // 重新渲染表格状态
+      refreshTable: true,
+      // 查询参数
+      queryParams: {
+        btnParentId: 0,
+        btnGroupName: "",
+        pageNum: 1,
+        pageSize: 10,
+      },
+      // 分页数据
+      total: 0,
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        menuName: [
+          { required: true, message: "菜单名称不能为空", trigger: "blur" },
+        ],
+        orderNum: [
+          { required: true, message: "菜单顺序不能为空", trigger: "blur" },
+        ],
+        path: [
+          { required: true, message: "路由地址不能为空", trigger: "blur" },
+        ],
+      },
+      // 按钮组表单数据
+      btnGroupFormData: {
+        btnGroupName: "", //按钮组名
+        btnParentId: "", //父节点id
+        btnName: "", //按钮显示的文字
+        btnIcon: "", //按钮图标
+        btnType: 6, //0:操作按钮,1,其他,2表单,3内链,4流程,5脚本, 6,目录, 7:外链
+        btnFormKey: "", //表单唯一标识
+        btnProcessKey: "", //流程唯一标识
+        btnTableKey: "", //表格唯一标识
+        btnScriptKey: "", //脚本唯一标识
+        btnShowCondition: "", //按钮显示条件
+        btnParams: "", //操作参数
+        btnHasPermi: "", //权限字符
+        btnSort: 0, //按钮顺序
+        btnKey: "",
+      },
+      conditionBtnData: [],
+      btnTypeOptions: [
+        // {
+        //   value: 0,
+        //   label: "操作按钮",
+        // },
+        // {
+        //   value: 1,
+        //   label: "其它",
+        // },
+        // {
+        //   value: 2,
+        //   label: "表单",
+        // },
+        // {
+        //   value: 3,
+        //   label: "内链",
+        // },
+        // {
+        //   value: 4,
+        //   label: "流程",
+        // },
+        // {
+        //   value: 5,
+        //   label: "脚本",
+        // },
+        {
+          value: "6",
+          label: "目录",
+        },
+        {
+          value: "7",
+          label: "外链",
+        },
+        {
+          value: "3",
+          label: "内链",
+        },
+        {
+          value: "8",
+          label: "修改",
+        },
+        {
+          value: "9",
+          label: "删除",
+        },
+      ],
+      formOptions: [],
+      tableOptions: [],
+      processOptions: [],
+      scriptOptions: [],
+    };
+  },
+  created() {
+    this.getList();
+    this.initFormSubData();
+  },
+  methods: {
+    // 选择图标
+    selected(name) {
+      this.btnGroupFormData.btnIcon = name;
+    },
+    /** 查询菜单列表 */
+    getList() {
+      this.loading = true;
+
+      listBtn(this.queryParams).then((response) => {
+        this.btnList = response.rows;
+        console.log("btnList", this.btnList);
+        this.loading = false;
+      });
+    },
+    /** 转换菜单数据结构 */
+    normalizer(node) {
+      // if (node.children && !node.children.length) {
+      //   delete node.children;
+      // }
+      return {
+        id: node.id,
+        label: node.btnName,
+        children: node.children,
+      };
+    },
+    /** 查询菜单下拉树结构 */
+    getTreeselect() {
+      listBtn({ ...this.queryParams, isEnablePaging: false }).then(
+        (response) => {
+          this.menuOptions = [];
+          const btnTemp = {
+            id: 0,
+            btnGroupName: "新建按钮组",
+            btnName: "新建按钮组",
+            children: [],
+            btnType: 6,
+          };
+
+          let _this = this;
+          let res = response.rows.filter((node) => _this.getAllMenuList(node));
+          btnTemp.children.push(...res);
+          console.log(btnTemp);
+
+          this.menuOptions.push(btnTemp);
+        }
+      );
+    },
+    // 只保留目录
+    getAllMenuList(node) {
+      // 如果当前节点的btnType等于6,则保留该节点,否则删除该节点
+      if (node.btnType == 6) {
+        if (Array.isArray(node.children) && node.children.length != 0) {
+          // 递归遍历子节点,并删除所有btnType不等于6的子节点
+          let _this = this;
+          node.children = node.children.filter((child) =>
+            _this.getAllMenuList(child)
+          );
+        }
+        return node;
+      } else {
+        return false;
+      }
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.btnGroupFormData = {
+        btnGroupName: "", //按钮组名
+        btnParentId: "", //父节点id
+        btnName: "", //按钮显示的文字
+        btnIcon: "", //按钮图标
+        btnType: "6", //0:操作按钮,1,其他,2表单,3跳转,4流程,5脚本
+        btnFormKey: "", //表单唯一标识
+        btnProcessKey: "", //流程唯一标识
+        btnTableKey: "", //表格唯一标识
+        btnScriptKey: "", //脚本唯一标识
+        btnShowCondition: "", //按钮显示条件
+        btnParams: "", //操作参数
+        btnHasPermi: "", //权限字符
+        btnSort: 0, //按钮顺序
+        btnKey: "",
+      };
+      this.resetForm("btnGroupFormRef");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    /** 新增按钮操作 */
+    handleAdd(row) {
+      this.title = "新增按钮";
+      this.reset();
+      this.getTreeselect();
+
+      this.editType = row ? true : false;
+      if (row != null && row.id) {
+        //在已知节点下新增
+        this.btnGroupFormData.btnParentId = row.id;
+      } else {
+        this.btnGroupFormData.btnParentId = 0;
+      }
+      console.log(this.btnGroupFormData.btnParentId);
+      this.open = true;
+      this.title = "添加按钮组";
+    },
+    /** 展开/折叠操作 */
+    toggleExpandAll() {
+      this.refreshTable = false;
+      this.isExpandAll = !this.isExpandAll;
+      this.$nextTick(() => {
+        this.refreshTable = true;
+      });
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      this.getTreeselect();
+      this.editType = false;
+      getBtn(row.id).then((response) => {
+        this.btnGroupFormData = response.data;
+        this.open = true;
+        this.title = "修改菜单";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["btnGroupFormRef"].validate(async (valid) => {
+        if (valid) {
+          if (this.editType) {
+            // 新增按钮组
+            this.btnGroupFormData.btnKey = uuidv4();
+            let res = await addBtn(this.btnGroupFormData);
+            if (res.code == 200) {
+              this.$message.success("添加成功");
+            } else {
+              this.$message.error("网络异常,请稍后添加");
+            }
+          } else {
+            // 修改按钮组
+            let res = await updateBtn(this.btnGroupFormData);
+            if (res.code == 200) {
+              this.$message.success("修改成功");
+            } else {
+              this.$message.error("网络异常,请稍后修改");
+            }
+          }
+
+          this.getList();
+          this.open = false;
+        }
+      });
+    },
+    // 更新路由
+    reloadRouter() {
+      this.$store.dispatch("GenerateRoutes").then((accessRoutes) => {
+        this.$router.addRoutes(accessRoutes); // 动态添加可访问路由表
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      this.$modal
+        .confirm('是否确认删除名称为"' + row.btnGroupName + '"的数据项?')
+        .then(function () {
+          return delBtn(row.id);
+        })
+        .then(() => {
+          this.getList();
+          this.$modal.msgSuccess("删除成功");
+        })
+        .catch(() => {});
+    },
+    // 初始化表单辅助数据
+    async initFormSubData() {
+      try {
+        //获取表单选项数据
+        let formRes = await listForm({ isEnablePaging: false });
+        if (formRes.code == 200) {
+          this.formOptions = formRes.rows;
+        } else {
+          this.$message.error("网络异常请稍后再试");
+        }
+        // 获取流程选项数据
+        let processRes = await listProcess({ isEnablePaging: false });
+        if (processRes.code == 200) {
+          this.processOptions = processRes.rows;
+        } else {
+          this.$message.error("网络异常请稍后再试");
+        }
+        // 获取表格选项数据
+        let TableRes = await listTable({ isEnablePaging: false });
+        if (TableRes.code == 200) {
+          this.tableOptions = TableRes.rows;
+        } else {
+          this.$message.error("网络异常请稍后再试");
+        }
+        // 获取脚本选项数据
+        let scriptRes = await listScript({ isEnablePaging: false });
+        if (scriptRes.code == 200) {
+          this.scriptOptions = scriptRes.rows;
+        } else {
+          this.$message.error("网络异常请稍后再试");
+        }
+      } catch (error) {}
+    },
+    // 添加按钮条件
+    addConditionHandler() {
+      this.conditionBtnData.push({
+        tableName: "",
+        fieldName: "",
+        condition: 1, //1:> 2:< 3:= 4:>= 5:<=
+        flagValue: 0,
+        fieldList: [],
+      });
+    },
+  },
+};
+</script>
+<style scoped lang="scss" scoped>
+/* #app .sidebar-container .submenu-title-noDropdown:hover, #app .sidebar-container .el-submenu__title:hover {
+    background-color: rgba(0, 0, 0, 0.06) !important;
+}  */
+.submenu-title-noDropdown:hover {
+  background-color: linear-gradient(to right, blue, rgb(69, 118, 225));
+}
+</style>

+ 15 - 2
ruoyi-ui/src/views/system/fromModel/index.vue

@@ -77,12 +77,25 @@ export default {
       //
       var editorHtmlJson =
         codeHtmlFront + JSON.stringify(jsonData) + codeHtmlLast;
+      let { list } = jsonData;
+      let needSqlArr = ["select", "treeSelect", "cascader"];
+      let selectArr = list.filter((item) => {
+        return needSqlArr.includes(item.type) && item.options.dynamic;
+      });
+      let formSQL = {};
+      selectArr.forEach((item) => {
+        // formSQL = {
+        //   ...formSQL,
+        //   ...item.options.sqlData,
+        // };
+        Object.assign(formSQL, item.options.sqlData);
+      });
+
       let {
         formName,
         nickFormName,
         mainTableName,
         formDescription,
-        formSQL,
         formNodeId,
       } = jsonData.config;
       if (!this.fid) {
@@ -112,7 +125,7 @@ export default {
           fId: this.fid,
           dfTableName: mainTableName,
           dfNotes: formDescription,
-          dfFormSql: formSQL,
+          dfFormSql: JSON.stringify(formSQL),
           dfNodeId: formNodeId,
         }).then((res) => {
           console.log(res);

+ 18 - 0
ruoyi-ui/src/views/system/selectOptionsMange/index.vue

@@ -0,0 +1,18 @@
+<template>
+  <div class="app-container">选项数据管理</div>
+</template>
+
+<script>
+export default {
+  name: "SelectOptionsMange",
+  props: [],
+  components: {},
+  data() {
+    return {};
+  },
+  computed: {},
+  methods: {},
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 72 - 15
ruoyi-ui/src/views/tableMange/components/StyleFormPanel.vue

@@ -52,40 +52,40 @@
         ref="styleFormDataRef"
         :model="styleFormData"
         label-width="100px"
+        :rules="styleFormRules"
       >
-        <el-form-item label="样式名">
+        <el-form-item label="样式名" prop="styleName">
           <el-input v-model="styleFormData.styleName"></el-input>
         </el-form-item>
-        <el-form-item label="样式描述">
+        <el-form-item label="样式描述" prop="styleDescription">
           <el-input
             type="textarea"
             v-model="styleFormData.styleDescription"
           ></el-input>
         </el-form-item>
-        <el-form-item label="样式类型">
+        <el-form-item label="样式类型" prop="styleType">
           <el-radio-group v-model="styleFormData.styleType" size="small">
             <el-radio-button :label="0">行样式</el-radio-button>
             <el-radio-button :label="1">字段样式</el-radio-button>
             <el-radio-button :label="2">字典样式</el-radio-button>
           </el-radio-group>
         </el-form-item>
-        <template v-if="styleFormData.styleType == 0">
-          <el-form-item label="背景颜色">
+        <div v-show="styleFormData.styleType == 0">
+          <el-form-item label="背景颜色" prop="rowBgColor">
             <input
               type="color"
               :value="styleFormData.rowBgColor"
               @input="selectColors($event, 'rowBgColor')"
             />
           </el-form-item>
-        </template>
-        <template v-else-if="styleFormData.styleType == 1">
-          <el-form-item label="样式生效字段">
+        </div>
+        <div v-show="styleFormData.styleType == 1">
+          <el-form-item label="样式生效字段" prop="styleTable">
             <el-col :span="10">
               <el-select
                 v-model="styleFormData.styleTable"
                 value-key=""
                 placeholder="请选择表"
-                clearable
                 filterable
               >
                 <el-option
@@ -106,7 +106,6 @@
                 v-model="styleFormData.styleField"
                 value-key=""
                 placeholder="请选择字段"
-                clearable
                 filterable
               >
                 <el-option
@@ -172,9 +171,9 @@
               >
             </el-form-item>
           </template>
-        </template>
-        <template v-else>
-          <el-form-item label="字典生效字段" size="normal">
+        </div>
+        <div v-show="styleFormData.styleType == 2">
+          <el-form-item label="字典生效字段" size="normal" prop="styleTable">
             <el-col :span="10">
               <el-select
                 v-model="styleFormData.styleTable"
@@ -233,8 +232,8 @@
               </el-option>
             </el-select>
           </el-form-item>
-        </template>
-        <div v-if="styleFormData.styleType != 2" class="condition-table-wrap">
+        </div>
+        <div v-show="styleFormData.styleType != 2" class="condition-table-wrap">
           <span class="table-title">条件编辑</span>
           <el-table :data="conditionTableData" style="width: 100%">
             <el-table-column label="序号" type="index" width="50">
@@ -380,6 +379,14 @@ export default {
         tagType: "",
         conditionTableStr: "",
       },
+      styleFormRules: {
+        styleName: [
+          { required: true, message: "请输入样式名", trigger: "blur" },
+        ],
+        styleTable: [
+          { validator: this.styleFieldValidator, trigger: "change" },
+        ],
+      },
       conditionTableData: [
         // {
         //   tableName: "",
@@ -526,6 +533,12 @@ export default {
     saveStyleFormHandler() {
       this.$refs.styleFormDataRef.validate((valid) => {
         if (valid) {
+          // 校验样式生效条件的表格数据
+          let validateRes = this.validateCondition();
+          if (!validateRes.flag) {
+            this.$message.error(validateRes.msg);
+            return;
+          }
           let tempConditionTableData = this.conditionTableData.map((item) => ({
             tableName: item.tableName,
             fieldName: item.fieldName,
@@ -626,6 +639,50 @@ export default {
       });
       return res;
     },
+
+    // 获取样式条件中的表名和字段
+    getStyleTableField() {
+      let res = [];
+      this.styleTableData
+        .filter((item) => item.styleType != 2)
+        .map((item) => {
+          let tableList = JSON.parse(item.conditionTableStr);
+          tableList.forEach((val) => {
+            res.push(val.tableName + "." + val.fieldName);
+          });
+        });
+      return res;
+    },
+
+    // 样式生效字段的表格验证
+    styleFieldValidator(rule, value, callBack) {
+      if (this.styleFormData.styleType == 0) return callBack();
+      let { styleTable, styleField } = this.styleFormData;
+      if (!styleTable) return callBack(new Error("请选择表格"));
+      if (!styleField) return callBack(new Error("请选择字段"));
+      callBack();
+    },
+
+    // 校验样式生效条件
+    validateCondition() {
+      let { styleType } = this.styleFormData;
+      if (styleType == 2) return { flag: true };
+      let res = {
+        flag: true,
+      };
+      try {
+        this.conditionTableData.forEach((item) => {
+          if (!item.tableName || !item.fieldName) {
+            res.flag = false;
+            res.msg = "请完善表格数据(表格名/字段名)";
+            throw new Error("validate error");
+          }
+        });
+      } catch (error) {
+        if (error != "validate error") console.log(error);
+      }
+      return res;
+    },
   },
   async mounted() {
     let res = await listType(this.addDateRange({ isEnablePaging: false }, []));

+ 60 - 6
ruoyi-ui/src/views/tableMange/index.vue

@@ -273,6 +273,21 @@
                     ></el-option>
                   </el-select>
                 </el-form-item>
+                <el-form-item label="操作列按钮" prop="btnGroupList">
+                  <el-select
+                    v-model="formData.btnGroupList"
+                    placeholder="请选择按钮组"
+                    clearable
+                    multiple
+                  >
+                    <el-option
+                      v-for="val in btnGroupOptions"
+                      :key="val.btnKey"
+                      :label="val.btnGroupName"
+                      :value="val.btnKey"
+                    ></el-option>
+                  </el-select>
+                </el-form-item>
                 <el-form-item label="排序依赖字段">
                   <el-select
                     v-model="formData.orderByColumn"
@@ -703,7 +718,7 @@ import Sortable from "sortablejs";
 import Treeselect from "@riophae/vue-treeselect";
 import "@riophae/vue-treeselect/dist/vue-treeselect.css";
 import { v4 as uuidv4 } from "uuid";
-
+import { listBtn } from "@/api/system/btn";
 import StyleFormPanel from "./components/StyleFormPanel.vue";
 export default {
   name: "tableMange",
@@ -807,6 +822,7 @@ export default {
         orderByColumn: "",
         isAsc: false,
         primaryKey: "",
+        btnGroupList: [],
       },
       rules: {
         menuName: [
@@ -860,6 +876,9 @@ export default {
 
       // 样式编辑tab数据
       dragTableStyleList: [],
+
+      //操作列按钮组数据
+      btnGroupOptions: [],
     };
   },
   computed: {
@@ -1232,9 +1251,10 @@ export default {
         let temp = tableFieldList[i];
         if (temp.isShow) {
           let tempArr = prefix + temp.tableName + "." + temp.fieldName;
-          if (temp.isChildren) {
-            tempArr += asOrSpace + temp.tableName + "_" + temp.fieldName;
-          }
+          // 给主表也加上表名前缀
+          // if (temp.isChildren) {
+          tempArr += asOrSpace + temp.tableName + "_" + temp.fieldName;
+          // }
           fieldArr.push(tempArr);
         }
         if (temp.relationTable && temp.relationFieldName && temp.relationType) {
@@ -1279,6 +1299,7 @@ export default {
     getSQLStr() {
       let prefix = "{DBNAME}.";
       let sqlType = this.databaseType; //数据库类型
+      let asOrSpace = sqlType == "oracle" ? " " : " AS ";
       // let sqlType = "oracle";
       let sql = "";
       // mysql
@@ -1294,8 +1315,13 @@ export default {
       // if (discriISEmpty) {
       //   return false;
       // }
+      let styleFieldList = this.$refs.styleTableRef.getStyleTableField();
+      styleFieldList = styleFieldList.map((item) => {
+        return `${prefix}${item}${asOrSpace}${item.replace(".", "_")}`;
+      });
+      let set = new Set([...fieldNameArr, ...styleFieldList]);
+      fieldNameArr = [...set];
       let isNeedUsername = sqlType == "oracle" ? this.username + "." : "";
-      let asOrSpace = sqlType == "oracle" ? " " : " AS ";
       sql +=
         fieldNameArr.join(",") +
         " FROM " +
@@ -1378,7 +1404,8 @@ export default {
           tempFieldName = temp.tableName + "_" + temp.fieldName;
           exportFieldName = temp.tableName + "@" + temp.fieldName;
         } else {
-          tempFieldName = temp.fieldName;
+          // tempFieldName = temp.fieldName;
+          tempFieldName = temp.tableName + "_" + temp.fieldName;
           exportFieldName = temp.fieldName;
         }
         if (temp.isShow) {
@@ -1538,7 +1565,10 @@ export default {
           //   this.$message.error("请补全关联条件");
           //   return;
           // }
+<<<<<<< HEAD
           // console.log("123", columns);
+=======
+>>>>>>> 0b02a879572de5f5533cacbfea997e10bc594762
           this.uuid = uuidv4();
           this.tableKey = uuidv4();
           // 表单
@@ -1642,6 +1672,9 @@ export default {
               data.menuId = this.menuId;
               data.sqlKey = this.editData.sqlKey;
               data.tableKey = this.editData.tableKey;
+              data.dragTableBtnRelevanceList = this.getBtnMapList(
+                data.tableKey
+              );
               res = await editTable(data);
               this.dragTableStatisticList.forEach((item) => {
                 item.tableKey = this.editData.tableKey;
@@ -1655,6 +1688,9 @@ export default {
               });
             } else {
               data.menuId = result.data;
+              data.dragTableBtnRelevanceList = this.getBtnMapList(
+                data.tableKey
+              );
               res = await addDragTable(data);
 
               this.dragTableStatisticList.forEach((item) => {
@@ -1698,6 +1734,15 @@ export default {
         }
       });
     },
+    getBtnMapList(tableKey) {
+      let res = this.formData.btnGroupList.map((item) => {
+        return {
+          tableKey,
+          btnKey: item,
+        };
+      });
+      return res;
+    },
     // 修改表格回显数据
     async initTableData(tId) {
       let res = await getTableInfo(tId);
@@ -1714,6 +1759,7 @@ export default {
           isAsc,
           primaryKey,
           menuName,
+          btnGroupList,
         } = echoData.formData;
         Object.assign(this.formData, {
           menuName,
@@ -1722,6 +1768,7 @@ export default {
           orderByColumn,
           isAsc,
           primaryKey,
+          btnGroupList,
         });
         this.formData.routePath = this.getParentMenuId(
           res.data.menuId,
@@ -1845,11 +1892,18 @@ export default {
     getTableCommont(tableName, tableList) {
       return tableList.find((item) => item.tableName == tableName).tableComment;
     },
+
+    // 获取按钮组数据
+    async getBtnList() {
+      let res = await listBtn({ isEnablePaging: false, btnParentId: 0 });
+      this.btnGroupOptions = res.rows;
+    },
   },
   created() {},
   async mounted() {
     this.getAllTable();
     this.initDragTable();
+    this.getBtnList();
     await this.getMenuList();
     if (this.$route.query.tId) {
       this.tId = this.$route.query.tId;

+ 465 - 0
ruoyi-ui/src/views/tableMange/styleMange/index.vue

@@ -0,0 +1,465 @@
+<template>
+  <div class="app-container">
+    <el-form
+      :model="queryParams"
+      ref="queryForm"
+      size="small"
+      :inline="true"
+      v-show="showSearch"
+      label-width="68px"
+    >
+      <el-form-item label="样式key" prop="styleKey">
+        <el-input
+          v-model="queryParams.styleKey"
+          placeholder="请输入样式key"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="样式名称" prop="styleName">
+        <el-input
+          v-model="queryParams.styleName"
+          placeholder="请输入样式名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="样式描述" prop="styleDescription">
+        <el-input
+          v-model="queryParams.styleDescription"
+          placeholder="请输入样式描述"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="创建者ID" prop="createById">
+        <el-input
+          v-model="queryParams.createById"
+          placeholder="请输入创建者ID"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="更新者ID" prop="updateById">
+        <el-input
+          v-model="queryParams.updateById"
+          placeholder="请输入更新者ID"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
+          >搜索</el-button
+        >
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+          >重置</el-button
+        >
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['system:style:add']"
+          >新增</el-button
+        >
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['system:style:edit']"
+          >修改</el-button
+        >
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['system:style:remove']"
+          >删除</el-button
+        >
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['system:style:export']"
+          >导出</el-button
+        >
+      </el-col>
+      <right-toolbar
+        :showSearch.sync="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
+    </el-row>
+
+    <el-table
+      v-loading="loading"
+      stripe
+      :data="styleList"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="编号" align="center" prop="id" />
+      <!-- <el-table-column label="样式key" align="center" prop="styleKey" /> -->
+      <el-table-column label="样式名称" align="center" prop="styleName" />
+      <el-table-column label="样式类型" align="center" prop="styleType">
+        <template slot-scope="scope">
+          {{ theGetDictLabel(scope.row.styleType, dict.type.table_style_type) }}
+        </template>
+      </el-table-column>
+      <!-- <el-table-column label="样式代码" align="center" prop="styleCode" /> -->
+      <el-table-column
+        label="样式描述"
+        align="center"
+        prop="styleDescription"
+      />
+      <!-- <el-table-column label="样式状态" align="center" prop="styleStatus" /> -->
+      <!-- <el-table-column label="创建者ID" align="center" prop="createById" />
+      <el-table-column label="更新者ID" align="center" prop="updateById" /> -->
+      <el-table-column
+        label="操作"
+        align="center"
+        class-name="small-padding fixed-width"
+      >
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['system:style:edit']"
+            >修改</el-button
+          >
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['system:style:remove']"
+            >删除</el-button
+          >
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改动态格样式模板对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <!-- <el-form-item label="样式key" prop="styleKey">
+          <el-input v-model="form.styleKey" placeholder="请输入样式key" />
+        </el-form-item> -->
+        <el-form-item label="样式名称" prop="styleName">
+          <el-input v-model="form.styleName" placeholder="请输入样式名称" />
+        </el-form-item>
+        <el-form-item label="样式类型" prop="styleType">
+          <el-select
+            v-model="form.styleType"
+            placeholder="请选择样式类型"
+            filterable
+          >
+            <el-option
+              v-for="item in dict.type.table_style_type"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="样式代码" prop="styleCode">
+          <el-input
+            v-model="form.styleCode"
+            type="textarea"
+            placeholder="请输入内容"
+          />
+          <!-- <el-button icon="el-icon-edit" @click="drawerOpenHandler"></el-button> -->
+        </el-form-item>
+        <el-form-item label="样式描述" prop="styleDescription">
+          <el-input
+            v-model="form.styleDescription"
+            placeholder="请输入样式描述"
+          />
+        </el-form-item>
+        <!-- <el-form-item label="删除标志" prop="delFlag">
+          <el-input v-model="form.delFlag" placeholder="请输入删除标志" />
+        </el-form-item>
+        <el-form-item label="创建者ID" prop="createById">
+          <el-input v-model="form.createById" placeholder="请输入创建者ID" />
+        </el-form-item>
+        <el-form-item label="更新者ID" prop="updateById">
+          <el-input v-model="form.updateById" placeholder="请输入更新者ID" />
+        </el-form-item> -->
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+    <el-drawer
+      :visible.sync="drawer"
+      direction="rtl"
+      :before-close="drawerHandleClose"
+      :with-header="false"
+    >
+      <div ref="container" class="monaco-container"></div>
+    </el-drawer>
+  </div>
+</template>
+
+<script>
+import {
+  listStyle,
+  getStyle,
+  delStyle,
+  addStyle,
+  updateStyle,
+} from "@/api/system/style";
+import { getDictLabel } from "@/utils/other";
+import * as monaco from "monaco-editor";
+
+export default {
+  name: "StyleMange",
+  dicts: ["table_style_type"],
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 动态格样式模板表格数据
+      styleList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        styleKey: null,
+        styleName: null,
+        styleType: null,
+        styleCode: null,
+        styleDescription: null,
+        styleStatus: null,
+        createById: null,
+        updateById: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        styleName: [
+          { required: true, message: "请输入样式名", trigger: "blur" },
+        ],
+        styleType: [
+          { required: true, message: "请选择样式类型", trigger: "change" },
+        ],
+        styleCode: [
+          { required: true, message: "请输入样式代码", trigger: "blur" },
+        ],
+        styleDescription: [
+          { required: true, message: "请输入样式样式描述", trigger: "blur" },
+        ],
+      },
+      // 代码编辑器
+      monacoEditor: null,
+      drawer: false,
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询动态格样式模板列表 */
+    getList() {
+      this.loading = true;
+      listStyle(this.queryParams).then((response) => {
+        this.styleList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        styleKey: null,
+        styleName: null,
+        styleType: null,
+        styleCode: null,
+        styleDescription: null,
+        styleStatus: null,
+        delFlag: null,
+        createBy: null,
+        createById: null,
+        createTime: null,
+        updateBy: null,
+        updateById: null,
+        updateTime: null,
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map((item) => item.id);
+      this.single = selection.length !== 1;
+      this.multiple = !selection.length;
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加动态格样式模板";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids;
+      getStyle(id).then((response) => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改动态格样式模板";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate((valid) => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateStyle(this.form).then((response) => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addStyle(this.form).then((response) => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal
+        .confirm('是否确认删除动态格样式模板编号为"' + ids + '"的数据项?')
+        .then(function () {
+          return delStyle(ids);
+        })
+        .then(() => {
+          this.getList();
+          this.$modal.msgSuccess("删除成功");
+        })
+        .catch(() => {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download(
+        "system/style/export",
+        {
+          ...this.queryParams,
+        },
+        `style_${new Date().getTime()}.xlsx`
+      );
+    },
+    theGetDictLabel(value, dictList) {
+      return getDictLabel(value, dictList);
+    },
+    // 抽屉打开回调
+    drawerOpenHandler() {
+      this.monacoEditor?.dispose();
+      this.drawer = true;
+      this.$nextTick(() => {
+        this.monacoEditor = monaco.editor.create(this.$refs.container, {
+          value: this.form.styleCode,
+          language: "css",
+          theme: "vs-dark", // 编辑器主题:vs, hc-black, or vs-dark,更多选择详见官网
+          contextmenu: false, // 禁用右键菜单
+          editorOptions: this.editorOptions, // 同codes
+        });
+      });
+    },
+    // 抽屉关闭前回调
+    drawerHandleClose(done) {
+      this.$confirm("即将关闭编辑器,是否保存代码?")
+        .then(
+          (val) => {
+            this.form.styleCode = this.monacoEditor?.getValue();
+            // this.drawer = false;
+            done();
+          },
+          (res) => {
+            // this.drawer = false;
+            done();
+          }
+        )
+        .catch(() => {});
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.monaco-container {
+  width: 100%;
+  height: 100%;
+}
+</style>

+ 74 - 0
ruoyi-ui/src/views/tablelist/commonTable/BtnMenu.vue

@@ -0,0 +1,74 @@
+<template>
+  <div class="myDiv">
+    <el-dropdown trigger="click" :hide-on-click="false">
+      <span class="el-dropdown-link">
+        <el-button v-if="btnObj.btnParentId == 0" type="warning"
+          ><span
+            ><svg-icon
+              class="pre-icon"
+              v-if="btnObj.btnIcon"
+              slot="prefix"
+              :icon-class="btnObj.btnIcon" />{{ btnObj.btnName }}
+            <i class="el-icon-arrow-down el-icon--right"></i></span
+        ></el-button>
+        <span v-else>
+          <span
+            ><svg-icon
+              class="pre-icon"
+              v-if="btnObj.btnIcon"
+              slot="prefix"
+              :icon-class="btnObj.btnIcon" />{{ btnObj.btnName }}
+            <i class="el-icon-arrow-down el-icon--right"></i
+          ></span>
+        </span>
+      </span>
+      <el-dropdown-menu slot="dropdown">
+        <template v-for="item in btnObj.children">
+          <el-dropdown-item v-if="item.children.length == 0"
+            ><span @click="clickHandler(item, row)"
+              ><svg-icon
+                v-if="item.btnIcon"
+                class="pre-icon"
+                slot="prefix"
+                :icon-class="item.btnIcon"
+              />{{ item.btnName }}</span
+            ></el-dropdown-item
+          >
+          <el-dropdown-item v-else>
+            <Menu
+              :listAll="item"
+              :row="row"
+              @excuteHandler="clickHandler"
+            ></Menu>
+          </el-dropdown-item>
+        </template>
+      </el-dropdown-menu>
+    </el-dropdown>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "Menu",
+  components: {},
+  props: ["listAll", "row"],
+  data() {
+    return {};
+  },
+  computed: {
+    btnObj() {
+      return this.listAll;
+    },
+  },
+  methods: {
+    clickHandler(btnData, row) {
+      this.$emit("excuteHandler", btnData, row);
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.pre-icon {
+  margin-right: 5px;
+}
+</style>

+ 346 - 57
ruoyi-ui/src/views/tablelist/commonTable/listInfo.vue

@@ -41,7 +41,7 @@
             :underline="false"
             style="font-size: 12px; vertical-align: baseline"
             @click="importTemplate"
-          >下载模板
+            >下载模板
           </el-link>
         </div>
       </el-upload>
@@ -65,7 +65,7 @@
           icon="el-icon-plus"
           size="mini"
           @click="handleAdd"
-        >新增
+          >新增
         </el-button>
       </el-col>
       <el-col :span="1.5" v-if="false">
@@ -76,7 +76,7 @@
           size="mini"
           :disabled="single"
           @click="handleUpdate"
-        >修改
+          >修改
         </el-button>
       </el-col>
       <el-col :span="1.5">
@@ -87,7 +87,7 @@
           size="mini"
           :disabled="multiple"
           @click="handleDelete"
-        >删除
+          >删除
         </el-button>
       </el-col>
       <el-col :span="1.5">
@@ -96,7 +96,7 @@
           icon="el-icon-upload2"
           size="mini"
           @click="upload.open = true"
-        >导入
+          >导入
         </el-button>
       </el-col>
       <el-col :span="1.5">
@@ -106,7 +106,7 @@
           icon="el-icon-download"
           size="mini"
           @click="handleExport"
-        >导出
+          >导出
         </el-button>
       </el-col>
       <right-toolbar
@@ -121,13 +121,15 @@
       :data="tableList"
       @selection-change="handleSelectionChange"
       row-key="id"
+      :cell-style="cellStyle"
     >
       <el-table-column
         type="selection"
         width="55"
         reserve-selection
         align="center"
-      />
+      >
+      </el-table-column>
       <!-- <span v-for="(key, val) in columns" :key="key">
         <el-table-column :label="key" align="center" :prop="val" />
       </span> -->
@@ -137,38 +139,88 @@
         :label="item.value"
         align="center"
         :prop="item.key"
-      />
+      >
+        <template slot-scope="scope">
+          <!-- 存在字段样式或字典样式 -->
+          <template
+            v-if="
+              scope.row.styleFieldObj != undefined &&
+              scope.row.styleFieldObj[item.key]
+            "
+          >
+            <!-- 字段样式 -->
+            <template v-if="scope.row.styleFieldObj[item.key].styleType == 1">
+              <!-- 一般字体样式 -->
+              <template
+                v-if="scope.row.styleFieldObj[item.key].fieldStyleType == 0"
+              >
+                <span
+                  :style="`color:${
+                    scope.row.styleFieldObj[item.key].fontColor
+                  }`"
+                  >{{ scope.row[item.key] }}</span
+                >
+              </template>
+              <!-- 标签字体样式 -->
+              <template
+                v-else-if="
+                  scope.row.styleFieldObj[item.key].fieldStyleType == 1
+                "
+              >
+                <el-tag
+                  :type="scope.row.styleFieldObj[item.key].tagType"
+                  :effect="
+                    scope.row.styleFieldObj[item.key].isTagFullBg
+                      ? 'dark'
+                      : 'light'
+                  "
+                >
+                  {{ scope.row[item.key] }}
+                </el-tag>
+              </template>
+            </template>
+            <!-- 字典样式 -->
+            <template
+              v-else-if="scope.row.styleFieldObj[item.key].styleType == 2"
+            >
+              <span
+                v-if="
+                  scope.row.styleFieldObj[item.key].listClass == '' ||
+                  scope.row.styleFieldObj[item.key].listClass == 'default'
+                "
+                >{{ scope.row.styleFieldObj[item.key].dictLabel }}</span
+              >
+              <el-tag
+                v-else
+                :type="
+                  scope.row.styleFieldObj[item.key].listClass == 'primary'
+                    ? ''
+                    : scope.row.styleFieldObj[item.key].listClass
+                "
+                >{{ scope.row.styleFieldObj[item.key].dictLabel }}</el-tag
+              >
+            </template>
+          </template>
+          <!-- 显示默认值 -->
+          <template v-else>
+            {{ scope.row[item.key] }}
+          </template>
+        </template>
+      </el-table-column>
       <el-table-column
+        v-show="isShowExcuteCol"
         label="操作"
         align="center"
         class-name="small-padding fixed-width"
       >
         <template slot-scope="scope">
-          <el-dropdown>
-            <el-button type="warning" plain size="small">
-              处理<i class="el-icon-arrow-down el-icon--right"></i>
-            </el-button>
-            <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item>
-                <el-button
-                  size="mini"
-                  type="text"
-                  icon="el-icon-edit"
-                  @click="handleUpdate(scope.row)"
-                >修改
-                </el-button>
-              </el-dropdown-item>
-              <el-dropdown-item>
-                <el-button
-                  size="mini"
-                  type="text"
-                  icon="el-icon-delete"
-                  @click="handleDelete(scope.row)"
-                >删除
-                </el-button>
-              </el-dropdown-item>
-            </el-dropdown-menu>
-          </el-dropdown>
+          <Menu
+            :row="scope.row"
+            v-for="btnObj in excuteBtnArr"
+            :key="btnObj.id"
+            :listAll="btnObj"
+            @excuteHandler="excuteHandler"
+          ></Menu>
         </template>
       </el-table-column>
     </el-table>
@@ -192,8 +244,10 @@
       <k-form-build
         class="formBuild"
         ref="addFromRef"
+        :dynamicData="dynamicData"
         :defaultValue="defaultValue"
         @submit="tempSubBtn"
+        @change="formChangeHandler"
         :value="jsonData"
       />
       <div slot="footer" class="dialog-footer">
@@ -212,16 +266,18 @@ import {
   getInfoBySqlKey,
   addTableData,
   batchEdit,
-  getStatisticList
+  getStatisticList,
 } from "@/api/tablelist/commonTable";
-import {getToken} from "@/utils/auth";
+import { listData } from "@/api/system/tenant/data";
+import { getToken } from "@/utils/auth";
 import Queryfrom from "@/views/tablelist/commonTable/queryfrom.vue";
-import {camelCase} from "@/utils";
-import {inputDisableComplete} from "@/utils/other";
+import { camelCase } from "@/utils";
+import { inputDisableComplete } from "@/utils/other";
+import Menu from "./BtnMenu.vue";
 
 export default {
   name: "listInfo",
-  components: {Queryfrom},
+  components: { Queryfrom, Menu },
   data() {
     return {
       // 遮罩层
@@ -260,7 +316,7 @@ export default {
         // 是否更新已经存在的数据
         updateSupport: 0,
         // 设置上传的请求头部
-        headers: {Authorization: "Bearer " + getToken()},
+        headers: { Authorization: "Bearer " + getToken() },
         // 上传的地址
         url: process.env.VUE_APP_BASE_API3 + "common/uploadData",
       },
@@ -302,6 +358,14 @@ export default {
       defaultValue: {},
       // 统计card
       statisticList: [],
+      // 样式表
+      styleList: [],
+      // 字典样式对象
+      dictStyleObj: {},
+      // 操作列 按钮数据
+      excuteBtnArr: [],
+      // 下拉框动态数据
+      dynamicData: {},
     };
   },
 
@@ -309,6 +373,20 @@ export default {
     // 得到当前展示的table的唯一标识
     this.tableKey = this.$route.query.tableKey;
   },
+  watch: {
+    tableList: {
+      handler(val) {
+        console.log(JSON.parse(JSON.stringify(val)), "tableListChange");
+      },
+      deep: true,
+    },
+  },
+  computed: {
+    isShowExcuteCol() {
+      // return true;
+      return !this.excuteBtnArr?.every((arr) => arr.children.length == 0);
+    },
+  },
   methods: {
     /** 查询列表 */
     getList(queryParams) {
@@ -316,16 +394,24 @@ export default {
       // 序列化当前查询参数列表
       queryParams && (this.queryParams.queryMap = queryParams.queryMap);
       // 获取当前表单结构信息
-      dragTableInfo({queryMap: {tableKey: this.tableKey}})
+      dragTableInfo({ queryMap: { tableKey: this.tableKey } })
         .then((res) => {
           // 得到当前模版信息 --- sql columns queryWhere
           this.templateInfo = res.data.resultMap;
+          this.styleList = res.data.resultMap.style?.map((item) => {
+            item.styleField = camelCase(
+              item.styleField.replace(".", "_") || ""
+            );
+            return item;
+          });
+          // 获取操作列的按钮数据
+          this.excuteBtnArr = res.data.resultMap.button;
           // console.log('res', this.templateInfo)
           this.queryParams.orderByColumn =
             res.data.resultMap.querySql.orderByColumn;
           this.sortOrder = JSON.parse(res.data.resultMap.querySql.sortOrder);
           // 根据拖拽时设置当前列表排列顺序
-          this.queryParams.isAsc = this.sortOrder ? "DESC" : "ASC"
+          this.queryParams.isAsc = this.sortOrder ? "DESC" : "ASC";
           this.tableName = this.templateInfo.template.dtTableName;
           // 得到查询条件
           this.queryFromWhere = res.data.resultMap.where;
@@ -342,27 +428,32 @@ export default {
             this.queryParams.orderByColumn || ""
           );
           // 根据sql语句查询当前表数据
-          console.log(this.queryParams)
-          unionListTableData(this.queryParams).then((res) => {
+          unionListTableData(this.queryParams).then(async (res) => {
             // console.log('unionListTableData');
             this.tableList = [];
             res.rows.forEach((item) => {
               this.tableList.push(item.resultMap);
             });
             // 驼峰转换
-            this.tableList = this.tableList.map((item) => {
+            let tempTableList = [];
+            tempTableList = this.tableList.map((item) => {
               let kv = {};
               for (let itemKey in item) {
                 kv[camelCase(itemKey)] = item[itemKey];
               }
               return kv;
             });
+            // this.setDictStyleData().then(() => {
+            //   this.tableList = this.setFieldStyleData(this.tableList);
+            // });
+            this.tableList = await this.setFieldStyleData(tempTableList);
             this.total = res.total;
             this.loading = false;
           });
 
           // 查询统计信息
           getStatisticList({
+<<<<<<< HEAD
             queryMap: {
               tableKey: this.templateInfo.template.tableKey,
               queryCriteriaValue: this.queryParams.queryMap.queryCriteriaValue
@@ -371,6 +462,12 @@ export default {
             // console.log('getStatisticList', res);
             this.statisticList = res.data
           })
+=======
+            queryMap: { tableKey: this.templateInfo.template.tableKey },
+          }).then((res) => {
+            this.statisticList = res.data;
+          });
+>>>>>>> 0b02a879572de5f5533cacbfea997e10bc594762
         });
     },
     isUpperCase(char) {
@@ -440,9 +537,9 @@ export default {
       this.$refs.mychild.pageList(
         row == undefined
           ? {
-            limit: this.queryParams.pageSize,
-            page: this.queryParams.pageNum,
-          }
+              limit: this.queryParams.pageSize,
+              page: this.queryParams.pageNum,
+            }
           : row
       );
     },
@@ -472,11 +569,15 @@ export default {
     handleAdd(row) {
       // this.reset();
       this.defaultValue = {};
-      getInfoBySqlKey(this.templateInfo.template.sqlKey).then(({data}) => {
+      getInfoBySqlKey(this.templateInfo.template.sqlKey).then(({ data }) => {
         if (!data || !data.dfVueTemplate) {
           this.$message.error("当前表格未绑定表单!");
           return;
         }
+        if (data.dfFormSql) {
+          let dynamicData = JSON.parse(data.dfFormSql);
+          Object.assign(this.dynamicData, dynamicData);
+        }
         this.jsonData = JSON.parse(data.dfVueTemplate);
         this.open = true;
         this.title = "添加信息";
@@ -487,13 +588,38 @@ export default {
         });
       });
     },
+    longestCommonSubstring(strs) {
+      if (!strs || strs.includes("")) return "";
+      let str1_Length = strs[0].length;
+      let str_Nums = strs.length;
+      let flag = 0;
+      for (let i = 0; i < str1_Length && flag == 0; i++) {
+        let char = strs[0][i];
+        for (var j = 1; j < str_Nums; j++) {
+          if (char !== strs[j][i] || i == strs[j].length) {
+            return strs[1].substring(0, i);
+          }
+        }
+      }
+      return strs[0];
+    },
+
     /** 修改按钮操作 */
     handleUpdate(row) {
-      getInfoBySqlKey(this.templateInfo.template.sqlKey).then(({data}) => {
+      console.log(row);
+      getInfoBySqlKey(this.templateInfo.template.sqlKey).then(({ data }) => {
         if (!data || !data.dfVueTemplate) {
           this.$message.error("当前表格未绑定表单!");
           return;
         }
+        // let fieldList = Object.keys(row);
+        // let tableName = this.longestCommonSubstring(fieldList);
+        // fieldList.forEach((field) => {
+        //   let realField = field.replace(tableName, "");
+        //   realField = realField[0].toLocaleLowerCase() + realField.substring(1);
+        //   row[realField] = row[field];
+        // });
+        this.addRealFieldName(row);
         Object.assign(this.defaultValue, row);
         this.jsonData = JSON.parse(data.dfVueTemplate);
         this.open = true;
@@ -517,6 +643,16 @@ export default {
         this.form.password = "";
       });
     },
+    // 添加真正的字段名
+    addRealFieldName(row) {
+      let fieldList = Object.keys(row);
+      let tableName = this.longestCommonSubstring(fieldList);
+      fieldList.forEach((field) => {
+        let realField = field.replace(tableName, "");
+        realField = realField[0].toLocaleLowerCase() + realField.substring(1);
+        row[realField] = row[field];
+      });
+    },
 
     /** 提交按钮 */
     submitForm: function () {
@@ -545,6 +681,7 @@ export default {
     handleDelete(row) {
       let delIds = this.ids;
       let primary = camelCase(this.templateInfo.template?.primaryKey);
+      this.addRealFieldName(row);
       if (row[primary] != undefined && row[primary] != null) {
         delIds = [];
         delIds.push(row[primary]);
@@ -568,8 +705,7 @@ export default {
           this.$refs.mychild.pageList();
           this.$modal.msgSuccess("删除成功");
         })
-        .catch(() => {
-        });
+        .catch(() => {});
     },
     /** 导出按钮操作 */
     handleExport() {
@@ -602,7 +738,7 @@ export default {
     importTemplate() {
       this.download(
         process.env.VUE_APP_BASE_API3 +
-        `common/exportTemplate?tableName=${this.tableName}&sqlkey=${this.templateInfo.template.sqlKey}`,
+          `common/exportTemplate?tableName=${this.tableName}&sqlkey=${this.templateInfo.template.sqlKey}`,
         {},
         `下载模版名称${new Date().getTime()}.xlsx`
       );
@@ -618,10 +754,10 @@ export default {
       this.$refs.upload.clearFiles();
       this.$alert(
         "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
-        response.msg +
-        "</div>",
+          response.msg +
+          "</div>",
         "导入结果",
-        {dangerouslyUseHTMLString: true}
+        { dangerouslyUseHTMLString: true }
       );
       this.$refs.mychild.pageList({
         limit: this.queryParams.pageSize,
@@ -669,7 +805,7 @@ export default {
             updateData.conditionMap[this.templateInfo.template?.primaryKey] =
               this.defaultValue[
                 camelCase(this.templateInfo.template?.primaryKey)
-                ];
+              ];
             Object.keys(values).map((k) => {
               updateData.commMap[k] = values[k];
             });
@@ -695,7 +831,6 @@ export default {
         .catch((res) => {
           this.$modal.msgError("表单校验失败,请规范填写数据");
         });
-
     },
     // 使用提交数据类型的按钮获取数据
     tempSubBtn(getData) {
@@ -707,6 +842,160 @@ export default {
           console.log("验证未通过,获取失败");
         });
     },
+    // 判断是否生效行样式
+    cellStyle({ row, column, rowIndex, columnIndex }) {
+      let rowStyleList = this.styleList.filter((item) => item.styleType == 0);
+      if (!rowStyleList.length) return "";
+      let mainTableName = this.templateInfo.querySql.tableAlias; //主表名
+      for (let i = 0; i < rowStyleList.length; i++) {
+        let item = rowStyleList[i];
+        let judgeRes = this.determineCondition(item.styleCondtion, row);
+        if (judgeRes) {
+          let styleCode = JSON.parse(item.styleCode);
+          return `background-color:${styleCode.rowBgColor};`;
+        }
+      }
+    },
+
+    // 获取生效条件组结果
+    determineCondition(conditionStr, row) {
+      let conditionList = JSON.parse(conditionStr);
+      if (!conditionList.length) return false;
+      return conditionList.every((item) => this.judgeOneCondition(item, row));
+    },
+
+    // 获取单个判断条件结果
+    judgeOneCondition(item, row) {
+      let fullField = camelCase(item.tableName + "_" + item.fieldName);
+      switch (item.condition) {
+        case 1:
+          return row[fullField] > item.flagValue;
+        case 2:
+          return row[fullField] < item.flagValue;
+        case 3:
+          return row[fullField] == item.flagValue;
+        case 4:
+          return row[fullField] >= item.flagValue;
+        case 5:
+          return row[fullField] <= item.flagValue;
+        default:
+          return true; //默认为true
+      }
+    },
+
+    // 设置表格字段样式
+    async setFieldStyleData(tableList) {
+      let fieldConditionList = this.styleList.filter(
+        (item) => item.styleType == 1 || item.styleType == 2
+      );
+      if (!fieldConditionList.length) return tableList;
+      let res = await this.setDictStyleData();
+      console.log(res);
+      this.dictStyleObj = res;
+      // console.log(JSON.parse(JSON.stringify(this.dictStyleObj)));
+      tableList.forEach((row) => {
+        // if (!row.styleFieldObj) row.styleFieldObj = {};
+        for (let i = 0; i < fieldConditionList.length; i++) {
+          let item = fieldConditionList[i];
+          if (item.styleType == 1) {
+            //字段样式
+            let judgeRes = this.determineCondition(item.styleCondtion, row);
+            if (judgeRes) {
+              let styleCode = JSON.parse(item.styleCode);
+              if (!row.styleFieldObj) row.styleFieldObj = {};
+              row.styleFieldObj[item.styleField] = {
+                styleType: item.styleType,
+                fieldStyleType: styleCode.fieldStyleType,
+                fontColor: styleCode.fontColor,
+                isTagFullBg: styleCode.isTagFullBg,
+                tagType: styleCode.tagType,
+              };
+              // row.styleField = item.styleField; //样式生效字段
+              // row.styleType = item.styleType; //0:行样式 1:字段样式 2:字典样式
+              // row.fieldStyleType = styleCode.fieldStyleType; //0:文本  1:标签
+              // row.fontColor = styleCode.fontColor;
+              // row.isTagFullBg = styleCode.isTagFullBg; //true/false
+              // row.tagType = styleCode.tagType; //string
+            }
+          } else {
+            //字典样式
+            let dicStyle = this.dictStyleObj[item.styleField]?.find((dict) => {
+              return dict.dictValue == row[item.styleField];
+            });
+            if (dicStyle) {
+              if (!row.styleFieldObj) row.styleFieldObj = {};
+              row.styleFieldObj[item.styleField] = dicStyle; //设置该字段应该显示的字典样式
+              row.styleFieldObj[item.styleField].styleType = 2;
+            }
+          }
+        }
+      });
+      return tableList;
+    },
+
+    //设置表格字典相关数据
+    setDictStyleData() {
+      let fieldConditionList = this.styleList.filter(
+        (item) => item.styleType == 2
+      );
+      if (!fieldConditionList.length) return;
+
+      return new Promise((resolve, reject) => {
+        fieldConditionList.forEach((item) => {
+          try {
+            let temp = {};
+            listData({
+              isEnablePaging: false,
+              dictType: item.styleCondtion,
+            }).then((res) => {
+              temp[item.styleField] = res.rows;
+              resolve(temp);
+            });
+          } catch (error) {
+            reject(error);
+          }
+        });
+      });
+    },
+
+    // 内链页面跳转
+    routerHandler(link, type) {
+      console.log(link);
+      if (type == "3") {
+        this.$router.push(link);
+      } else {
+        window.open("http://" + link, "_blank");
+      }
+    },
+
+    // 操作列回调
+    excuteHandler(btnData, row) {
+      console.log(btnData, row);
+      let { btnType, btnParams } = btnData;
+      switch (
+        btnType //3:内链  6:目录  7:外链  8:修改  9:删除
+      ) {
+        case "3":
+          this.routerHandler(btnParams, btnType);
+          break;
+        case "7":
+          this.routerHandler(btnParams, btnType);
+          break;
+        case "8":
+          this.handleUpdate(row);
+          break;
+        case "9":
+          this.handleDelete(row);
+          break;
+        default:
+          break;
+      }
+    },
+
+    // k-form-build表单变化回调
+    formChangeHandler(value, label) {
+      console.log(value, label);
+    },
   },
 };
 </script>

+ 2 - 5
ruoyi-ui/vue.config.js

@@ -8,7 +8,8 @@ const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
 
 const CompressionPlugin = require('compression-webpack-plugin')
 
-const name = process.env.VUE_APP_TITLE || '后台管理系统' // 网页标题
+// const name = process.env.VUE_APP_TITLE || '后台管理系统' // 网页标题
+const name = 'wu' // 网页标题
 
 const port = process.env.port || process.env.npm_config_port || 80 // 端口
 const isDev = process.env.NODE_ENV !== "production";
@@ -38,11 +39,7 @@ module.exports = {
     proxy: {
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
-<<<<<<< HEAD
-        target: `http://192.168.110.83:8080`,
-=======
         target: `http://192.168.110.76:8080`,
->>>>>>> 61c3b2a1bbef89cc20056ddf30d1203ffe17e3f1
         changeOrigin: true,
         pathRewrite: {
           ['^' + process.env.VUE_APP_BASE_API]: ''