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

Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

4、所有下载插件的前端必须统一以FR.downloadHyperlink( taskId ) 为入口实现下载触发,且超链接的type属性必须是download

5、所有文件下载的服务必须统一为两个web接口:

FR.servletURL+"?op=fr_attach&cmd=ah_info&id="+taskId 

...

功能:产品内部已有的附件下载接口(我们下载的时候需要借助产品的附件这个入口实现)

响应:文件流


二、实现

我们会用到两个JAR包(里面把上传下载会用到的一些FR的东西诸如动态计算,界面处理,JS的实现等等的逻辑提前封装好了,我们直接依赖即可)首先我们要依赖于一个插件(标准中有两个请求,但是产品里面第一个获取文件信息的接口并没有实现,所以我们单独做了一个补丁插件把这接口和JS的部分都封装好了)

View file
nametoolfr-plugin-tptjattachment-xmlservice-1.0.jarzip
height250
View file
nametool-tptj-file-operator-1.0.jar
height250

接下来我们开发一个基础的从磁盘上传或者下载文件的插件作为demo示例

首先我们要定义我们描述一个文件的对象,我们简单分为,路径/名称/重命名 3个属性(大家实际开发的时候,具体有多少种属性,属性叫啥自己根据需要定义即可),因为这些属性我们都支持公式,也允许单元格扩展填报动态计算,那么我们属性值就都定义成Object安装这个插件除了获得获取文件信息接口的能力外,插件还提供了一些产品内部计算逻辑和简化逻辑的封装,我们开发自己的插件时plugin.xml不要忘记添加依赖哟

Code Block
languagejavaxml
themeEclipse
firstline1
titleFileDefineplugin.javaxml
linenumberstrue
collapsetrue
package com.tptj.bridge.hg.file.load.demo;

import com.fr.io.context.info.GetConfig;
import com.fr.stable.FCloneable;
import <dependence>
	<item type="plugin" key="com.tptj.toolsextra.hg.file.operator.dynamics.Column;
import com.tptj.toolsattachment.service"/>
</dependence>

注:除了plugin.xml要添加依赖之外,开发的时候也不要忘记依赖插件内的3个JAR包哟!


接下来我们开发一个基础的从磁盘上传或者下载文件的插件作为demo示例

首先我们要定义我们描述一个文件的对象,我们简单分为,路径/名称/重命名 3个属性(大家实际开发的时候,具体有多少种属性,属性叫啥自己根据需要定义即可),因为这些属性我们都支持公式,也允许单元格扩展填报动态计算,那么我们属性值就都定义成Object

Code Block
languagejava
themeEclipse
firstline1
titleFileDefine.java
linenumberstrue
collapsetrue
package com.tptj.bridge.hg.file.operatorload.utils.BaseUtilsdemo;

import com.tptjfr.toolsio.hgcontext.xmlinfo.fun.ConfigGetConfig;

/**
 import com.fr.stable.FCloneable;
import com.tptj.tools.hg.file.operator.dynamics.Column;
import com.tptj.tools.hg.file.operator.utils.BaseUtils;
import com.tptj.tools.hg.xml.fun.Config;

/**
 * @author 秃破天际
 * @version 10.0
 * Created by 秃破天际 on 2021-01-07
 **/
public class FileDefine implements FCloneable {

    public static final String KEY_PATH = "path";
    public static final String KEY_FILE = "file";
    public static final String KEY_RENAME = "rename";

    @Config(KEY_PATH)
    @Column(title = "路径",idx = 0)
    private Object path;

    @Config(KEY_FILE)
    @Column(title = "文件",idx = 1)
    private Object file;

    @Config(KEY_RENAME)
    @Column(title = "重命名",idx = 2)
    private Object rename;

    @GetConfig(KEY_PATH)
    public Object getPath() {
        return path;
    }

    public void setPath(Object path) {
        this.path = path;
    }

    @GetConfig(KEY_FILE)
    public Object getFile() {
        return file;
    }

    public void setFile(Object file) {
        this.file = file;
    }

    @GetConfig(KEY_RENAME)
    public Object getRename() {
        return rename;
    }

    public void setRename(Object rename) {
        this.rename = rename;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        FileDefine obj = (FileDefine)super.clone();
        obj.file = BaseUtils.clone( file );
        obj.path = BaseUtils.clone( path );
        obj.rename = BaseUtils.clone( rename );
        return obj;
    }
}

...

Code Block
languagejava
themeEclipse
firstline1
titleDownloadHyperlinkPane.java
linenumberstrue
collapsetrue
package com.tptj.bridge.hg.file.load.demo;

import com.fr.design.beans.BasicBeanPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.tptj.tools.hg.file.operator.design.DynamicsListPane;
import com.tptj.tools.hg.file.operator.utils.DynamicsPaneUtils;

import java.awt.*;

/**
 * @author 秃破天际
 * @version 10.0
 * Created by 秃破天际 on 2021-01-04
 **/
