【仅供内部供应商使用,不提供对外解答和培训】
...
4、所有下载插件的前端必须统一以FR.downloadHyperlink( taskId ) 为入口实现下载触发,且超链接的type属性必须是download
5、所有文件下载的服务必须统一为两个web接口:
FR.servletURL+"?op=fr_attach&cmd=ah_info&id="+taskId
...
功能:产品内部已有的附件下载接口(我们下载的时候需要借助产品的附件这个入口实现)
响应:文件流
我们会用到两个JAR包(里面把上传下载会用到的一些FR的东西诸如动态计算,界面处理,JS的实现等等的逻辑提前封装好了,我们直接依赖即可)首先我们要依赖于一个插件(标准中有两个请求,但是产品里面第一个获取文件信息的接口并没有实现,所以我们单独做了一个补丁插件把这接口和JS的部分都封装好了)
View file | ||||
---|---|---|---|---|
|
View file | ||||
---|---|---|---|---|
|
接下来我们开发一个基础的从磁盘上传或者下载文件的插件作为demo示例
首先我们要定义我们描述一个文件的对象,我们简单分为,路径/名称/重命名 3个属性,因为这些属性我们都支持公式,也允许单元格扩展填报动态计算,那么我们属性值就都定义成Object安装这个插件除了获得获取文件信息接口的能力外,插件还提供了一些产品内部计算逻辑和简化逻辑的封装,我们开发自己的插件时plugin.xml不要忘记添加依赖哟
Code Block | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||
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 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||
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 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||
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 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||
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 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||
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 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||
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 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
<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> |
运行效果如下:
接下来我们再来实现对应的上传功能,下载我们每次只能添加一个文件任务(没有做文件夹压缩,感兴趣的同学可以自己在把压缩实现一下即可),那么上传我们希望一次可以多个任务。
...