【仅供内部供应商使用,不提供对外解答和培训】

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Current »

一、特殊名词介绍

WEB组件:本文中所指的组件是指一组用于解决特定业务或实现特定功能的,JS脚本和样式的集合。

二、背景、场景介绍

1.在帆软的决策系统和报表展现时,不同的客户往往对展现的样式和交互风格有自身的审美要求。当产品本身的配置功能不满足需要时,则可以使用该接口进行个性化的处理。

2.在帆软产品的使用过程中,如果客户需要对产品的前端功能进行扩充和变更,则可以使用该接口进行配合实现;(比如:平台功能修改、新增平台功能、新控件、新图表 的开发)

ComposeWebResourceProvider接口是WebResourceProvider的增强版本,WebResourceProvider一次只能引入一个组件,而ComposeWebResourceProvider一次可以引入多个组件。

三、接口介绍

ComposeWebResourceProvider.java
package com.fr.decision.fun;

import com.fr.stable.fun.mark.ComposeWebCoalition;

/**
 * @author Roger
 * @version 10.0
 * @date 2021/1/15
 * 给多个web主组件添加子组件
 */
public interface ComposeWebResourceProvider extends ComposeWebCoalition {

    String MARK_STRING = "ComposeWebResourceProvider";

    int CURRENT_LEVEL = 1;
}

ComposeWebCoalition.java
package com.fr.stable.fun.mark;


/**
 * @author Roger
 * @version 10.0
 * @date 2021/1/15
 * 多主组件注册
 */
public interface ComposeWebCoalition extends Mutable {

    WebCoalition[] webCoalitions();
}

WebCoalition.java
package com.fr.stable.fun.mark;

import com.fr.web.struct.Atom;

/**
 * 带有web资源的扩展接口
 */
public interface WebCoalition extends Mutable {

    /**
     * 需要附加到的主组件
     * @return 主组件
     */
    Atom attach();

    /**
     * 客户端所需的组件
     *
     * @return 组件
     */
    @Deprecated
    Atom client();

    /**
     * 客户端所需的组件集合
     *
     * @return 组件集合
     */
    Atom[] clients();

}


关联接口:com.fr.web.struct.Atom


四、支持版本

产品线

版本

支持情况

备注

FR10.0支持
BI5.1.3支持

五、插件注册

plugin.xml
<extra-decision>
        <ComposeWebResourceProvider class="your class name"/>
</extra-decision>


六、原理说明

AtomActivator.java
package com.fr.web.struct;

import com.fr.module.extension.PrepareAdaptor;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.injectable.PluginInjectionFilter;
import com.fr.stable.ArrayUtils;
import com.fr.stable.fun.mark.ComposeWebCoalition;
import com.fr.stable.fun.mark.WebCoalition;
import com.fr.web.struct.extra.ModificatorInjectUtil;

/**
 * Created by juhaoyu on 2018/9/4.
 */
public class AtomActivator extends PrepareAdaptor {
    
    @Override
    public void prepare() {
    
        addMutable(PluginInjectionFilter.KEY, new PluginInjectionFilter<WebCoalition>(WebCoalition.class) {
            
            @Override
            public void on(WebCoalition webCoalition, PluginContext context) {
                register(webCoalition, context);
            }
        
            @Override
            public void off(WebCoalition webCoalition, PluginContext context) {
                remove(webCoalition, context);
            }
        });

        addMutable(PluginInjectionFilter.KEY, new PluginInjectionFilter<ComposeWebCoalition>(ComposeWebCoalition.class) {

            @Override
            public void on(ComposeWebCoalition composeWebCoalition, PluginContext context) {
                for (WebCoalition webCoalition : composeWebCoalition.webCoalitions()) {
                    register(webCoalition, context);
                }
            }

            @Override
            public void off(ComposeWebCoalition composeWebCoalition, PluginContext context) {
                for (WebCoalition webCoalition : composeWebCoalition.webCoalitions()) {
                    remove(webCoalition, context);
                }
            }

        });
    }

    private void register(WebCoalition webCoalition, PluginContext context) {
        if (webCoalition.client() != null) {
            Atom wrappedAtom = ModificatorInjectUtil.wrapAtom(webCoalition.client(), context.getID());
            Registry.register(webCoalition.attach().getClass(), wrappedAtom);
        }
        if (ArrayUtils.isNotEmpty(webCoalition.clients())) {
            for (Atom client : webCoalition.clients()) {
                Atom wrappedAtom = ModificatorInjectUtil.wrapAtom(client, context.getID());
                Registry.register(webCoalition.attach().getClass(), wrappedAtom);
            }
        }
    }

    private void remove(WebCoalition webCoalition, PluginContext context) {
        if (webCoalition.client() != null) {
            Atom wrappedAtom = ModificatorInjectUtil.wrapAtom(webCoalition.client(), context.getID());
            Registry.remove(webCoalition.attach().getClass(), wrappedAtom);
        }
        if (ArrayUtils.isNotEmpty(webCoalition.clients())) {
            for (Atom client : webCoalition.clients()) {
                Atom wrappedAtom = ModificatorInjectUtil.wrapAtom(client, context.getID());
                Registry.remove(webCoalition.attach().getClass(), wrappedAtom);
            }
        }
    }
}

Registry.java
package com.fr.web.struct;

import com.fr.common.annotations.Open;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 扩展子组件的管理器
 */
@Open
public class Registry {

    private static Map<Class<? extends Atom>, LinkedHashSet<Atom>>
            children = new ConcurrentHashMap<Class<? extends Atom>, LinkedHashSet<Atom>>();