public class DownloadHyperlinkPane extends BasicBeanPane<DownloadHyperlink> {

    DynamicsListPane<FileDefine> editor ;

    public DownloadHyperlinkPane(){
        setLayout(FRGUIPaneFactory.createM_BorderLayout());
        editor = DynamicsPaneUtils.createListPane(FileDefine.class);
        add( editor, BorderLayout.CENTER );
    }

    @Override
    public void populateBean( DownloadHyperlink link ) {
        if( null == link ){
            return;
        }
        editor.populateBean( link.getFile() );
    }

    @Override
    public DownloadHyperlink updateBean() {
        DownloadHyperlink rt = new DownloadHyperlink();
        rt.setFile( editor.updateBean() );
        return rt;
    }

    @Override
    protected String title4PopupWindow() {
        return "下载demo";
    }
}

这个就是一般的FR设计器插件中常用的beanpane的实现,这里我们单独提供了一个API。 DynamicsPaneUtils.createListPane

它的功能就是,把我们带@Column和@Config注解且实现了FCloneable的对象,转换成支持公式编辑的属性配置界面(后面可以看实际效果)

我们这里除了文件描述以外没有增加任何其他配置,大家开发的时候根据自己的实际需要定义相关配置即可。

下载我们前面说了,需要通过固定的两个接口和一个固定的JS入口,才能实现对移动端的兼容,这里我们JAR里面已经实现好了,大家只需要继承一下即可

Code Block
languagejava
themeEclipse
firstline1
titleFilter.java
linenumberstrue
collapsetrue
package com.tptj.bridge.hg.file.load.demo;

import com.tptj.tools.hg.file.operator.bridge.FileMessageFilter;

/**
 * @author 秃破天际
 * @version 10.0
 * Created by 秃破天际 on 2021-01-07
 **/
public class Filter extends FileMessageFilter {
    @Override
    public String filterName() {
        return "Download Filter";
    }

}

Code Block
languagejava
themeEclipse
firstline1
titleFileDownloadJs.java
linenumberstrue
collapsetrue
package com.tptj.bridge.hg.file.load.demo;

import com.tptj.tools.hg.file.operator.bridge.FileDownloadJs;

/**
 * @author 秃破天际
 * @version 10.0
 * Created by 秃破天际 on 2021-01-07
 **/
public class LoadJS extends FileDownloadJs {
}

...

rt;
    }

    @Override
    protected String title4PopupWindow() {
        return "下载demo";
    }
}

这个就是一般的FR设计器插件中常用的beanpane的实现,这里我们单独提供了一个API。 DynamicsPaneUtils.createListPane

它的功能就是,把我们带@Column和@Config注解且实现了FCloneable的对象,转换成支持公式编辑的属性配置界面(后面可以看实际效果)

我们这里除了文件描述以外没有增加任何其他配置,大家开发的时候根据自己的实际需要定义相关配置即可。


最后我们注册到插件里面生效即可

Code Block
languagejava
themeEclipse
firstline1
titleDownloadHyperlinkBridge.java
linenumberstrue
collapsetrue
package com.tptj.bridge.hg.file.load.demo;

import com.fr.design.fun.impl.AbstractHyperlinkProvider;
import com.fr.design.gui.controlpane.NameObjectCreator;
import com.fr.design.gui.controlpane.NameableCreator;
import com.fr.general.ComparatorUtils;

/**
 * @author 秃破天际
 * @version 10.0
 * Created by 秃破天际 on 2021-01-04
 **/
public class DownloadHyperlinkBridge extends AbstractHyperlinkProvider {
    //只需要改这里就可以了
    private NameableCreator nameableCreator = new NameObjectCreator("下载demo",
            DownloadHyperlink.class, DownloadHyperlinkPane.class);

    @Override
    public int hashCode() {
        return nameableCreator.menuName().hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return (obj != null && obj instanceof DownloadHyperlinkBridge)
                && ComparatorUtils.equals(((DownloadHyperlinkBridge) obj).nameableCreator, nameableCreator);
    }

    @Override
    public NameableCreator createHyperlinkCreator() {
        return nameableCreator;
    }
}

...

Code Block
languagexml
themeEclipse
firstline1
titleplugin.xml
linenumberstrue
<extra-designer>
	<HyperlinkProvider class="com.tptj.bridge.hg.file.load.demo.DownloadHyperlinkBridge"/>
</extra-designer>
<extra-report>
	<JavaScriptFileHandler class="com.tptj.bridge.hg.file.load.demo.LoadJS"/>
</extra-report>
<extra-decision>
	<GlobalRequestFilterProvider class="com.tptj.bridge.hg.file.load.demo.Filter"/>
</extra-decision>

运行效果如下:


接下来我们再来实现对应的上传功能,下载我们每次只能添加一个文件任务(没有做文件夹压缩,感兴趣的同学可以自己在把压缩实现一下即可),那么上传我们希望一次可以多个任务。

...