ludc
2024-12-13 9d92bb1d5698690bfd06fb93c668d9ae73300426
添加按钮权限查询接口。
修改UI页面定义的属性字段。
已修改12个文件
297 ■■■■ 文件已修改
Source/plt-web/plt-web-parent/plt-web-api/src/main/java/com/vci/pagemodel/MenuVO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-parent/plt-web-api/src/main/java/com/vci/pagemodel/PLDefinationVO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-parent/plt-web-api/src/main/java/com/vci/pagemodel/UIComponentVO.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/controller/SmFunctionController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/ISmFunctionQueryService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/UIManagerServiceI.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/SmFunctionQueryServicePlatformImpl.java 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/UIEngineServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/UIManagerServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/uidataservice/impl/UIDataCommonServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/util/RightControlUtil.java 62 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/xmlmodel/UIComponentDefineXO.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-parent/plt-web-api/src/main/java/com/vci/pagemodel/MenuVO.java
@@ -126,7 +126,7 @@
    private String modeType;
    /**
     * 功能类型:0:功能菜单节点,1:分类,3:按钮
     * 功能类型:0:功能菜单节点,1:分类
     */
    private int functionType;
Source/plt-web/plt-web-parent/plt-web-api/src/main/java/com/vci/pagemodel/PLDefinationVO.java
@@ -176,12 +176,12 @@
    /**
     * cs端使用的自定义查询类名或URL
     */
    private String csCustQueryCLsOrUrl = "";
    private String csDataModel = "";
    /**
     * bs端使用的自定义查询类名或URL
     */
    private String bsCustQueryCLsOrUrl = "";
    private String bsDataModel = "";
    /**
     * 子UI的业务类型
Source/plt-web/plt-web-parent/plt-web-api/src/main/java/com/vci/pagemodel/UIComponentVO.java
@@ -29,7 +29,7 @@
    /**
     * bs端使用的自定义查询类名或URL
     */
    private String bsCustQueryCLsOrUrl;
    private String bsDataModel;
    /**
     * 所属区域
@@ -91,12 +91,12 @@
     */
    private List<UIButtonDefineVO> buttons;
    public void setBsCustQueryCLsOrUrl(String bsCustQueryCLsOrUrl) {
        this.bsCustQueryCLsOrUrl = bsCustQueryCLsOrUrl;
    public void setBsDataModel(String bsDataModel) {
        this.bsDataModel = bsDataModel;
    }
    public String getBsCustQueryCLsOrUrl() {
        return bsCustQueryCLsOrUrl;
    public String getBsDataModel() {
        return bsDataModel;
    }
    @Override
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/controller/SmFunctionController.java
@@ -47,6 +47,16 @@
    }
    /**
     * 获取当前用户的所有按钮
     * @param treeQueryObject 树查询对象
     * @return
     */
    @GetMapping("/getAllButtons")
    public BaseResult getAllButtons(TreeQueryObject treeQueryObject){
        return BaseResult.dataList(functionQueryService.buttons(treeQueryObject));
    }
    /**
     * 获取当前用户的菜单
     * @param treeQueryObject 树查询对象
     * @return  树节点,出现错误会在异常处理器中统一返回Json
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/ISmFunctionQueryService.java
@@ -45,6 +45,14 @@
    List<SmFunctionVO> listFunctionByUserOid(String userOid, Map<String, String> queryMap, ResourceControlTypeEnum resourceControlTypeEnum);
    /**
     * 根据角色返回所有按钮的树形结构
     *
     * @param treeQueryObject
     * @return
     */
    List<MenuVO> buttons(TreeQueryObject treeQueryObject);
    /**
     * 获取当前角色的菜单
     * @param treeQueryObject 属性查询对象
     * @param resourceControlTypeEnum 角色控制区域,也是功能控制的区域
@@ -61,6 +69,7 @@
     * @throws VciBaseException
     */
    List<MenuVO> getSysModelTreeMenuByPID(String parentId,String modeType,boolean isAll) throws VciBaseException;
    /**
     * 通过模块ID获取子级列表
     * @param isAll 是否包括无效的模块,true则包括
@@ -176,6 +185,7 @@
     * @throws PLException
     */
    BaseResult saveRoleRight(List<RoleRightParamDTO> roleRightDTOS, String roleId) throws PLException;
    /**
     * 获取所授权的模块权限
     * @param roleName 搜索的角色
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/UIManagerServiceI.java
@@ -94,21 +94,21 @@
    DataGrid getTabByContextIdAndType(String contextId, int areaType) throws PLException;
    /**
     * 添加区域数据
     * 添加区域(页签)数据
     * @param plTabPage
     * @return
     */
    boolean addTabData(PLTabPage plTabPage) throws PLException;
    /**
     * 修改区域数据
     * 修改区域(页签)数据
     * @param plTabPage
     * @return
     */
    boolean updateTabData(PLTabPage plTabPage) throws PLException;
    /**
     * 删除区域数据
     * 删除区域(页签)数据
     * @param oids
     * @return
     */
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/SmFunctionQueryServicePlatformImpl.java
@@ -150,6 +150,155 @@
    }
    /**
     * 根据用户返回所有菜单下的按钮(树形结构)
     *
     * @param treeQueryObject
     * @return
     */
    @Override
    public List<MenuVO> buttons(TreeQueryObject treeQueryObject) {
        //1、先根据session判断当前用户类型
        SessionInfo sessionInfo = WebUtil.getCurrentUserSessionInfoNotException();
        boolean adminOrDeveloperOrRoot = rightControlUtil.isAdminOrDeveloperOrRoot(sessionInfo.getUserId());
        String parentId;
        //2、根据不同用户返回不同的节点下的菜单和按钮
        if (adminOrDeveloperOrRoot) {
            //系统菜单
            parentId = SYSTEMMANAGMENTNODE;
        } else if (rightControlUtil.isThreeAdminCurUser()) {
            //三员返回管理功能模块相关的菜单
            parentId = SYSTEMMANAGMENTNODE;
        } else {
            // 普通用户只返回业务功能模块相关的菜单,
            // 但可能存在普通用户分配系统功能的菜单和按钮权限,不过需要
            // 再业务功能模块下创建对应的管理功能模块的菜单并进行授权。
            parentId = ROOT_MENU_ID;
        }
        RoleRightInfo[] userRoleRights = rightControlUtil.getRoleRightByUserName(sessionInfo.getUserId());
        //3、根据角色查询出对应的父节点下的所有的菜单,然后再获取菜单下的所有按钮
        //List<FunctionInfo>  menuList = rightControlUtil.getMenusByPIdAndPermission(parentId, sessionInfo.getUserId(),userRoleRights);
        Map<String, List<FunctionInfo>> map = rightControlUtil.getAllChildrenFunctionsByUserName(
                parentId, sessionInfo.getUserId(), userRoleRights);
        List<MenuVO> functionVOList = new ArrayList<>();
        //4、先获取parentid对应的菜单,再获取每一层子节点,同时过滤掉按钮未启用的功能模块
        for (FunctionInfo menu : map.get(parentId)) {
            if(!menu.isValid){
                continue;
            }
            MenuVO functionVO = new MenuVO();
            functionVO.setId(menu.id);
            functionVO.setSource(menu.image);
            functionVO.setPath(menu.resourceB);
            functionVO.setParentId(menu.parentId);
            functionVO.setCode(menu.aliasName);
            functionVO.setAlias(menu.aliasName);
            functionVO.setName(menu.name);
            functionVO.setFunctionType(menu.functionType);
            functionVO.setIsValid(menu.isValid);
            functionVO.getMeta().put("keepAlive",false);
            functionVO.setSort((int) menu.seq);
            try {
                functionVO.setChildren(findChildFunctionVO(menu.id, map));
            } catch (PLException e) {
                e.printStackTrace();
                String errorMsg = "菜单查询时出现错误,原因:" + VciBaseUtil.getExceptionMessage(e);
                logger.error(errorMsg);
                throw new VciBaseException(errorMsg);
            }
            if(functionVO.getChildren().size() > 0){
                functionVO.setHasChildren(true);
            }else {
                functionVO.setHasChildren(false);
            }
            functionVOList.add(functionVO);
        }
        //6、过滤出实际的菜单节点
        List<MenuVO> menuVOList = new ArrayList<>();
        recursionFunction(functionVOList,menuVOList);
        // 5、处理每一个菜单下需要返回的按钮
        menuVOList.stream().forEach(menuVO -> {
            try {
                //6、获取当前菜单下的按钮
                Map<String, Long> authMap = Arrays.stream(userRoleRights).collect(Collectors.toMap(e -> e.funcId, e -> e.rightValue,
                        (existing, replacement) -> existing));
                menuVO.setChildren(getButtonsByAuth(menuVO.getId(),adminOrDeveloperOrRoot,authMap));
            } catch (PLException e) {
                e.printStackTrace();
                String errorMsg = "按钮查询时出现错误,原因:" + VciBaseUtil.getExceptionMessage(e);
                logger.error(errorMsg);
                throw new VciBaseException(errorMsg);
            }
        });
        return menuVOList;
    }
    /**
     * 过滤出菜单只返回菜单节点
     * @param sourceList
     * @param targetList
     */
    private static void recursionFunction(List<MenuVO> sourceList, List<MenuVO> targetList) {
        for (MenuVO menu : sourceList) {
            // 检查functionType是否为0
            if (menu.getFunctionType() == 0) {
                targetList.add(menu);
            }
            // 递归处理children
            recursionFunction(menu.getChildren(), targetList);
        }
    }
    /**
     * 根据菜单主键和角色权限获取其下的按钮
     * @param parentOid
     * @return
     * @throws PLException
     */
    private List<MenuVO> getButtonsByAuth(String parentOid,boolean adminOrDeveloperOrRoot,Map<String, Long> authMap) throws PLException {
        List<MenuVO> buttonList = new ArrayList<>();
        if(Func.isBlank(parentOid)){
            return buttonList;
        }
        FuncOperationInfo[] funcOperates = platformClientUtil.getFrameworkService().getFuncOperationByModule(parentOid, "", true);
        List<FuncOperationInfo> funcOperationList = new ArrayList<>();
        if(!adminOrDeveloperOrRoot){
            for (int i = 0; i < funcOperates.length; i++) {
                if(authMap.containsKey(funcOperates[i].funcId)){
                    long rightValue = authMap.get(funcOperates[i].funcId);
                    long nodeValue = funcOperates[i].number;
                    long preValue = (rightValue >> nodeValue) & 1;
                    //进行位与操作,如果相等则表示具有当前操作的权限
                    if (preValue == 1) {
                        funcOperationList.add(funcOperates[i]);
                    }
                }
            }
        }else{
            funcOperationList = Arrays.asList(funcOperates);
        }
        if(Func.isNotEmpty(funcOperationList)){
            for(FuncOperationInfo info: funcOperationList){
                MenuVO menuVO = new MenuVO();
                menuVO.setChildType(0);
                menuVO.setId(info.id);
                menuVO.setFuncId(info.funcId);
                menuVO.setCode(info.operIndentify);
                menuVO.setOperId(info.operId);
                menuVO.setName(info.operName);
                menuVO.setAlias(info.operAlias);
                menuVO.setRemark(info.operDesc);
                menuVO.setSort((int) info.number);
                menuVO.setIsValid(info.isValid);
                menuVO.setHasChildren(false);
                menuVO.setCategory(1);
                menuVO.setFunctionType(2);
                buttonList.add(menuVO);
            }
        }
        return buttonList;
    }
    /**
     * 原平台功能转换为新平台的功能
     * @param functionForPlatform1List 原平台功能对象列表
     * @return 新平台功能对象
@@ -281,7 +430,7 @@
            }
            functionVOList.add(functionVO);
        }
        //如果是开发或者测试用户,需哟获取系统模块配置菜单
        //如果是开发或者测试用户,需要获取系统模块配置菜单
        if(adminOrDeveloperOrRoot){
            //获取首页系统模块配置菜单
            MenuVO menuVO = JsonConfigReader.getSysModuleConf().getSysModuleNode();
@@ -315,7 +464,7 @@
                    if(childType == 2){
                        try{
                            FuncOperationInfo[] infos = platformClientUtil.getFrameworkService().getFuncOperationByModule(parentId, "", false);
                            if(Func.isNotEmpty(infos.length)){
                            if(Func.isNotEmpty(infos)){
                                childType = this.checkChildObject(infos[0].id); //都是同一层所以取第一个即可查询是什么类型
                                for(int i = 0;i < infos.length ;i++){
                                    FuncOperationInfo info = infos[i];
@@ -333,7 +482,7 @@
                                    menuVO.setIsValid(info.isValid);
                                    menuVO.setHasChildren(false);
                                    menuVO.setCategory(1);
                                    menuVO.setFunctionType(2);
                                    menuVO.setFunctionType(3);
                                    menuVOList.add(menuVO);
                                }
                            }
@@ -436,8 +585,7 @@
     * @param funcInfo
     * @return
     */
    private MenuVO functionInfoToMenuVO(FunctionInfo funcInfo)
    {
    private MenuVO functionInfoToMenuVO(FunctionInfo funcInfo) {
        MenuVO menuVO = new MenuVO();
        menuVO.setId(funcInfo.id);
        menuVO.setIsValid(funcInfo.isValid);
@@ -493,9 +641,7 @@
            functionVO.setId(menu.id);
            functionVO.setSource(menu.image);
            functionVO.setFunctionType(menu.functionType);
//            if(StringUtils.isBlank(menu.resourceB) ){
//                continue;
//            }
            functionVO.setIsValid(menu.isValid);
            functionVO.setPath(menu.resourceB);
            functionVO.setCode(menu.aliasName);
            functionVO.setAlias(menu.aliasName);
@@ -600,7 +746,7 @@
        List<String> authList = new ArrayList<>();
        for (FunctionInfo functionInfo : moduleListByParentId) {
            if(authMap.containsKey(functionInfo.id)){
//                authList.add(functionInfo.id);
                // authList.add(functionInfo.id);
                getChildAuthNode(functionInfo, authMap, authList);
            }
        }
@@ -1090,7 +1236,6 @@
    }
    /**
     * 通过模块ID获取子级列表
     * @param isAll 是否包括无效的模块,true则包括
@@ -1136,7 +1281,6 @@
        return functionVOList;
    }
    /**
     * 通过模块ID获取子级列表
     * @param parentId
@@ -1149,4 +1293,5 @@
        funcInfos = platformClientUtil.getFrameworkService().getModuleListByParentId(parentId, isAll);
        return funcInfos;
    }
}
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/UIEngineServiceImpl.java
@@ -1255,7 +1255,7 @@
                return  null;
            }
            //自定义查询方式
            componentVO.setBsCustQueryCLsOrUrl(componentDefineXO.getBsCustQueryCLsOrUrl());
            componentVO.setBsDataModel(componentDefineXO.getBsDataModel());
            //之前的类型的值是1,2,3等看着不直观
            UIComponentTypeEnum componentTypeEnum = null;
            if("1".equals(componentDefineXO.getTemplateType())){
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/UIManagerServiceImpl.java
@@ -843,7 +843,7 @@
    }
    /**
     * 根据上下文ID和区域类型,按顺序获取当前区域的tab页
     * 根据上下文ID和区域(页签)类型,按顺序获取当前区域的tab页
     */
    @Override
    public DataGrid getTabByContextIdAndType(String contextId, int areaType) throws PLException {
@@ -874,7 +874,7 @@
    }
    /**
     * 修改区域数据
     * 修改区域(页签)数据
     * @param plTabPage
     * @return
     */
@@ -891,7 +891,7 @@
    }
    /**
     * 删除区域数据
     * 删除区域(页签)数据
     * @param oids
     * @return
     */
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/uidataservice/impl/UIDataCommonServiceImpl.java
@@ -157,7 +157,7 @@
        //先判断查询模板是否配置了自定义查询类
        UIComponentVO componentVO = uiEngineService.getComponentByOid(dataGridQuery.getComponentOid(), null);
        UITableDefineVO tableDefineVO = componentVO.getTableDefineVO();
        String bsCustQueryCLsOrUrl = componentVO.getBsCustQueryCLsOrUrl();
        String bsCustQueryCLsOrUrl = componentVO.getBsDataModel()   ;
        // TODO: 2024/12/5 Ludc 根据UI配置的进行判断是否使用自定义类进行查询(自定义类查询方式优先级高于查询模板)
        if(Func.isNotBlank(bsCustQueryCLsOrUrl) && isCustomClass(bsCustQueryCLsOrUrl)){
            //通过反射调用bsCustQueryCLsOrUrl中定义的服务类中的查询方法
@@ -259,7 +259,7 @@
        //先判断查询模板是否配置了自定义查询类
        UIComponentVO componentVO = uiEngineService.getComponentByOid(formQuery.getComponentOid(), null);
        //UIFormDefineVO formDefineVO = uiEngineService.getFormById(formQuery.getBtmName(),formQuery.getFormDefineId());
        String bsCustQueryCLsOrUrl = componentVO.getBsCustQueryCLsOrUrl();
        String bsCustQueryCLsOrUrl = componentVO.getBsDataModel();
        if(Func.isNotBlank(bsCustQueryCLsOrUrl) && isCustomClass(bsCustQueryCLsOrUrl)){
            //通过反射调用bsCustQueryCLsOrUrl中定义的服务类中的查询方法
            try {
@@ -417,7 +417,7 @@
        if(componentVO == null || StringUtils.isBlank(componentVO.getOid())){
            throw new VciBaseException("树的配置信息没有获取到");
        }
        String bsCustQueryCLsOrUrl = componentVO.getBsCustQueryCLsOrUrl();
        String bsCustQueryCLsOrUrl = componentVO.getBsDataModel();
        if(Func.isNotBlank(bsCustQueryCLsOrUrl) && isCustomClass(bsCustQueryCLsOrUrl)){
            //通过反射调用bsCustQueryCLsOrUrl中定义的服务类中的查询方法
            try {
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/util/RightControlUtil.java
@@ -9,15 +9,12 @@
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Component
public class RightControlUtil {
    @Resource
    private PlatformClientUtil platformClientUtil;
@@ -25,11 +22,17 @@
    // add by xchao 2012.09.20 统一归整管理员、开发者用户判断
    // 以便将来有可能修改管理员、开发者用户,对于判断依然有效
    private static String userAdminEnum = "user.admin";
    private String userNameAdmin = null;
    private static String userDeveloperEnum = "user.developer";
    private String userNameDeveloper = null;
    private String userNameRoot = null;
    private static String userRootEnum = "user.rooter";
    public boolean isAdmin(String userName){
        return userName.equals(getUserNameAdmin(userAdminEnum));
    }
@@ -70,6 +73,7 @@
        }
        return userNameAdmin;
    }
    /**
     * 获取配置的开发人员
     * @param key 配置key
@@ -168,7 +172,7 @@
            if (mapRight.containsKey(right.funcId)) {
                lstRight = mapRight.get(right.funcId);
            } else {
                lstRight = new ArrayList<RoleRightInfo>();
                lstRight = new ArrayList<>();
            }
            lstRight.add(right);
            mapRight.put(right.funcId, lstRight);
@@ -197,18 +201,8 @@
                else{
                    if (lstRight.size() > 0)
                        isHasRight = true;
//                    for (int j = 0; j < lstRight.size(); j++) {
//                        long lRight = lstRight.get(j).getRightValue();
//                        if (lRight != 0){
//                            isHasRight = true;
//                            //System.out.println("      === 有授权");
//
//                            break;
//                        }
//                    }
                }
            }
            if (!isHasRight) {
                continue;
            }
@@ -227,7 +221,6 @@
        return map;
    }
    public FunctionInfo[] getFunctionsByParentId(String parentId, String userName) {
        FunctionInfo[] funcObjs =  null;
        try {
@@ -241,6 +234,40 @@
            log.error(e.code, e.messages);
        }
        return funcObjs;
    }
    /**
     * 根据父主键和用户以及角色信息来返回菜单数据
     * @param parentId
     * @param userName
     * @param userRoleRights
     * @return
     */
    public List<FunctionInfo> getMenusByPIdAndPermission(String parentId, String userName,RoleRightInfo[] userRoleRights) {
        Map<String, List<RoleRightInfo>> mapRight = new LinkedHashMap<String, List<RoleRightInfo>>();
        for (int i = 0; i < userRoleRights.length; i++) {
            RoleRightInfo right = userRoleRights[i];
            List<RoleRightInfo> lstRight = null;
            if (mapRight.containsKey(right.funcId)) {
                lstRight = mapRight.get(right.funcId);
            } else {
                lstRight = new ArrayList<>();
            }
            lstRight.add(right);
            mapRight.put(right.funcId, lstRight);
        }
        FunctionInfo[] functionInfos = this.getFunctionsByParentId(parentId, userName);
        boolean isAllShow = isDeveloper(userName) || isAdmin(userName) || !isFunctionSwithOn();
        List<FunctionInfo> functionInfoList = Arrays.stream(functionInfos).filter(menu -> {
            // 只返回有效且是菜单的节点
            if ((menu.isValid && menu.functionType == 0) && (mapRight.containsKey(menu.id) || isAllShow)) {
                return true;
            }
            return false;
        }).collect(Collectors.toList());
        return functionInfoList;
    }
    /**
@@ -261,4 +288,5 @@
        return false;
    }
}
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/xmlmodel/UIComponentDefineXO.java
@@ -165,7 +165,7 @@
    /**
     * bs端使用的自定义查询类名或URL
     */
    private String bsCustQueryCLsOrUrl;
    private String bsDataModel;
    public String getType() {
        return type;
@@ -399,12 +399,12 @@
        this.queryTemplateName = queryTemplateName;
    }
    public void setBsCustQueryCLsOrUrl(String bsCustQueryCLsOrUrl) {
        this.bsCustQueryCLsOrUrl = bsCustQueryCLsOrUrl;
    public void setBsDataModel(String bsDataModel) {
        this.bsDataModel = bsDataModel;
    }
    public String getBsCustQueryCLsOrUrl() {
        return bsCustQueryCLsOrUrl;
    public String getBsDataModel() {
        return bsDataModel;
    }
    @Override
@@ -439,7 +439,7 @@
                ", UIParser='" + UIParser + '\'' +
                ", extAttr='" + extAttr + '\'' +
                ", queryTemplateName='" + queryTemplateName + '\'' +
                ", bsCustQueryCLsOrUrl='" + bsCustQueryCLsOrUrl + '\'' +
                ", bsDataModel='" + bsDataModel + '\'' +
                '}';
    }
}