    /**
     * 注册某个组件所需要的子组件
     * @param clazz 父组件
     * @param atom 子组件
     */
    public static void register(Class<? extends Atom> clazz, Atom... atom) {
        LinkedHashSet<Atom> set = children.get(clazz);
        if (set == null) {
            set = new LinkedHashSet<Atom>();
            children.put(clazz, set);
        }
        Collections.addAll(set, atom);
    }

    public static void remove(Class<? extends Atom> clazz, Atom... atom) {
        LinkedHashSet<Atom> set = children.get(clazz);
        if (set == null) {
            return;
        }
        set.removeAll(Arrays.asList(atom));
    }


    /**
     * 获取一个组件的所有额外的子组件
     * @param clazz 父组件
     * @return 所有的子组件组成的数组
     */
    public static Atom[] getChildren(Class<? extends Atom> clazz) {
        LinkedHashSet<Atom> set = children.get(clazz);
        if (set == null) {
            return new Atom[0];
        }
        set.remove(null);
        List<Atom> list = new ArrayList<Atom>();
        for (Atom atom : set) {
            Filter filter = atom.filter();
            if (filter == null || filter.accept()) {
                list.add(atom);
            }
        }
        return list.toArray(new Atom[0]);
    }
}



七、特殊限制说明

目前经过实际统计,在最新的版本中,以下组件支持使用插件进行子组件扩展。也就是接口的attach方法可以返回的key值如下:

假设 $HOST = http(s)://$IP:$PORT/webroot/decision

key被依赖组件——前端页面说明

CommonComponent.KEY

1.DeployComponent.KEY——服务器初始化,导致部署失败时,访问平台会出现此页面,插件中基本用不到

2.DirectoryComponent.KEY——$HOST/directory 单独集成平台报表目录的页面

3.EncryptionComponent.KEY——$HOST/v10/encryption/page 平台切换国密的时候才可能会用到,主要用于提示异常。绝大部分情况下应该是没啥用处的。

4.InitializationComponent.KEY——$HOST/login/initialization 如果系统没有设置超管和finedb数据源的情况下才会出现的页面,大部分时候也没啥用处

5.LoginComponent.KEY——$HOST/login 访问登录页时会加载

6.MainComponent.KEY——$HOST 访问决策平台主页时加载

7.MapEditComponent.KEY——$HOST#management/map 访问决策平台地图配置功能时加载

8.MigrationComponent.KEY——$HOST/v10/migration/page FineDb迁移数据时的进度页面,在插件中用处不大

9.PrivilegeComponent.KEY——$HOST/privilege 单独访问权限管理页面时生效

10.UserComponent.KEY——$HOST/user 单独访问用户管理页面时生效

11.ScheduleComponent.KEY——$HOST/timer  单独访问定时调度页面时生效

12.WorkflowComponent.KEY——$HOST/workflow/authority 单独访问多级上报权限控制页面时生效

Common组件,顾名思义是常用的基础组件,在生效的这些页面中属于非常靠前加载的,优先于被依赖的组件资源加载。这些页面也基本都是跟决策平台相关的页面。所以,开发者想把插件的影响范围扩大到被依赖的多个组件中同时生效的话,可以直接把插件组件作为Common组件的子组件引入即可

ConnectionComponent.KEY

Connection组件在访问决策平台主页时加载,数据源管理组件的资源,但是感觉产品加载的时机过于提前了。

DataSetComponent.KEY

DataSet组件在访问决策平台主页时加载,服务器数据集管理组件的资源,但是感觉产品加载的时机过于提前了。

MainComponent.KEY

【常用】Main组件在访问决策平台主页的时候加载,是整个决策平台的主体资源入口。

DeployComponent.KEY

/服务器初始化,导致部署失败时,访问平台会出现此页面,插件中基本用不到

DirectoryComponent.KEY

$HOST/directory 单独集成平台报表目录的页面

EncryptionComponent.KEY

$HOST/v10/encryption/page 平台切换国密的时候才可能会用到,主要用于提示异常。绝大部分情况下应该是没啥用处的。

FormMainComponent.KEY

【常用】访问决策报表时页面主体JS的入口。
InitializationComponent.KEY$HOST/login/initialization 如果系统没有设置超管和finedb数据源的情况下才会出现的页面,大部分时候也没啥用处
LoginComponent.KEY【常用】$HOST/login 访问登录页时会加载
MapEditComponent.KEY$HOST#management/map 访问决策平台地图配置功能时加载
MigrationComponent.KEY$HOST/v10/migration/page FineDb迁移数据时的进度页面,在插件中用处不大
PrivilegeComponent.KEY$HOST/privilege 单独访问权限管理页面时生效

ReportMainComponent.KEY

【常用】访问一般报表时页面主体JS的入口
ScheduleComponent.KEY$HOST/timer  单独访问定时调度页面时生效
UserComponent.KEY$HOST/user 单独访问用户管理页面时生效
WorkflowComponent.KEY$HOST/workflow/authority 单独访问多级上报权限控制页面时生效

废弃的Atom client()接口方法仅作为兼容保留。新插件中全部使用Atom[] clients();实现即可。

八、常用链接

入门demo地址:demo-web-resource-simple

全功能测试demo地址(包含该接口的所有使用场景):demo-web-resource

三组常见引入JS和CSS的插件接口对比

九、开源案例

免责声明:所有文档中的开源示例,均为开发者自行开发并提供。仅用于参考和学习使用,开发者和官方均无义务对开源案例所涉及的所有成果进行教学和指导。禁止用于任何商业用途,若作为商用一切后果责任由使用者自行承担。

open-JSD-8016

open-JSD-7930

open-JSD-7747

plugin-repository-hdfs

plugin-repository-s3


  • No labels