@ -0,0 +1,5 @@
|
||||
set JAVA_HOME=D:\FineReport\develop\java\jdk1.6u35 |
||||
|
||||
set ANT_OPTS=-Xmx512M -Xss100m |
||||
|
||||
D:\FineReport\develop\release\build\ant\bin\ant -f build.xml jar |
@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||
<project basedir="." default="jar" name="plugin"> |
||||
<!-- JDK路径,根据自己机器上实际位置修改--> |
||||
<property name="jdk.home" value="D:\FineReport\develop\java\jdk1.7.0_55"/> |
||||
|
||||
<property name="libs" value="${basedir}/lib"/> |
||||
<property name="publicLibs" value=""/> |
||||
<property name="destLoc" value="."/> |
||||
<property name="classes" value="classes"/> |
||||
<xmlproperty file="${basedir}/plugin.xml"/> |
||||
<property name="current-version" value="${plugin.version}"/> |
||||
|
||||
<!-- 插件版本--> |
||||
<property name="plugin-version" value="${current-version}"/> |
||||
<!-- 插件名字--> |
||||
<property name="plugin-name" value="external"/> |
||||
<property name="plugin-jar" value="fr-plugin-${plugin-name}-${plugin-version}.jar"/> |
||||
|
||||
<target name="prepare"> |
||||
<delete dir="${classes}"/> |
||||
<delete dir="fr-plugin-${plugin-name}-${plugin-version}"/> |
||||
<xmlproperty file="${basedir}/plugin.xml"/> |
||||
<delete dir="${destLoc}/${plugin.name}"/> |
||||
</target> |
||||
<path id="compile.classpath"> |
||||
<fileset dir="${libs}"> |
||||
<include name="**/*.jar"/> |
||||
</fileset> |
||||
<fileset dir="${publicLibs}"> |
||||
<include name="**/*.jar"/> |
||||
</fileset> |
||||
</path> |
||||
<patternset id="resources4Jar"> |
||||
<exclude name="**/.settings/**"/> |
||||
<exclude name=".classpath"/> |
||||
<exclude name=".project"/> |
||||
|
||||
<exclude name="**/*.java"/> |
||||
<exclude name="**/*.db"/> |
||||
<exclude name="**/*.g"/> |
||||
<exclude name="**/package.html"/> |
||||
</patternset> |
||||
<target name="copy_resources"> |
||||
<echo message="从${resources_from}拷贝图片,JS,CSS等资源文件"/> |
||||
<delete dir="tmp"/> |
||||
<copy todir="tmp"> |
||||
<fileset dir="${resources_from}\src"> |
||||
<patternset refid="resources4Jar"/> |
||||
</fileset> |
||||
</copy> |
||||
<copy todir="${classes}"> |
||||
<fileset dir="tmp"/> |
||||
</copy> |
||||
<delete dir="tmp"/> |
||||
</target> |
||||
<target name="compile_javas"> |
||||
<echo message="编译${compile_files}下的Java文件"/> |
||||
<javac destdir="${classes}" debug="false" optimize="on" source="${source_jdk_version}" |
||||
target="${target_jdk_version}" |
||||
fork="true" memoryMaximumSize="512m" listfiles="false" srcdir="${basedir}" |
||||
executable="${compile_jdk_version}/bin/javac"> |
||||
<src path="${basedir}/src"/> |
||||
<exclude name="**/.svn/**"/> |
||||
<compilerarg line="-encoding UTF8 "/> |
||||
<classpath refid="compile.classpath"/> |
||||
</javac> |
||||
</target> |
||||
|
||||
<target name="jar_classes"> |
||||
<echo message="打Jar包:${jar_name}"/> |
||||
<delete file="${basedir}/${jar_name}"/> |
||||
<jar jarfile="${basedir}/${jar_name}"> |
||||
<fileset dir="${classes}"> |
||||
</fileset> |
||||
</jar> |
||||
</target> |
||||
|
||||
<target name="super_jar" depends="prepare"> |
||||
<antcall target="copy_resources"> |
||||
<param name="resources_from" value="${basedir}"/> |
||||
</antcall> |
||||
<antcall target="compile_javas"> |
||||
<param name="source_jdk_version" value="1.6"/> |
||||
<param name="target_jdk_version" value="1.6"/> |
||||
<param name="compile_jdk_version" value="${jdk.home}"/> |
||||
<param name="compile_files" value="${basedir}/src"/> |
||||
</antcall> |
||||
<echo message="compile plugin success!"/> |
||||
|
||||
<antcall target="jar_classes"> |
||||
<param name="jar_name" value="${plugin-jar}"/> |
||||
</antcall> |
||||
<delete dir="${classes}"/> |
||||
|
||||
</target> |
||||
<target name="jar" depends="super_jar"> |
||||
<antcall target="zip"/> |
||||
</target> |
||||
|
||||
<target name="zip"> |
||||
<property name="plugin-folder" value="fr-plugin-${plugin-name}-${plugin-version}"/> |
||||
<echo message="----------zip files----------"/> |
||||
<mkdir dir="${plugin-folder}"/> |
||||
<copy todir="${plugin-folder}"> |
||||
<fileset dir="."> |
||||
<include name="${plugin-jar}"/> |
||||
<include name="plugin.xml"/> |
||||
</fileset> |
||||
</copy> |
||||
<zip destfile="${basedir}/${plugin-folder}.zip" basedir="."> |
||||
<include name="${plugin-folder}/*.jar"/> |
||||
<include name="${plugin-folder}/plugin.xml"/> |
||||
</zip> |
||||
<xmlproperty file="${basedir}/plugin.xml"/> |
||||
<move file="${plugin-folder}.zip" todir="${destLoc}/${plugin.name}"/> |
||||
</target> |
||||
</project> |
After Width: | Height: | Size: 220 KiB |
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<module type="JAVA_MODULE" version="4"> |
||||
<component name="NewModuleRootManager" inherit-compiler-output="true"> |
||||
<exclude-output /> |
||||
<content url="file://$MODULE_DIR$"> |
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> |
||||
</content> |
||||
<orderEntry type="inheritedJdk" /> |
||||
<orderEntry type="sourceFolder" forTests="false" /> |
||||
<orderEntry type="module" module-name="base-stable" /> |
||||
<orderEntry type="module" module-name="base-basic" /> |
||||
</component> |
||||
</module> |
@ -0,0 +1,201 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<module type="JAVA_MODULE" version="4"> |
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6"> |
||||
<output url="file://$MODULE_DIR$/../../../../../FineReport_10.0-2019-01-20/webapps/webroot/WEB-INF/plugins/plugin-com.fr.plugin.external.v10-1.4.4/classes" /> |
||||
<output-test url="file://$MODULE_DIR$/../../../../../FineReport_10.0-2019-01-20/webapps/webroot/WEB-INF/plugins/plugin-com.fr.plugin.external.v10-1.4.4/classes" /> |
||||
<exclude-output /> |
||||
<content url="file://$MODULE_DIR$"> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> |
||||
</content> |
||||
<orderEntry type="inheritedJdk" /> |
||||
<orderEntry type="sourceFolder" forTests="false" /> |
||||
<orderEntry type="module" module-name="base-activator-conf" /> |
||||
<orderEntry type="module" module-name="base-attachments" /> |
||||
<orderEntry type="module" module-name="base-attachments-interface" /> |
||||
<orderEntry type="module" module-name="base-basic" /> |
||||
<orderEntry type="module" module-name="base-basic-base" /> |
||||
<orderEntry type="module" module-name="base-basic-sdk" /> |
||||
<orderEntry type="module" module-name="base-cache" /> |
||||
<orderEntry type="module" module-name="base-cache-general" /> |
||||
<orderEntry type="module" module-name="base-calculate" /> |
||||
<orderEntry type="module" module-name="base-cluster-collections" /> |
||||
<orderEntry type="module" module-name="base-cluster-ehcache" /> |
||||
<orderEntry type="module" module-name="base-cluster-engine" /> |
||||
<orderEntry type="module" module-name="base-components" /> |
||||
<orderEntry type="module" module-name="base-components-sdk" /> |
||||
<orderEntry type="module" module-name="base-condition" /> |
||||
<orderEntry type="module" module-name="base-connection" /> |
||||
<orderEntry type="module" module-name="base-core-i18n" /> |
||||
<orderEntry type="module" module-name="base-data" /> |
||||
<orderEntry type="module" module-name="base-data-base" /> |
||||
<orderEntry type="module" module-name="base-data-sdk" /> |
||||
<orderEntry type="module" module-name="base-datasource" /> |
||||
<orderEntry type="module" module-name="base-datasource-i18n" /> |
||||
<orderEntry type="module" module-name="base-datasource-sdk" /> |
||||
<orderEntry type="module" module-name="base-db-handler" /> |
||||
<orderEntry type="module" module-name="base-dialect" /> |
||||
<orderEntry type="module" module-name="base-excel" /> |
||||
<orderEntry type="module" module-name="base-fr-log" /> |
||||
<orderEntry type="module" module-name="base-general-base" /> |
||||
<orderEntry type="module" module-name="base-general-data" /> |
||||
<orderEntry type="module" module-name="base-graph-canvas" /> |
||||
<orderEntry type="module" module-name="base-i18n" /> |
||||
<orderEntry type="module" module-name="base-i18n-loader" /> |
||||
<orderEntry type="module" module-name="base-license" /> |
||||
<orderEntry type="module" module-name="base-message" /> |
||||
<orderEntry type="module" module-name="base-module-conf" /> |
||||
<orderEntry type="module" module-name="base-module-register" /> |
||||
<orderEntry type="module" module-name="base-module-register-sdk" /> |
||||
<orderEntry type="module" module-name="base-platform" /> |
||||
<orderEntry type="module" module-name="base-plugin" /> |
||||
<orderEntry type="module" module-name="base-plugin-db" /> |
||||
<orderEntry type="module" module-name="base-privacy" /> |
||||
<orderEntry type="module" module-name="base-privilege-interface" /> |
||||
<orderEntry type="module" module-name="base-repo-ftp" /> |
||||
<orderEntry type="module" module-name="base-resource-io" /> |
||||
<orderEntry type="module" module-name="base-resource-sync" /> |
||||
<orderEntry type="module" module-name="base-stable" /> |
||||
<orderEntry type="module" module-name="base-stable-extension" /> |
||||
<orderEntry type="module" module-name="base-transaction" /> |
||||
<orderEntry type="module" module-name="base-web-atom" /> |
||||
<orderEntry type="module" module-name="base-web-fineui" /> |
||||
<orderEntry type="module" module-name="base-web-sdk" /> |
||||
<orderEntry type="module" module-name="base-web-socket" /> |
||||
<orderEntry type="module" module-name="base-web-tools" /> |
||||
<orderEntry type="module" module-name="base-web-vancharts" /> |
||||
<orderEntry type="module" module-name="base-workspace-engine" /> |
||||
<orderEntry type="module" module-name="base-xml-filemanager" /> |
||||
<orderEntry type="module" module-name="basic-barcode" /> |
||||
<orderEntry type="module" module-name="basic-base" /> |
||||
<orderEntry type="module" module-name="basic-base-application-sdk" /> |
||||
<orderEntry type="module" module-name="basic-email" /> |
||||
<orderEntry type="module" module-name="basic-geo" /> |
||||
<orderEntry type="module" module-name="basic-headerfooter" /> |
||||
<orderEntry type="module" module-name="basic-market" /> |
||||
<orderEntry type="module" module-name="basic-module" /> |
||||
<orderEntry type="module" module-name="basic-plugin" /> |
||||
<orderEntry type="module" module-name="basic-privilege" /> |
||||
<orderEntry type="module" module-name="basic-record" /> |
||||
<orderEntry type="module" module-name="basic-scheduler" /> |
||||
<orderEntry type="module" module-name="basic-upload" /> |
||||
<orderEntry type="module" module-name="basic-web" /> |
||||
<orderEntry type="module" module-name="core-base-stabe-sdk" /> |
||||
<orderEntry type="module" module-name="core-base-stable-extension-sdk" /> |
||||
<orderEntry type="module" module-name="core-clone" /> |
||||
<orderEntry type="module" module-name="core-cluster-extension" /> |
||||
<orderEntry type="module" module-name="core-cluster-interface" /> |
||||
<orderEntry type="module" module-name="core-collections" /> |
||||
<orderEntry type="module" module-name="core-common" /> |
||||
<orderEntry type="module" module-name="core-db" /> |
||||
<orderEntry type="module" module-name="core-diff" /> |
||||
<orderEntry type="module" module-name="core-env" /> |
||||
<orderEntry type="module" module-name="core-ftp" /> |
||||
<orderEntry type="module" module-name="core-gif" /> |
||||
<orderEntry type="module" module-name="core-http" /> |
||||
<orderEntry type="module" module-name="core-i18n-interface" /> |
||||
<orderEntry type="module" module-name="core-image4j" /> |
||||
<orderEntry type="module" module-name="core-intelli" /> |
||||
<orderEntry type="module" module-name="core-jgroups" /> |
||||
<orderEntry type="module" module-name="core-json" /> |
||||
<orderEntry type="module" module-name="core-jwt" /> |
||||
<orderEntry type="module" module-name="core-log-interface" /> |
||||
<orderEntry type="module" module-name="core-module" /> |
||||
<orderEntry type="module" module-name="core-monitor" /> |
||||
<orderEntry type="module" module-name="core-performance" /> |
||||
<orderEntry type="module" module-name="core-pinyin" /> |
||||
<orderEntry type="module" module-name="core-plugin-interface" /> |
||||
<orderEntry type="module" module-name="core-project" /> |
||||
<orderEntry type="module" module-name="core-project-base" /> |
||||
<orderEntry type="module" module-name="core-project-plugin-interface" /> |
||||
<orderEntry type="module" module-name="core-query" /> |
||||
<orderEntry type="module" module-name="core-resource-io" /> |
||||
<orderEntry type="module" module-name="core-security" /> |
||||
<orderEntry type="module" module-name="core-sqlparser" /> |
||||
<orderEntry type="module" module-name="core-ssh" /> |
||||
<orderEntry type="module" module-name="core-unit" /> |
||||
<orderEntry type="module" module-name="core-web" /> |
||||
<orderEntry type="module" module-name="core-web-atom" /> |
||||
<orderEntry type="module" module-name="core-workspace" /> |
||||
<orderEntry type="module" module-name="core-xml" /> |
||||
<orderEntry type="module" module-name="core-zip4j" /> |
||||
<orderEntry type="module" module-name="decision" /> |
||||
<orderEntry type="module" module-name="decision-base" /> |
||||
<orderEntry type="module" module-name="decision-extension-bi-i18n" /> |
||||
<orderEntry type="module" module-name="decision-extension-report-i18n" /> |
||||
<orderEntry type="module" module-name="decision-feature" /> |
||||
<orderEntry type="module" module-name="decision-i18n" /> |
||||
<orderEntry type="module" module-name="decision-main-i18n" /> |
||||
<orderEntry type="module" module-name="decision-report" /> |
||||
<orderEntry type="module" module-name="decision-report-feature" /> |
||||
<orderEntry type="module" module-name="decision-report-sdk" /> |
||||
<orderEntry type="module" module-name="decision-report-workflow" /> |
||||
<orderEntry type="module" module-name="decision-sdk" /> |
||||
<orderEntry type="module" module-name="decision-web" /> |
||||
<orderEntry type="module" module-name="design" /> |
||||
<orderEntry type="module" module-name="design-i18n" /> |
||||
<orderEntry type="module" module-name="design-i18n-chart" /> |
||||
<orderEntry type="module" module-name="design-i18n-report" /> |
||||
<orderEntry type="module" module-name="designer-base" /> |
||||
<orderEntry type="module" module-name="designer-chart" /> |
||||
<orderEntry type="module" module-name="designer-form" /> |
||||
<orderEntry type="module" module-name="designer-realize" /> |
||||
<orderEntry type="module" module-name="engine" /> |
||||
<orderEntry type="module" module-name="engine-analysis" /> |
||||
<orderEntry type="module" module-name="engine-chart" /> |
||||
<orderEntry type="module" module-name="engine-chart-base" /> |
||||
<orderEntry type="module" module-name="engine-chart-chartattr" /> |
||||
<orderEntry type="module" module-name="engine-chart-chartdata" /> |
||||
<orderEntry type="module" module-name="engine-chart-chartglyph" /> |
||||
<orderEntry type="module" module-name="engine-chart-sdk" /> |
||||
<orderEntry type="module" module-name="engine-chart-web" /> |
||||
<orderEntry type="module" module-name="engine-cross" /> |
||||
<orderEntry type="module" module-name="engine-enhancement" /> |
||||
<orderEntry type="module" module-name="engine-file" /> |
||||
<orderEntry type="module" module-name="engine-i18n" /> |
||||
<orderEntry type="module" module-name="engine-page" /> |
||||
<orderEntry type="module" module-name="engine-platform" /> |
||||
<orderEntry type="module" module-name="engine-platform-sdk" /> |
||||
<orderEntry type="module" module-name="engine-report" /> |
||||
<orderEntry type="module" module-name="engine-report-sdk" /> |
||||
<orderEntry type="module" module-name="engine-test" /> |
||||
<orderEntry type="module" module-name="engine-view" /> |
||||
<orderEntry type="module" module-name="engine-workspace-server" /> |
||||
<orderEntry type="module" module-name="engine-write" /> |
||||
<orderEntry type="module" module-name="fine-activator" /> |
||||
<orderEntry type="module" module-name="fine-activator-sdk" /> |
||||
<orderEntry type="module" module-name="fine-core" /> |
||||
<orderEntry type="module" module-name="fine-core-sdk" /> |
||||
<orderEntry type="module" module-name="fine-datasource" /> |
||||
<orderEntry type="module" module-name="fine-decision" /> |
||||
<orderEntry type="module" module-name="fine-decision-sdk" /> |
||||
<orderEntry type="module" module-name="fine-report-designer" /> |
||||
<orderEntry type="module" module-name="fine-report-engine" /> |
||||
<orderEntry type="module" module-name="fine-report-engine-sdk" /> |
||||
<orderEntry type="module" module-name="fine-schedule" /> |
||||
<orderEntry type="module" module-name="fine-schedule-sdk" /> |
||||
<orderEntry type="module" module-name="fine-webui" /> |
||||
<orderEntry type="module" module-name="finereport-maven" /> |
||||
<orderEntry type="module" module-name="fmobile" /> |
||||
<orderEntry type="module" module-name="form" /> |
||||
<orderEntry type="module" module-name="fsbakrestore" /> |
||||
<orderEntry type="module" module-name="fschedule" /> |
||||
<orderEntry type="module" module-name="fservice" /> |
||||
<orderEntry type="module" module-name="fsmonitor" /> |
||||
<orderEntry type="module" module-name="fsworkflow" /> |
||||
<orderEntry type="module" module-name="i18n-engine" /> |
||||
<orderEntry type="module" module-name="schedule" /> |
||||
<orderEntry type="module" module-name="schedule-base" /> |
||||
<orderEntry type="module" module-name="schedule-extension-bi-i18n" /> |
||||
<orderEntry type="module" module-name="schedule-extension-report-i18n" /> |
||||
<orderEntry type="module" module-name="schedule-feature" /> |
||||
<orderEntry type="module" module-name="schedule-i18n" /> |
||||
<orderEntry type="module" module-name="schedule-main-i18n" /> |
||||
<orderEntry type="module" module-name="schedule-report" /> |
||||
<orderEntry type="module" module-name="schedule-report-feature" /> |
||||
<orderEntry type="module" module-name="schedule-sdk" /> |
||||
<orderEntry type="module" module-name="schedule-web" /> |
||||
<orderEntry type="library" name="Maven: com.fr.third:fine-third:10.0-RELEASE-SNAPSHOT" level="project" /> |
||||
<orderEntry type="library" name="Maven: com.fr.third.server:servlet-api:3.0" level="project" /> |
||||
<orderEntry type="module" module-name="plugin-engine-r" /> |
||||
</component> |
||||
</module> |
@ -0,0 +1,39 @@
|
||||
package com.fr.plugin.external; |
||||
|
||||
import com.fr.web.struct.AssembleComponent; |
||||
import com.fr.web.struct.Atom; |
||||
import com.fr.web.struct.browser.RequestClient; |
||||
import com.fr.web.struct.category.ScriptPath; |
||||
import com.fr.web.struct.category.StylePath; |
||||
|
||||
public class DebugComponent extends AssembleComponent { |
||||
|
||||
public static final DebugComponent KEY = new DebugComponent(); |
||||
|
||||
private DebugComponent() { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public Atom[] refer() { |
||||
return new Atom[0]; |
||||
} |
||||
|
||||
@Override |
||||
public Atom[] children() { |
||||
return new Atom[0]; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public ScriptPath script(RequestClient client) { |
||||
// 这边是需要注入的js
|
||||
return ScriptPath.build("/com/fr/nx/web/ui/show.debug.js"); |
||||
} |
||||
|
||||
@Override |
||||
public StylePath style(RequestClient client) { |
||||
return StylePath.EMPTY; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,17 @@
|
||||
package com.fr.plugin.external; |
||||
|
||||
import com.fr.decision.fun.impl.AbstractWebResourceProvider; |
||||
import com.fr.report.web.ReportMainComponent; |
||||
import com.fr.web.struct.Atom; |
||||
|
||||
public class EngineDebugResourceProvider extends AbstractWebResourceProvider { |
||||
@Override |
||||
public Atom attach() { |
||||
return ReportMainComponent.KEY; |
||||
} |
||||
|
||||
@Override |
||||
public Atom client() { |
||||
return EngineTestComponent.KEY; |
||||
} |
||||
} |
@ -0,0 +1,31 @@
|
||||
package com.fr.plugin.external; |
||||
|
||||
import com.fr.web.struct.AssembleComponent; |
||||
import com.fr.web.struct.Atom; |
||||
import com.fr.web.struct.Registry; |
||||
import com.fr.web.struct.browser.RequestClient; |
||||
import com.fr.web.struct.category.ScriptPath; |
||||
|
||||
public class EngineTestComponent extends AssembleComponent { |
||||
|
||||
public static final EngineTestComponent KEY = new EngineTestComponent(); |
||||
|
||||
private EngineTestComponent() { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public Atom[] refer() { |
||||
return new Atom[0]; |
||||
} |
||||
|
||||
@Override |
||||
public ScriptPath script(RequestClient req) { |
||||
return ScriptPath.build("/com/fr/nx/web/ui/show.debug1.js"); |
||||
} |
||||
|
||||
@Override |
||||
public Atom[] children() { |
||||
return Registry.getChildren(EngineTestComponent.class); |
||||
} |
||||
} |
@ -0,0 +1,194 @@
|
||||
package com.fr.plugin.external; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.design.gui.ibutton.UIButton; |
||||
import com.fr.design.gui.icheckbox.UICheckBox; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.utils.gui.GUICoreUtils; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.swing.JDialog; |
||||
import javax.swing.JFileChooser; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.plaf.metal.MetalFileChooserUI; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.Component; |
||||
import java.awt.Container; |
||||
import java.awt.Dimension; |
||||
import java.awt.Insets; |
||||
import java.awt.LayoutManager; |
||||
|
||||
/** |
||||
* 抄的9.0 的---为了8.0能用 |
||||
* 扩展的文件选择框(底部控制区域扩展一个复选框) |
||||
* Created by zack on 2018/3/8. |
||||
* |
||||
* @deprecated |
||||
*/ |
||||
public class ExpandFileChooser extends JFileChooser { |
||||
private JDialog dialog; |
||||
private UICheckBox compressCheckBox;//选择框底部的复选按钮
|
||||
private int retVal = ERROR_OPTION; |
||||
private UIButton approve; |
||||
private UIButton cancel; |
||||
private static final int DEFAULT_WIDTH = 520; |
||||
|
||||
public ExpandFileChooser() { |
||||
this(StringUtils.EMPTY, StringUtils.EMPTY); |
||||
} |
||||
|
||||
public ExpandFileChooser(String checkBoxText, String approveButtonText) { |
||||
JPanel previewContainerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
MetalFileChooserUI chooserUI = (MetalFileChooserUI) getUI(); |
||||
String approveText = StringUtils.isEmpty(approveButtonText) ? chooserUI.getApproveButtonText(this) : approveButtonText; |
||||
dialog = new JDialog(); |
||||
|
||||
dialog.setSize(new Dimension(DEFAULT_WIDTH, 362)); |
||||
dialog.add(previewContainerPane); |
||||
dialog.setIconImage(BaseUtils.readImage("/com/fr/base/images/oem/logo.png")); |
||||
dialog.setTitle(approveText); |
||||
previewContainerPane.add(this, BorderLayout.CENTER); |
||||
|
||||
|
||||
JPanel bottomControlPanel = new JPanel(); |
||||
bottomControlPanel.setLayout(new ImageAreaLayout()); |
||||
bottomControlPanel.setPreferredSize(new Dimension(DEFAULT_WIDTH, 40)); |
||||
|
||||
approve = new UIButton(approveText); |
||||
cancel = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Button_Cancel")); |
||||
if (StringUtils.isNotEmpty(checkBoxText)) { |
||||
compressCheckBox = new UICheckBox(checkBoxText); |
||||
compressCheckBox.setSelected(true); |
||||
bottomControlPanel.add(compressCheckBox); |
||||
} else { |
||||
bottomControlPanel.add(new UILabel());//空标签占位
|
||||
} |
||||
bottomControlPanel.add(approve); |
||||
approve.addActionListener(chooserUI.getApproveSelectionAction()); |
||||
cancel.addActionListener(chooserUI.getCancelSelectionAction()); |
||||
bottomControlPanel.add(cancel); |
||||
previewContainerPane.add(bottomControlPanel, BorderLayout.SOUTH); |
||||
GUICoreUtils.centerWindow(dialog); |
||||
} |
||||
|
||||
public boolean isCompressSelected() { |
||||
if (compressCheckBox!=null){ |
||||
return compressCheckBox.isSelected(); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public int showDialog(Component parent, String approveButtonText) { |
||||
dialog.setModal(true); |
||||
dialog.setVisible(true); |
||||
return retVal; |
||||
} |
||||
|
||||
@Override |
||||
public void approveSelection() { |
||||
retVal = APPROVE_OPTION; |
||||
if (dialog != null) { |
||||
dialog.setVisible(false); |
||||
} |
||||
fireActionPerformed(APPROVE_SELECTION); |
||||
} |
||||
|
||||
@Override |
||||
public void cancelSelection() { |
||||
retVal = CANCEL_OPTION; |
||||
if (dialog != null) { |
||||
dialog.setVisible(false); |
||||
} |
||||
fireActionPerformed(CANCEL_SELECTION); |
||||
} |
||||
|
||||
@Override |
||||
public boolean getControlButtonsAreShown() { |
||||
return false;//隐藏默认的控制按钮(打开/取消)
|
||||
} |
||||
|
||||
private class ImageAreaLayout implements LayoutManager { |
||||
private static final int TEN = 10; |
||||
private int hGap = 5; |
||||
private int topMargin = TEN; |
||||
private int leftMargin = TEN; |
||||
private int leftStart = 8; |
||||
|
||||
@Override |
||||
public void addLayoutComponent(String string, Component comp) { |
||||
} |
||||
|
||||
@Override |
||||
public void layoutContainer(Container container) { |
||||
Component[] children = container.getComponents(); |
||||
|
||||
if (children != null && children.length > 0) { |
||||
int numChildren = children.length; |
||||
Dimension[] sizes = new Dimension[numChildren]; |
||||
Insets insets = container.getInsets(); |
||||
int yLocation = insets.top + topMargin; |
||||
int maxWidth = 0; |
||||
|
||||
for (int counter = 0; counter < numChildren; counter++) { |
||||
sizes[counter] = children[counter].getPreferredSize(); |
||||
maxWidth = Math.max(maxWidth, sizes[counter].width); |
||||
} |
||||
int xLocation, xOffset; |
||||
if (container.getComponentOrientation().isLeftToRight()) { |
||||
xLocation = container.getSize().width - insets.left - maxWidth - leftMargin; |
||||
xOffset = hGap + maxWidth; |
||||
} else { |
||||
xLocation = insets.left; |
||||
xOffset = -(hGap + maxWidth); |
||||
} |
||||
//单独设置图片压缩按钮的位置
|
||||
children[0].setBounds(leftStart, yLocation, |
||||
maxWidth, sizes[0].height); |
||||
|
||||
for (int counter = numChildren - 1; counter >= 1; counter--) { |
||||
children[counter].setBounds(xLocation, yLocation, |
||||
maxWidth, sizes[counter].height); |
||||
xLocation -= xOffset; |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public Dimension minimumLayoutSize(Container c) { |
||||
if (c != null) { |
||||
Component[] children = c.getComponents(); |
||||
|
||||
if (children != null && children.length > 0) { |
||||
int numChildren = children.length; |
||||
int height = 0; |
||||
Insets cInsets = c.getInsets(); |
||||
int extraHeight = topMargin + cInsets.top + cInsets.bottom; |
||||
int extraWidth = cInsets.left + cInsets.right; |
||||
int maxWidth = 0; |
||||
|
||||
for (int counter = 0; counter < numChildren; counter++) { |
||||
Dimension aSize = children[counter].getPreferredSize(); |
||||
height = Math.max(height, aSize.height); |
||||
maxWidth = Math.max(maxWidth, aSize.width); |
||||
} |
||||
return new Dimension(extraWidth + numChildren * maxWidth + |
||||
(numChildren - 1) * hGap, |
||||
extraHeight + height); |
||||
} |
||||
} |
||||
return new Dimension(0, 0); |
||||
} |
||||
|
||||
@Override |
||||
public Dimension preferredLayoutSize(Container c) { |
||||
return minimumLayoutSize(c); |
||||
} |
||||
|
||||
@Override |
||||
public void removeLayoutComponent(Component c) { |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,525 @@
|
||||
package com.fr.plugin.external; |
||||
|
||||
/* |
||||
* Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved. |
||||
*/ |
||||
|
||||
import com.fr.base.Base64; |
||||
import com.fr.base.GraphHelper; |
||||
import com.fr.base.background.AbstractBackground; |
||||
import com.fr.base.background.ImageSerializable; |
||||
import com.fr.general.Background; |
||||
import com.fr.general.ComparatorUtils; |
||||
import com.fr.json.JSONException; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.plugin.ExtraClassManager; |
||||
import com.fr.stable.BaseConstants; |
||||
import com.fr.stable.CheckOut; |
||||
import com.fr.stable.CodeUtils; |
||||
import com.fr.stable.Constants; |
||||
import com.fr.stable.CoreGraphHelper; |
||||
import com.fr.stable.StableUtils; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.fun.ImageLayoutDescriptionProcessor; |
||||
import com.fr.stable.fun.ServletURLTransformer; |
||||
import com.fr.stable.web.Repository; |
||||
import com.fr.stable.web.SessionProvider; |
||||
import com.fr.stable.xml.XMLPrintWriter; |
||||
import com.fr.stable.xml.XMLableReader; |
||||
import com.fr.web.RepositoryDeal; |
||||
import com.fr.web.core.SessionPoolManager; |
||||
|
||||
import java.awt.Dimension; |
||||
import java.awt.Graphics; |
||||
import java.awt.Graphics2D; |
||||
import java.awt.Image; |
||||
import java.awt.Paint; |
||||
import java.awt.Shape; |
||||
import java.awt.TexturePaint; |
||||
import java.awt.geom.Rectangle2D; |
||||
import java.awt.image.BufferedImage; |
||||
import java.io.IOException; |
||||
import java.io.ObjectOutputStream; |
||||
import java.util.UUID; |
||||
|
||||
/** |
||||
* 图片背景,该背景使用一张图片作为填充。 |
||||
*/ |
||||
public class ExternalImageBackground extends AbstractBackground { |
||||
private transient Image image = null; |
||||
private int layout = Constants.IMAGE_CENTER; //layout.
|
||||
//这个layout只是用来展示的,不保存进xml,因为图片远大于单元格时,会变成空白,需要动态改变layout以展示图片
|
||||
private int layout4Draw = Constants.IMAGE_CENTER; |
||||
|
||||
private double specifiedImageWidth = -1; |
||||
private double specifiedImageHeight = -1; |
||||
private String id; |
||||
|
||||
private static final int PAINT_WIDTH_OFFSET = 40; |
||||
private static final int PAINT_HEIGHT_OFFSET = 40; |
||||
|
||||
|
||||
/** |
||||
* 默认的构造函数 |
||||
*/ |
||||
public ExternalImageBackground() { |
||||
this(null, null); |
||||
} |
||||
|
||||
/** |
||||
* 根据指定图片生成的图片背景 |
||||
* |
||||
* @param image 给定的图片 |
||||
*/ |
||||
public ExternalImageBackground(Image image, String id) { |
||||
this(image, Constants.IMAGE_TILED, id); |
||||
} |
||||
|
||||
/** |
||||
* 根据指定的图片和布局方式生成的图片背景 |
||||
* |
||||
* @param image 给定的图片 |
||||
* @param layout 布局方式 |
||||
*/ |
||||
public ExternalImageBackground(Image image, int layout, String id) { |
||||
this.setImage(image); |
||||
this.setLayout(layout); |
||||
this.setId(id); |
||||
} |
||||
|
||||
/** |
||||
* 获取用于填充背景的图片 |
||||
* |
||||
* @return 图片 |
||||
*/ |
||||
public Image getImage() { |
||||
if (this.image == null) { |
||||
this.image = ImageManager.getInstance().findImageById(this.id); |
||||
} |
||||
|
||||
return this.image; |
||||
} |
||||
|
||||
/** |
||||
* 设置图片背景所使用的图片 |
||||
* |
||||
* @param image 背景所使用的图片 |
||||
*/ |
||||
public void setImage(Image image) { |
||||
this.image = image; |
||||
} |
||||
|
||||
/** |
||||
* 获取图片背景的布局方式 |
||||
* 可能的值包括Constants.IMAGE_DEFAULT、Constants.IMAGE_TILED、 |
||||
* Constants.IMAGE_CENTER和Constants.IMAGE_EXTEND |
||||
* 默认为Constants.IMAGE_DEFAULT |
||||
* |
||||
* @return 图片背景布局 |
||||
*/ |
||||
public int getLayout() { |
||||
return this.layout; |
||||
} |
||||
|
||||
public int getLayout4Draw() { |
||||
return layout4Draw == Constants.IMAGE_CENTER ? this.layout : layout4Draw; |
||||
} |
||||
|
||||
public void setLayout4Draw(int layout4Draw) { |
||||
this.layout4Draw = layout4Draw; |
||||
} |
||||
|
||||
/** |
||||
* 设置图片背景的布局方式 |
||||
* |
||||
* @param layout 布局方式 |
||||
* @see Constants#IMAGE_DEFAULT |
||||
* @see Constants#IMAGE_TILED |
||||
* @see Constants#IMAGE_CENTER |
||||
* @see Constants#IMAGE_EXTEND |
||||
*/ |
||||
public void setLayout(int layout) { |
||||
this.layout = layout; |
||||
} |
||||
|
||||
/** |
||||
* 获取用于指定图片背景中图片宽度的值 |
||||
* |
||||
* @return 自定义的图片宽度,如果该值为-1则使用原始图片的宽度 |
||||
*/ |
||||
public double getSpecifiedImageWidth() { |
||||
return specifiedImageWidth; |
||||
} |
||||
|
||||
/** |
||||
* 设置用于指定图片背景中图片宽度的值 |
||||
* |
||||
* @param specifiedImageWidth 自定义的图片宽度,如果想使用图片原始的宽度,则把该值设置为-1 |
||||
*/ |
||||
public void setSpecifiedImageWidth(double specifiedImageWidth) { |
||||
this.specifiedImageWidth = specifiedImageWidth; |
||||
} |
||||
|
||||
/** |
||||
* 获取用于指定图片背景中图片高度的值 |
||||
* |
||||
* @return 自定义的图片高度,如果该值为-1则使用原始图片的高度 |
||||
*/ |
||||
public double getSpecifiedImageHeight() { |
||||
return specifiedImageHeight; |
||||
} |
||||
|
||||
/** |
||||
* 设置用于指定图片背景中图片高度的值 |
||||
* |
||||
* @param specifiedImageHeight 自定义的图片高度,如果想使用图片原始的高度,则把该值设置为-1 |
||||
*/ |
||||
public void setSpecifiedImageHeight(double specifiedImageHeight) { |
||||
this.specifiedImageHeight = specifiedImageHeight; |
||||
} |
||||
|
||||
public String getId() { |
||||
return id; |
||||
} |
||||
|
||||
public void setId(String id) { |
||||
if (StringUtils.isEmpty(id)) { |
||||
id = UUID.randomUUID().toString(); |
||||
} |
||||
this.id = id; |
||||
} |
||||
|
||||
/** |
||||
* 根据指定的画图对象和几何图形来画图片背景 |
||||
* |
||||
* @param g 画图对象 |
||||
* @param shape 几何图形 |
||||
*/ |
||||
public void paint(Graphics g, Shape shape) { |
||||
if (this.getImage() == null || shape == null) { |
||||
return; |
||||
} |
||||
|
||||
Graphics2D g2d = (Graphics2D) g; |
||||
|
||||
Paint paint = g2d.getPaint(); |
||||
|
||||
g2d.setPaint(createPaint(shape, StableUtils.isNotSupportARGB(g2d))); |
||||
|
||||
g2d.fill(shape); |
||||
|
||||
g2d.setPaint(paint); |
||||
} |
||||
|
||||
/** |
||||
* 根据指定的画图对象和几何图形来画具有渐变色的边框的图片背景 |
||||
* |
||||
* @param g 画图对象 |
||||
* @param shape 几何图形 |
||||
*/ |
||||
public void drawWithGradientLine(Graphics g, Shape shape) { |
||||
if (this.getImage() == null || shape == null) { |
||||
return; |
||||
} |
||||
Graphics2D g2d = (Graphics2D) g; |
||||
|
||||
Paint paint = g2d.getPaint(); |
||||
g2d.setPaint(createPaint(shape, StableUtils.isNotSupportARGB(g2d))); |
||||
|
||||
g2d.draw(shape); |
||||
|
||||
g2d.setPaint(paint); |
||||
} |
||||
|
||||
/** |
||||
* 布局变化 |
||||
* |
||||
* @param width 背景宽度 |
||||
* @param height 背景高度 |
||||
*/ |
||||
public void layoutDidChange(int width, int height) { |
||||
int imageLayout = StableUtils.changeImageLayout4Draw(getImage(), getLayout(), width, height); |
||||
setLayout4Draw(imageLayout); |
||||
} |
||||
|
||||
private Paint createPaint(Shape shape, boolean isNotSupportARGB) { |
||||
Rectangle2D rec2D = shape.getBounds2D(); |
||||
if ((int) rec2D.getWidth() <= 0) { |
||||
rec2D.setRect(rec2D.getX(), rec2D.getY(), rec2D.getWidth() + PAINT_WIDTH_OFFSET, rec2D.getHeight()); |
||||
} |
||||
if ((int) rec2D.getHeight() <= 0) { |
||||
rec2D.setRect(rec2D.getX(), rec2D.getY(), rec2D.getWidth(), rec2D.getHeight() + PAINT_HEIGHT_OFFSET); |
||||
} |
||||
//daniel:查了一下flash的ARGB有BUG,不能使用ARGB,653没有使用TexturePaint直接用GraphHelper画的所以没问题
|
||||
BufferedImage buffered = new BufferedImage((int) rec2D.getWidth(), (int) rec2D.getHeight(), isNotSupportARGB ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB); |
||||
Graphics2D g2 = buffered.createGraphics(); |
||||
GraphHelper.paintImage(g2, (int) rec2D.getWidth(), (int) rec2D.getHeight(), this.getImage(), |
||||
// 默认的话. 图片是从左上开始画
|
||||
this.getLayout4Draw(), Constants.LEFT, Constants.TOP, (int) this.getSpecifiedImageWidth(), (int) this.getSpecifiedImageHeight(), isNotSupportARGB); |
||||
|
||||
g2.dispose(); |
||||
|
||||
return new TexturePaint(buffered, rec2D); |
||||
} |
||||
|
||||
/** |
||||
* 判断当前对象是否和指定的对象相等 |
||||
* |
||||
* @param obj 指定的对象 |
||||
* @return 相等则返回true,不相等则返回false |
||||
*/ |
||||
public boolean equals(Object obj) { |
||||
if (!(obj instanceof com.fr.plugin.external.ExternalImageBackground)) { |
||||
return false; |
||||
} |
||||
com.fr.plugin.external.ExternalImageBackground newImageBackground = (com.fr.plugin.external.ExternalImageBackground) obj; |
||||
|
||||
return this.getLayout() == newImageBackground.getLayout() && |
||||
ComparatorUtils.equals(this.id, newImageBackground.id) && |
||||
ComparatorUtils.equals(this.getImage(), newImageBackground.getImage()); |
||||
} |
||||
|
||||
/** |
||||
* 将背景输出成JSON对象 |
||||
* |
||||
* @return 表示背景的JSON对象 |
||||
* @throws JSONException |
||||
*/ |
||||
public JSONObject toJSONObject() throws JSONException { |
||||
JSONObject js = super.toJSONObject(); |
||||
|
||||
js.put("layout", this.layout); |
||||
js.put("specifiedImageHeight", this.specifiedImageHeight); |
||||
js.put("specifiedImageWidth", this.specifiedImageWidth); |
||||
js.put("image", Base64.encode(this.getImage(), "png")); |
||||
|
||||
if (this.getImage() != null) { |
||||
js.put("imgWidth", this.getImage().getWidth(null)); |
||||
js.put("imgHeight", this.getImage().getHeight(null)); |
||||
} |
||||
|
||||
return js; |
||||
} |
||||
|
||||
@Override |
||||
public JSONObject toJSONObject(Repository repo, Dimension size) throws JSONException { |
||||
JSONObject jo = toJSONObject(); |
||||
BufferedImage image = createBufferedImage(size.width, size.height); |
||||
if (image != null) { |
||||
jo.put("image", Base64.encode(image, "png")); |
||||
} |
||||
return jo; |
||||
} |
||||
|
||||
/** |
||||
* 图片背景在web端作为辨识的字符串 |
||||
* |
||||
* @return 返回用于表示图片背景类型的字符串 |
||||
*/ |
||||
public String getBackgroundType() { |
||||
return "ExternalImageBackground"; |
||||
} |
||||
|
||||
public Background readAdditionalAttr(XMLableReader reader) { |
||||
setSpecifiedImageWidth(reader.getAttrAsDouble("specifiedImageWidth", -1)); |
||||
setSpecifiedImageHeight(reader.getAttrAsDouble("specifiedImageHeight", -1)); |
||||
setLayout(reader.getAttrAsInt("layout", Constants.IMAGE_DEFAULT)); |
||||
this.id = reader.getAttrAsString("id", ""); |
||||
|
||||
return this; |
||||
} |
||||
|
||||
public void writeAdditionalAttr(XMLPrintWriter writer) { |
||||
writer.attr("class", ExternalImageBackground.class.getName()); |
||||
|
||||
//width/height
|
||||
writer.attr("specifiedImageWidth", getSpecifiedImageWidth()) |
||||
.attr("specifiedImageHeight", getSpecifiedImageHeight()) |
||||
.attr("layout", getLayout()) |
||||
.attr("id", this.id); |
||||
|
||||
} |
||||
|
||||
//august:下面两个方法是针对image序列化写的,image都已经transient了,所以必须要手动去实现啊!修复BUG:20299
|
||||
|
||||
/** |
||||
* Serializable, read. |
||||
*/ |
||||
private void readObject(java.io.ObjectInputStream s) throws ClassNotFoundException, java.io.IOException { |
||||
s.defaultReadObject(); |
||||
|
||||
Object obj = s.readObject(); |
||||
if (obj != null) { |
||||
if (obj instanceof ImageSerializable) { |
||||
this.image = ((ImageSerializable) obj).getImage(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Serializable, write. |
||||
*/ |
||||
private void writeObject(ObjectOutputStream stream) throws IOException { |
||||
stream.defaultWriteObject(); |
||||
if (image == null) { |
||||
image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); |
||||
} |
||||
ImageSerializable wrapper = new ImageSerializable(image); |
||||
stream.writeObject(wrapper); |
||||
} |
||||
|
||||
public JSONObject createJSONConfig(Repository repo) throws JSONException { |
||||
String url; |
||||
StringBuffer sb = new StringBuffer(); |
||||
// 取出图片
|
||||
url = changeBackgroudImageDisplayMode(repo, this.getDefaultImage(), BaseConstants.CHECKOUTIMAGE); |
||||
sb.append("url(").append(url).append(") "); |
||||
sb.append(createImageLayoutDescription(this.getLayout())); |
||||
|
||||
int type = this.getLayout(); |
||||
if (layout == Constants.IMAGE_ADJUST || layout == Constants.IMAGE_EXTEND) { |
||||
return adjustBackgroundJson(repo, url, sb, type); |
||||
} |
||||
|
||||
return JSONObject.create().put("background", sb.toString()); |
||||
|
||||
} |
||||
|
||||
public String changeBackgroudImageDisplayMode(Repository repo, Object source, String type) { |
||||
if (repo instanceof RepositoryDeal) { |
||||
String prefix = repo.getServletURL(); |
||||
ServletURLTransformer transformer = ExtraClassManager.getInstance().getSingle(ServletURLTransformer.XML_TAG); |
||||
if (source == null && ComparatorUtils.equals(BaseConstants.CHECKOUTIMAGE, type)) {// 返回一个空图片的地址
|
||||
if (transformer != null) { |
||||
prefix = transformer.prefixForImage(repo.getServletURL(), type); |
||||
} |
||||
|
||||
return prefix + "?op=resource&resource=/com/fr/web/images/s.gif"; |
||||
} else if (source instanceof JSONObject) { // 这边的type直接了. 没有判断类型的了.
|
||||
if (transformer != null) { |
||||
prefix = transformer.prefixForWrite(repo.getServletURL(), source, type); |
||||
} |
||||
JSONObject location = (JSONObject) source; |
||||
// 标识一下这个widget是所属什么report的,否则parameterpane里的widget就去显示报表里面去拿值了
|
||||
return prefix + "?op=widget" + (type == null ? "" : ("&ftype=" + type)) + "&location=" + location.toString() + "&sessionID=" + SessionPoolManager.getSessionIDInfor(repo.getSessionID(), SessionProvider.class).getSessionID(); |
||||
} else { |
||||
CheckOut check = CheckOut.getByValue(type); |
||||
if (transformer != null) { |
||||
prefix = transformer.prefixForResource(repo.getServletURL(), check); |
||||
} |
||||
switch (check) { |
||||
case CHECKOUTFORMLET: |
||||
return prefix + "?formlet=" + CodeUtils.encodeURIComponent(CodeUtils.cjkEncode((String) source)); |
||||
case CHECKOUTREPORTLET: |
||||
return prefix + "?reportlet=" + CodeUtils.encodeURIComponent(CodeUtils.cjkEncode((String) source)); |
||||
case CHECKOUTWIDGET: |
||||
return prefix + "?op=widget&widgetname=" + source + "&sessionID=" + SessionPoolManager.getSessionIDInfor(repo.getSessionID(), SessionProvider.class).getSessionID(); |
||||
case CHECKOUTIMAGE: |
||||
return checkOutImage(source, prefix, repo); |
||||
} |
||||
return StringUtils.EMPTY; |
||||
} |
||||
} else { |
||||
return repo.checkoutObject(source, type); |
||||
} |
||||
} |
||||
|
||||
private String checkOutImage(Object source, String prefix, Repository repo) { |
||||
if (!(source instanceof Image)) { |
||||
return StringUtils.EMPTY; |
||||
} |
||||
Image image = (Image) source; |
||||
if (repo.getDevice().isMobile()) { |
||||
return Base64.encode(image, "png"); |
||||
} else { |
||||
return prefix + "?op=fr_attach&cmd=ah_image&id=" + ImageManager.getInstance().findAttachId(id); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 按照指定的高度和宽度返回原图片背景的图片 |
||||
* |
||||
* @return 修改过高度和宽度的图片 |
||||
*/ |
||||
public Image getDefaultImage() { |
||||
int sw = (int) this.specifiedImageWidth; |
||||
int sh = (int) this.specifiedImageHeight; |
||||
if (sw == -1 && sh == -1) { |
||||
return this.getImage(); |
||||
} |
||||
int imageWidth; |
||||
if (sw == -1) { |
||||
imageWidth = this.getImage().getWidth(null); |
||||
} else { |
||||
imageWidth = sw; |
||||
} |
||||
|
||||
int imageHeight; |
||||
if (sh == -1) { |
||||
imageHeight = this.getImage().getHeight(null); |
||||
} else { |
||||
imageHeight = sh; |
||||
} |
||||
BufferedImage bufferedImage = CoreGraphHelper.createBufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB); |
||||
Graphics2D g2d = bufferedImage.createGraphics(); |
||||
this.paint(g2d, new Rectangle2D.Double(0, 0, imageWidth, imageHeight)); |
||||
bufferedImage.flush(); |
||||
g2d.dispose(); |
||||
return bufferedImage; |
||||
} |
||||
|
||||
private JSONObject adjustBackgroundJson(Repository repo, String url, StringBuffer sb, int type) throws JSONException { |
||||
JSONObject jo = JSONObject.create(); |
||||
// 拉伸和自适应需要在web端再做处理
|
||||
if (repo.getBrowser().isLowIEVersion()) { |
||||
jo.put("type", type); |
||||
jo.put("url", url); |
||||
// 这里生成参数面板背景的repo获取不到boxModel 而ie8杂项需要特别处理
|
||||
jo.put("background", sb.toString()); |
||||
jo.put("background-repeat", "no-repeat"); |
||||
jo.put("background-image", "none"); |
||||
jo.put("filter", "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + url + "',sizingMethod='scale')"); |
||||
return jo; |
||||
} |
||||
|
||||
jo.put("background", sb.toString()); |
||||
switch (type) { |
||||
case Constants.IMAGE_ADJUST: |
||||
jo.put("background-size", "contain"); |
||||
jo.put("background-position", "center"); |
||||
break; |
||||
case Constants.IMAGE_EXTEND: |
||||
jo.put("background-size", "100% 100%"); |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
return jo; |
||||
} |
||||
|
||||
private static String createImageLayoutDescription(int layout) { |
||||
ImageLayoutDescriptionProcessor processor = ExtraClassManager.getInstance().getSingle(ImageLayoutDescriptionProcessor.XML_TAG); |
||||
if (processor != null) { |
||||
String description = processor.getCustomLayoutDescription(layout); |
||||
if (StringUtils.isNotEmpty(description)) { |
||||
return description; |
||||
} |
||||
} |
||||
|
||||
switch (layout) { |
||||
case Constants.IMAGE_DEFAULT: |
||||
return "no-repeat"; |
||||
case Constants.IMAGE_ADJUST: |
||||
return "no-repeat"; |
||||
case Constants.IMAGE_CENTER: |
||||
return "no-repeat center"; |
||||
case Constants.IMAGE_TILED: |
||||
return "repeat"; |
||||
case Constants.IMAGE_EXTEND: |
||||
return "no-repeat center"; |
||||
default: |
||||
return StringUtils.EMPTY; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,49 @@
|
||||
package com.fr.plugin.external; |
||||
|
||||
import com.fr.cache.Attachment; |
||||
import com.fr.cache.type.AttachmentScope; |
||||
import com.fr.web.AttachmentHelper; |
||||
|
||||
import java.awt.Image; |
||||
import java.util.concurrent.ExecutorService; |
||||
import java.util.concurrent.Executors; |
||||
|
||||
public class ImageBean { |
||||
|
||||
private Image image; |
||||
private Attachment attachment; |
||||
|
||||
public ImageBean(final Image image) { |
||||
this.image = image; |
||||
ExecutorService service = Executors.newSingleThreadExecutor(); |
||||
service.execute(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
// 可能已经在主线程初始化了.
|
||||
if (attachment != null) { |
||||
attachment = AttachmentHelper.addAttachment(image, AttachmentScope.HOLDER); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public Image getImage() { |
||||
return image; |
||||
} |
||||
|
||||
public void setImage(Image image) { |
||||
this.image = image; |
||||
} |
||||
|
||||
public Attachment getAttachment() { |
||||
if (attachment == null) { |
||||
attachment = AttachmentHelper.addAttachment(image, AttachmentScope.HOLDER); |
||||
} |
||||
|
||||
return attachment; |
||||
} |
||||
|
||||
public void setAttachment(Attachment attachment) { |
||||
this.attachment = attachment; |
||||
} |
||||
} |
@ -0,0 +1,256 @@
|
||||
/* |
||||
* Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved. |
||||
*/ |
||||
package com.fr.plugin.external; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.design.style.ChooseFileView; |
||||
|
||||
import javax.swing.filechooser.FileFilter; |
||||
import java.awt.Component; |
||||
import java.io.File; |
||||
import java.util.Enumeration; |
||||
import java.util.Hashtable; |
||||
|
||||
|
||||
/** |
||||
* 抄的9.0 的---为了8.0能用 |
||||
* This class used to choose image files. |
||||
* |
||||
* @deprecated |
||||
*/ |
||||
public class ImageFileChooser extends ExpandFileChooser { |
||||
|
||||
public ImageFileChooser(String compressText) { |
||||
super(compressText, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Open")); |
||||
ExampleFileFilter bothFilter = new ExampleFileFilter( |
||||
new String[]{"jpg", "gif", "png", "bmp"}, |
||||
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Image_Image_Files")); |
||||
bothFilter.setExtensionListInDescription(true); |
||||
this.addChoosableFileFilter(bothFilter); |
||||
this.setAcceptAllFileFilterUsed(false); |
||||
|
||||
// Create Custom FileView
|
||||
ChooseFileView fileView = new ChooseFileView(); |
||||
fileView.putIcon("jpg", BaseUtils.readIcon("/com/fr/base/images/dialog/file/jpgFile.gif")); |
||||
fileView.putIcon("gif", BaseUtils.readIcon("/com/fr/base/images/dialog/file/gifFile.gif")); |
||||
fileView.putIcon("png", BaseUtils.readIcon("/com/fr/base/images/dialog/file/pngFile.png")); |
||||
fileView.putIcon("bmp", BaseUtils.readIcon("/com/fr/base/images/dialog/file/bmpFile.gif")); |
||||
|
||||
this.setFileView(fileView); |
||||
} |
||||
|
||||
public int showDialog(Component parent, String approveButtonText) { |
||||
return super.showDialog(parent, approveButtonText); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* A convenience implementation of FileFilter that filters out |
||||
* all files except for those type extensions that it knows about. |
||||
* <p/>D:\finereport\develop\code\test\TestCase\WEB-INF\reportlets\TestCase\01903.cpt |
||||
* <p> |
||||
* Extensions are of the type ".foo", which is typically found on |
||||
* Windows and Unix boxes, but not on Macinthosh. Case is ignored. |
||||
* <p/> |
||||
* Example - create a new filter that filerts out all files |
||||
* but gif and jpg image files: |
||||
* <p/> |
||||
* JFileChooser chooser = new JFileChooser(); |
||||
* ExampleFileFilter filter = new ExampleFileFilter( |
||||
* new String{"gif", "jpg"}, "JPEG & GIF Images") |
||||
* chooser.addChoosableFileFilter(filter); |
||||
* chooser.showOpenDialog(this); |
||||
* |
||||
* @author Jeff Dinkins |
||||
* @version 1.12 12/03/01 |
||||
*/ |
||||
class ExampleFileFilter extends FileFilter { |
||||
private Hashtable filters = null; |
||||
private String description = null; |
||||
private String fullDescription = null; |
||||
private boolean useExtensionsInDescription = true; |
||||
|
||||
/** |
||||
* Creates a file filter. If no filters are added, then all |
||||
* files are accepted. |
||||
* |
||||
* @see #addExtension |
||||
*/ |
||||
public ExampleFileFilter() { |
||||
this.filters = new Hashtable(); |
||||
} |
||||
|
||||
/** |
||||
* Creates a file filter that accepts files with the given extension. |
||||
* Example: new ExampleFileFilter("jpg"); |
||||
* |
||||
* @see #addExtension |
||||
*/ |
||||
public ExampleFileFilter(String extension) { |
||||
this(extension, null); |
||||
} |
||||
|
||||
/** |
||||
* Creates a file filter that accepts the given file type. |
||||
* Example: new ExampleFileFilter("jpg", "JPEG Image Images"); |
||||
* <p/> |
||||
* Note that the "." before the extension is not needed. If |
||||
* provided, it will be ignored. |
||||
* |
||||
* @see #addExtension |
||||
*/ |
||||
public ExampleFileFilter(String extension, String description) { |
||||
this(); |
||||
if (extension != null) addExtension(extension); |
||||
if (description != null) setDescription(description); |
||||
} |
||||
|
||||
/** |
||||
* Creates a file filter from the given string array. |
||||
* Example: new ExampleFileFilter(String {"gif", "jpg"}); |
||||
* <p/> |
||||
* Note that the "." before the extension is not needed adn |
||||
* will be ignored. |
||||
* |
||||
* @see #addExtension |
||||
*/ |
||||
public ExampleFileFilter(String[] filters) { |
||||
this(filters, null); |
||||
} |
||||
|
||||
/** |
||||
* Creates a file filter from the given string array and description. |
||||
* Example: new ExampleFileFilter(String {"gif", "jpg"}, "Gif and JPG Images"); |
||||
* <p/> |
||||
* Note that the "." before the extension is not needed and will be ignored. |
||||
* |
||||
* @see #addExtension |
||||
*/ |
||||
public ExampleFileFilter(String[] filters, String description) { |
||||
this(); |
||||
for (int i = 0; i < filters.length; i++) { |
||||
// add filters one by one
|
||||
addExtension(filters[i]); |
||||
} |
||||
if (description != null) setDescription(description); |
||||
} |
||||
|
||||
/** |
||||
* Return true if this file should be shown in the directory pane, |
||||
* false if it shouldn't. |
||||
* <p/> |
||||
* Files that begin with "." are ignored. |
||||
* |
||||
* @see #getExtension |
||||
*/ |
||||
public boolean accept(File f) { |
||||
if (f != null) { |
||||
if (f.isDirectory()) { |
||||
return true; |
||||
} |
||||
String extension = getExtension(f); |
||||
if (extension != null && filters.get(getExtension(f)) != null) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Return the extension portion of the file's name . |
||||
* |
||||
* @see #getExtension |
||||
* @see FileFilter#accept |
||||
*/ |
||||
public String getExtension(File f) { |
||||
if (f != null) { |
||||
String filename = f.getName(); |
||||
int i = filename.lastIndexOf('.'); |
||||
if (i > 0 && i < filename.length() - 1) { |
||||
return filename.substring(i + 1).toLowerCase(); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Adds a filetype "dot" extension to filter against. |
||||
* <p/> |
||||
* For example: the following code will create a filter that filters |
||||
* out all files except those that end in ".jpg" and ".tif": |
||||
* <p/> |
||||
* ExampleFileFilter filter = new ExampleFileFilter(); |
||||
* filter.addExtension("jpg"); |
||||
* filter.addExtension("tif"); |
||||
* <p/> |
||||
* Note that the "." before the extension is not needed and will be ignored. |
||||
*/ |
||||
public void addExtension(String extension) { |
||||
if (filters == null) { |
||||
filters = new Hashtable(5); |
||||
} |
||||
filters.put(extension.toLowerCase(), this); |
||||
fullDescription = null; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Returns the human readable description of this filter. For |
||||
* example: "JPEG and GIF Image Files (*.jpg, *.gif)" |
||||
* |
||||
* @see FileFilter#getDescription |
||||
*/ |
||||
public String getDescription() { |
||||
if (fullDescription == null) { |
||||
if (description == null || isExtensionListInDescription()) { |
||||
fullDescription = description == null ? "(" : description + " ("; |
||||
// build the description from the extension list
|
||||
Enumeration extensions = filters.keys(); |
||||
if (extensions != null) { |
||||
fullDescription += "." + extensions.nextElement(); |
||||
while (extensions.hasMoreElements()) { |
||||
fullDescription += ", ." + extensions.nextElement(); |
||||
} |
||||
} |
||||
fullDescription += ")"; |
||||
} else { |
||||
fullDescription = description; |
||||
} |
||||
} |
||||
return fullDescription; |
||||
} |
||||
|
||||
/** |
||||
* Sets the human readable description of this filter. For |
||||
* example: filter.setDescription("Gif and JPG Images"); |
||||
*/ |
||||
public void setDescription(String description) { |
||||
this.description = description; |
||||
fullDescription = null; |
||||
} |
||||
|
||||
/** |
||||
* Determines whether the extension list (.jpg, .gif, etc) should |
||||
* show up in the human readable description. |
||||
* <p/> |
||||
* Only relevent if a description was provided in the constructor |
||||
* or using setDescription(); |
||||
*/ |
||||
public void setExtensionListInDescription(boolean b) { |
||||
useExtensionsInDescription = b; |
||||
fullDescription = null; |
||||
} |
||||
|
||||
/** |
||||
* Returns whether the extension list (.jpg, .gif, etc) should |
||||
* show up in the human readable description. |
||||
* <p/> |
||||
* Only relevent if a description was provided in the constructor |
||||
* or using setDescription(); |
||||
*/ |
||||
public boolean isExtensionListInDescription() { |
||||
return useExtensionsInDescription; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,211 @@
|
||||
package com.fr.plugin.external; |
||||
|
||||
import com.fr.base.FRContext; |
||||
import com.fr.general.IOUtils; |
||||
import com.fr.general.xml.GeneralXMLTools; |
||||
import com.fr.stable.CoreGraphHelper; |
||||
import com.fr.stable.StableUtils; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.project.ProjectConstants; |
||||
import com.fr.workspace.WorkContext; |
||||
|
||||
import java.awt.Image; |
||||
import java.io.File; |
||||
import java.io.FileInputStream; |
||||
import java.io.FileOutputStream; |
||||
import java.io.IOException; |
||||
import java.util.Map; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
import java.util.concurrent.ExecutorService; |
||||
import java.util.concurrent.Executors; |
||||
|
||||
public class ImageManager { |
||||
|
||||
private static ImageManager manager; |
||||
private static Image EMPTY = CoreGraphHelper.createBufferedImage(0, 0); |
||||
|
||||
public static ImageManager getInstance() { |
||||
if (manager == null) { |
||||
manager = new ImageManager(); |
||||
} |
||||
|
||||
return manager; |
||||
} |
||||
|
||||
private Map<String, ImageBean> cachedMap = new ConcurrentHashMap<String, ImageBean>(); |
||||
private ExecutorService executorService = Executors.newSingleThreadExecutor(); |
||||
private boolean compress = true; |
||||
|
||||
public void release() { |
||||
cachedMap.clear(); |
||||
executorService.shutdown(); |
||||
} |
||||
|
||||
public void updateImage(ExternalImageBackground background) { |
||||
updateImage(background.getId(), background.getImage()); |
||||
} |
||||
|
||||
public void updateImage(String id, Image image) { |
||||
updateImage(id, image, true); |
||||
} |
||||
|
||||
public void updateImage(String id, Image image, boolean save) { |
||||
if (StringUtils.isNotEmpty(id) && image != null) { |
||||
cachedMap.put(id, new ImageBean(image)); |
||||
if (save) { |
||||
saveImageToFile(image, id); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public void removeImage(String id) { |
||||
cachedMap.remove(id); |
||||
} |
||||
|
||||
public String[] listAllIds() { |
||||
updateImageFromDisk(); |
||||
return cachedMap.keySet().toArray(new String[cachedMap.size()]); |
||||
} |
||||
|
||||
public Image findImageById(String id) { |
||||
ImageBean result = cachedMap.get(id); |
||||
if (result == null) { |
||||
updateImageFromDisk(id); |
||||
result = cachedMap.get(id); |
||||
if (result == null) { |
||||
return EMPTY; |
||||
} |
||||
} |
||||
|
||||
return result.getImage(); |
||||
} |
||||
|
||||
public String findAttachId(String id) { |
||||
ImageBean result = cachedMap.get(id); |
||||
if (result == null) { |
||||
updateImageFromDisk(id); |
||||
result = cachedMap.get(id); |
||||
if (result == null) { |
||||
return StringUtils.EMPTY; |
||||
} |
||||
} |
||||
|
||||
return result.getAttachment().getID(); |
||||
} |
||||
|
||||
public boolean isCompress() { |
||||
return compress; |
||||
} |
||||
|
||||
public void setCompress(boolean compress) { |
||||
this.compress = compress; |
||||
} |
||||
|
||||
public void updateImageFromDisk() { |
||||
String path = StableUtils.pathJoin(WorkContext.getCurrent().getPath(), |
||||
ProjectConstants.ASSETS_NAME, "background"); |
||||
File imageFolder = new File(path); |
||||
if (!imageFolder.exists()) { |
||||
return; |
||||
} |
||||
|
||||
File[] images = imageFolder.listFiles(); |
||||
for (File imageFile : images) { |
||||
String name = imageFile.getName(); |
||||
String id = name.substring(0, name.lastIndexOf(".")); |
||||
if(cachedMap.containsKey(id)) { |
||||
continue; |
||||
} |
||||
|
||||
try { |
||||
byte[] content = IOUtils.inputStream2Bytes(new FileInputStream(imageFile)); |
||||
Image image = GeneralXMLTools.imageDecode(content); |
||||
updateImage(id, image, false); |
||||
} catch (Throwable e) { |
||||
FRContext.getLogger().debug("Image read failed: " + e.getMessage() + " id: " + id); |
||||
} |
||||
} |
||||
} |
||||
public void updateImageFromDisk(String targetId) { |
||||
String path = StableUtils.pathJoin(WorkContext.getCurrent().getPath(), |
||||
ProjectConstants.ASSETS_NAME, "background"); |
||||
File imageFolder = new File(path); |
||||
if (!imageFolder.exists()) { |
||||
return; |
||||
} |
||||
|
||||
File[] images = imageFolder.listFiles(); |
||||
for (File imageFile : images) { |
||||
String name = imageFile.getName(); |
||||
int dotIndex = name.lastIndexOf("."); |
||||
if (dotIndex <= 0) { |
||||
continue; |
||||
} |
||||
String id = name.substring(0, dotIndex); |
||||
if(cachedMap.containsKey(id) || !targetId.equals(id)) { |
||||
continue; |
||||
} |
||||
|
||||
try { |
||||
byte[] content = IOUtils.inputStream2Bytes(new FileInputStream(imageFile)); |
||||
Image image = GeneralXMLTools.imageDecode(content); |
||||
updateImage(id, image, false); |
||||
} catch (Throwable e) { |
||||
FRContext.getLogger().debug("Image read failed: " + e.getMessage() + " id: " + id); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void cacheAllImage() { |
||||
executorService.execute(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
if(!(WorkContext.getCurrent().isLocal())) { |
||||
FRContext.getLogger().error("图片外置不支持远程设计!"); |
||||
return; |
||||
} |
||||
|
||||
String path = StableUtils.pathJoin(WorkContext.getCurrent().getPath(), |
||||
ProjectConstants.ASSETS_NAME, "background"); |
||||
File imageFolder = new File(path); |
||||
if (!imageFolder.exists()) { |
||||
return; |
||||
} |
||||
|
||||
File[] images = imageFolder.listFiles(); |
||||
for (File imageFile : images) { |
||||
String name = imageFile.getName(); |
||||
String id = name.substring(0, name.lastIndexOf(".")); |
||||
try { |
||||
byte[] content = IOUtils.inputStream2Bytes(new FileInputStream(imageFile)); |
||||
Image image = GeneralXMLTools.imageDecode(content); |
||||
updateImage(id, image, false); |
||||
} catch (Throwable e) { |
||||
FRContext.getLogger().debug("Image read failed: " + e.getMessage() + " id: " + id); |
||||
} |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
private void saveImageToFile(final Image image, final String id) { |
||||
executorService.execute(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
// 存到磁盘
|
||||
String path = StableUtils.pathJoin(WorkContext.getCurrent().getPath(), |
||||
ProjectConstants.ASSETS_NAME, "background", id + ".png"); |
||||
File imageFile = new File(path); |
||||
try { |
||||
StableUtils.makesureFileExist(imageFile); |
||||
FileOutputStream out = new FileOutputStream(imageFile); |
||||
IOUtils.writeImage(image, "png", out); |
||||
out.close(); |
||||
} catch (IOException e) { |
||||
FRContext.getLogger().error(e.getMessage()); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,181 @@
|
||||
package com.fr.plugin.external; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.general.ComparatorUtils; |
||||
import com.fr.general.FRLogger; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.imageio.IIOImage; |
||||
import javax.imageio.ImageIO; |
||||
import javax.imageio.ImageReader; |
||||
import javax.imageio.ImageWriteParam; |
||||
import javax.imageio.ImageWriter; |
||||
import javax.imageio.stream.ImageInputStream; |
||||
import javax.imageio.stream.ImageOutputStream; |
||||
import java.awt.Graphics; |
||||
import java.awt.image.BufferedImage; |
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.util.Iterator; |
||||
|
||||
/** |
||||
* 抄的9.0 的---为了8.0能用 |
||||
* 设计器部分的图片处理工具类 |
||||
* Created by zack on 2018/3/8. |
||||
* @deprecated |
||||
*/ |
||||
public class ImageUtils { |
||||
|
||||
/** |
||||
* 默认压缩算法,采用75%质量压缩 |
||||
* |
||||
* @param imageFile 原文件 |
||||
* @return 压缩后的BufferedImage对象 |
||||
*/ |
||||
|
||||
public static BufferedImage defaultImageCompress(File imageFile) { |
||||
try { |
||||
return imageCompress(imageFile, 0.75f);//默认75%质量
|
||||
} catch (IOException e) { |
||||
FRLogger.getLogger().info("image compress failed!"); |
||||
|
||||
} |
||||
return BaseUtils.readImage(imageFile.getPath()); |
||||
} |
||||
|
||||
/** |
||||
* 图片压缩 |
||||
* |
||||
* @param imageFile 原文件 |
||||
* @param quality 质量系数(0-1) |
||||
* @return 压缩后的图片 |
||||
* @throws IOException |
||||
*/ |
||||
public static BufferedImage imageCompress(File imageFile, float quality) throws IOException { |
||||
if (imageFile == null) { |
||||
return null; |
||||
} |
||||
BufferedImage result = BaseUtils.readImage(imageFile.getPath()); |
||||
if (canbeCompressedToJPEG(imageFile)) { |
||||
return jpegCompress(result, quality); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
public static boolean canbeCompressedToJPEG(File imageFile) { |
||||
if (ComparatorUtils.equals(getImageType(imageFile), "JPEG")) {//JPEG大写
|
||||
return true; |
||||
} |
||||
if (ComparatorUtils.equals(getImageType(imageFile), "png")) {//png小写
|
||||
return !isAlphaAreaOverload(imageFile);//少量透明度系数的png直接压缩jpg
|
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* JPEG格式图片压缩 |
||||
* |
||||
* @param image 压缩源图片 |
||||
* @param quality 压缩质量,在0-1之间, |
||||
* @return 返回的字节数组 |
||||
*/ |
||||
public static BufferedImage jpegCompress(BufferedImage image, float quality) throws IOException { |
||||
if (image == null) { |
||||
return null; |
||||
} |
||||
// 得到指定Format图片的writer
|
||||
Iterator<ImageWriter> iter = ImageIO |
||||
.getImageWritersByFormatName("jpeg");// 得到迭代器
|
||||
ImageWriter writer = iter.next(); |
||||
|
||||
// 得到指定writer的输出参数设置(ImageWriteParam )
|
||||
ImageWriteParam iwp = writer.getDefaultWriteParam(); |
||||
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // 设置可否压缩
|
||||
iwp.setCompressionQuality(quality); // 设置压缩质量参数
|
||||
iwp.setProgressiveMode(ImageWriteParam.MODE_DISABLED); |
||||
|
||||
// 开始打包图片,写入byte[]
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); |
||||
ImageOutputStream ios = null; |
||||
ByteArrayInputStream in = null; |
||||
try { |
||||
image = copy(image, BufferedImage.TYPE_INT_RGB); |
||||
ios = ImageIO.createImageOutputStream(byteArrayOutputStream); |
||||
writer.setOutput(ios); |
||||
writer.write(null, new IIOImage(image, null, null), iwp); |
||||
in = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); |
||||
if (ios == null || in == null) { |
||||
throw new IOException("The image file cannot be compressed"); |
||||
} |
||||
return ImageIO.read(in); |
||||
} finally { |
||||
writer.dispose(); |
||||
ios.close(); |
||||
byteArrayOutputStream.close(); |
||||
in.close(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 判断图片中是否包含多于5%的透明区域,这个5%随便定的 |
||||
* |
||||
* @param imageFile 目标图片 |
||||
* @return 含透明度像素占比 |
||||
*/ |
||||
public static boolean isAlphaAreaOverload(File imageFile) { |
||||
if (imageFile == null || !imageFile.isFile()) { |
||||
return false; |
||||
} |
||||
BufferedImage bufferedImage = BaseUtils.readImage(imageFile.getPath()); |
||||
int width = bufferedImage.getWidth(); |
||||
int height = bufferedImage.getHeight(); |
||||
long alphaCount = 0; |
||||
for (int i = 0; i < width; i++) { |
||||
for (int j = 0; j < height; j++) { |
||||
int rgb = bufferedImage.getRGB(i, j); |
||||
int a = (0xff & (rgb >> 24)); |
||||
if (a != 0xff) { |
||||
alphaCount++; |
||||
} |
||||
} |
||||
} |
||||
return alphaCount / (double) (width * height) > 0.05; |
||||
} |
||||
|
||||
/** |
||||
* 获取图片类型 |
||||
* |
||||
* @param imageFile 图片文件 |
||||
* @return 图片类型(JPEG, PNG, GIF) |
||||
*/ |
||||
public static String getImageType(File imageFile) { |
||||
try { |
||||
ImageInputStream iis = ImageIO.createImageInputStream(imageFile); |
||||
Iterator<ImageReader> iter = ImageIO.getImageReaders(iis); |
||||
if (!iter.hasNext()) { |
||||
return StringUtils.EMPTY; |
||||
} |
||||
ImageReader reader = iter.next(); |
||||
iis.close(); |
||||
return reader.getFormatName(); |
||||
} catch (IOException ignore) { |
||||
} |
||||
return StringUtils.EMPTY; |
||||
} |
||||
|
||||
private static BufferedImage copy(BufferedImage img, int imageType) { |
||||
int width = img.getWidth(); |
||||
int height = img.getHeight(); |
||||
|
||||
BufferedImage newImage = new BufferedImage(width, height, imageType); |
||||
Graphics g = newImage.createGraphics(); |
||||
|
||||
g.drawImage(img, 0, 0, null); |
||||
|
||||
g.dispose(); |
||||
|
||||
return newImage; |
||||
} |
||||
} |
@ -0,0 +1,14 @@
|
||||
package com.fr.plugin.external.design; |
||||
|
||||
import com.fr.design.fun.impl.AbstractBackgroundQuickUIProvider; |
||||
import com.fr.design.mainframe.backgroundpane.BackgroundQuickPane; |
||||
|
||||
/** |
||||
* Created by Administrator on 2017/9/10/0010. |
||||
*/ |
||||
public class ExternalBackgroundUI extends AbstractBackgroundQuickUIProvider { |
||||
@Override |
||||
public BackgroundQuickPane appearanceForBackground() { |
||||
return new ExternalImageBackgroundQuickPane(); |
||||
} |
||||
} |
@ -0,0 +1,238 @@
|
||||
package com.fr.plugin.external.design; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.base.Style; |
||||
import com.fr.design.border.UIRoundedBorder; |
||||
import com.fr.design.constants.UIConstants; |
||||
import com.fr.design.event.UIObserverListener; |
||||
import com.fr.design.gui.ibutton.UIButton; |
||||
import com.fr.design.gui.ibutton.UIButtonGroup; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
import com.fr.design.mainframe.backgroundpane.BackgroundQuickPane; |
||||
import com.fr.design.mainframe.backgroundpane.ImagePreviewPane; |
||||
import com.fr.general.Background; |
||||
import com.fr.general.GeneralUtils; |
||||
import com.fr.plugin.external.ExternalImageBackground; |
||||
import com.fr.plugin.external.ImageFileChooser; |
||||
import com.fr.plugin.external.ImageManager; |
||||
import com.fr.plugin.external.ImageUtils; |
||||
import com.fr.stable.Constants; |
||||
import com.fr.stable.CoreGraphHelper; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.swing.JFileChooser; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.SwingWorker; |
||||
import javax.swing.event.ChangeEvent; |
||||
import javax.swing.event.ChangeListener; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.Dimension; |
||||
import java.awt.GridLayout; |
||||
import java.awt.Image; |
||||
import java.awt.event.ActionEvent; |
||||
import java.awt.event.ActionListener; |
||||
import java.io.File; |
||||
import java.lang.reflect.Method; |
||||
import java.util.UUID; |
||||
|
||||
/** |
||||
* @author zhou |
||||
* @since 2012-5-29下午1:12:06 |
||||
*/ |
||||
public class ExternalImageBackgroundQuickPane extends BackgroundQuickPane { |
||||
|
||||
private ImagePreviewPane previewPane; |
||||
private Style imageStyle = null; |
||||
private ChangeListener changeListener = null; |
||||
private ImageFileChooser imageFileChooser; |
||||
private UIButtonGroup<Byte> imageLayoutPane; |
||||
private String cachedId; |
||||
private SwingWorker<Void, Void> imageWorker; |
||||
|
||||
public ExternalImageBackgroundQuickPane() { |
||||
this(true); |
||||
} |
||||
|
||||
public ExternalImageBackgroundQuickPane(boolean hasImageLayout) { |
||||
this.setLayout(new BorderLayout(0, 4)); |
||||
String[] nameArray = {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Background_Image_Default"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Background_Image_Titled"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Background_Image_Extend"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Background_Image_Adjust")}; |
||||
Byte[] valueArray = {Constants.IMAGE_CENTER, Constants.IMAGE_TILED, Constants.IMAGE_EXTEND, Constants.IMAGE_ADJUST}; |
||||
imageLayoutPane = new UIButtonGroup<Byte>(nameArray, valueArray); |
||||
imageLayoutPane.setSelectedIndex(0); |
||||
|
||||
previewPane = new ImagePreviewPane(); |
||||
JPanel borderPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
borderPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, 5)); |
||||
borderPane.setPreferredSize(new Dimension(0, 145)); |
||||
borderPane.add(previewPane, BorderLayout.CENTER); |
||||
this.add(borderPane, BorderLayout.NORTH); |
||||
previewPane.addChangeListener(imageSizeChangeListener); |
||||
|
||||
JPanel southPane = new JPanel(new BorderLayout(0, 4)); |
||||
JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
contentPane.add(southPane, BorderLayout.NORTH); |
||||
this.add(contentPane, BorderLayout.CENTER); |
||||
|
||||
JPanel selectFilePane = new JPanel(new GridLayout(0, 2)); |
||||
|
||||
UIButton selectPictureButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Image_Select_Picture")); |
||||
selectFilePane.add(new JPanel()); |
||||
selectFilePane.add(selectPictureButton); |
||||
selectPictureButton.addActionListener(selectPictureActionListener); |
||||
|
||||
if (hasImageLayout) { |
||||
southPane.add(imageLayoutPane, BorderLayout.CENTER); |
||||
} |
||||
southPane.add(selectFilePane, BorderLayout.SOUTH); |
||||
|
||||
imageLayoutPane.addChangeListener(new ChangeListener() { |
||||
|
||||
@Override |
||||
public void stateChanged(ChangeEvent e) { |
||||
imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(imageLayoutPane.getSelectedItem()); |
||||
previewPane.setImageStyle(imageStyle); |
||||
previewPane.repaint(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* Select picture. |
||||
*/ |
||||
ActionListener selectPictureActionListener = new ActionListener() { |
||||
|
||||
public void actionPerformed(ActionEvent evt) { |
||||
if (imageFileChooser == null) { |
||||
String compressText = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Image_Compress"); |
||||
try { |
||||
GeneralUtils.classForName("com.fr.design.utils.ImageUtils"); |
||||
} catch (ClassNotFoundException e) { |
||||
compressText = StringUtils.EMPTY; |
||||
} |
||||
imageFileChooser = new ImageFileChooser(compressText); |
||||
imageFileChooser.setMultiSelectionEnabled(false); |
||||
} |
||||
int returnVal = imageFileChooser.showOpenDialog(DesignerContext.getDesignerFrame()); |
||||
if (returnVal != JFileChooser.CANCEL_OPTION) { |
||||
final File selectedFile = imageFileChooser.getSelectedFile(); |
||||
|
||||
if (selectedFile != null && selectedFile.isFile()) { |
||||
if (previewPane != null) { |
||||
Class<?> cls = null; |
||||
try { |
||||
cls = Class.forName("com.fr.design.mainframe.backgroundpane.ImagePreviewPane"); |
||||
Method loading = cls.getMethod("showLoading"); |
||||
loading.invoke(previewPane); |
||||
} catch (Exception ignore) { |
||||
|
||||
} |
||||
} |
||||
if (imageWorker != null && !imageWorker.isDone()) { |
||||
imageWorker = null; |
||||
} |
||||
imageWorker = new SwingWorker<Void, Void>() { |
||||
@Override |
||||
protected Void doInBackground() throws Exception { |
||||
Image image = imageFileChooser.isCompressSelected() ? ImageUtils.defaultImageCompress(selectedFile) : BaseUtils.readImage(selectedFile.getPath()); |
||||
CoreGraphHelper.waitForImage(image); |
||||
if (cachedId == null) { |
||||
cachedId = UUID.randomUUID().toString(); |
||||
} |
||||
previewPane.setImage(image); |
||||
imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(imageLayoutPane.getSelectedItem()); |
||||
previewPane.setImageStyle(imageStyle); |
||||
previewPane.repaint(); |
||||
fireChagneListener(); |
||||
return null; |
||||
} |
||||
}; |
||||
imageWorker.execute(); |
||||
} else { |
||||
previewPane.setImage(null); |
||||
} |
||||
} |
||||
|
||||
} |
||||
}; |
||||
|
||||
public void populateBean(Background background) { |
||||
ExternalImageBackground imageBackground = (ExternalImageBackground) background; |
||||
this.cachedId = imageBackground.getId(); |
||||
imageLayoutPane.setSelectedItem((byte) imageBackground.getLayout()); |
||||
Style.DEFAULT_STYLE.deriveImageLayout(imageBackground.getLayout()); |
||||
|
||||
previewPane.setImageStyle(ExternalImageBackgroundQuickPane.this.imageStyle); |
||||
previewPane.setImage(imageBackground.getImage()); |
||||
previewPane.repaint(); |
||||
} |
||||
|
||||
public Background updateBean() { |
||||
ExternalImageBackground imageBackground = new ExternalImageBackground(previewPane.getImage(), this.cachedId); |
||||
imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(imageLayoutPane.getSelectedItem()); |
||||
imageBackground.setLayout(imageStyle.getImageLayout()); |
||||
if (this.cachedId != null) { |
||||
ImageManager.getInstance().updateImage(imageBackground); |
||||
} |
||||
return imageBackground; |
||||
} |
||||
|
||||
/** |
||||
* 给组件登记一个观察者监听事件 |
||||
* |
||||
* @param listener 观察者监听事件 |
||||
*/ |
||||
public void registerChangeListener(final UIObserverListener listener) { |
||||
changeListener = new ChangeListener() { |
||||
public void stateChanged(ChangeEvent e) { |
||||
listener.doChange(); |
||||
} |
||||
}; |
||||
imageLayoutPane.addChangeListener(changeListener); |
||||
} |
||||
|
||||
|
||||
private void fireChagneListener() { |
||||
if (this.changeListener != null) { |
||||
ChangeEvent evt = new ChangeEvent(this); |
||||
this.changeListener.stateChanged(evt); |
||||
} |
||||
} |
||||
|
||||
ChangeListener imageSizeChangeListener = new ChangeListener() { |
||||
|
||||
public void stateChanged(ChangeEvent evt) { |
||||
if (imageLayoutPane.getSelectedItem() != null) { |
||||
imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(imageLayoutPane.getSelectedItem()); |
||||
previewPane.setImageStyle(imageStyle); |
||||
previewPane.repaint(); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
/** |
||||
* 判断是否是图片背景 |
||||
* |
||||
* @param background 背景 |
||||
* @return 判断是否是图片背景 |
||||
*/ |
||||
public boolean accept(Background background) { |
||||
return background instanceof ExternalImageBackground; |
||||
} |
||||
|
||||
/** |
||||
* 标题 |
||||
* |
||||
* @return 标题 |
||||
*/ |
||||
public String title4PopupWindow() { |
||||
return "外置图片"; |
||||
} |
||||
|
||||
public void reset() { |
||||
this.cachedId = null; |
||||
imageLayoutPane.setSelectedIndex(0); |
||||
previewPane.setImage(null); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,26 @@
|
||||
package com.fr.plugin.external.locale; |
||||
|
||||
import com.fr.intelli.record.Focus; |
||||
import com.fr.intelli.record.Original; |
||||
import com.fr.record.analyzer.EnableMetrics; |
||||
import com.fr.stable.fun.impl.AbstractLocaleFinder; |
||||
|
||||
/** |
||||
* Created by Administrator on 2015/7/13 0013. |
||||
*/ |
||||
@EnableMetrics |
||||
public class LocaleFinder extends AbstractLocaleFinder{ |
||||
|
||||
public static final String PLUGIN_ID = "com.fr.plugin.external"; |
||||
|
||||
/** |
||||
* 国际化文件路径 |
||||
* |
||||
* @return 路径 |
||||
* |
||||
*/ |
||||
@Focus(id = PLUGIN_ID, text = "FR-Plugin_External-Background", source = Original.PLUGIN) |
||||
public String find() { |
||||
return "com/fr/plugin/external/locale/locale"; |
||||
} |
||||
} |
@ -0,0 +1,31 @@
|
||||
package com.fr.plugin.external.web; |
||||
|
||||
import com.fr.data.NetworkHelper; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.plugin.external.ImageManager; |
||||
import com.fr.stable.fun.impl.AbstractRequestInterceptor; |
||||
import com.fr.web.utils.WebUtils; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
public class DeleteImageAction extends AbstractRequestInterceptor { |
||||
|
||||
@Override |
||||
public String getCMD() { |
||||
return "del"; |
||||
} |
||||
|
||||
@Override |
||||
public void actionCMD(HttpServletRequest req, HttpServletResponse res) throws Exception { |
||||
actionCMD(req, res, null); |
||||
} |
||||
|
||||
@Override |
||||
public void actionCMD(HttpServletRequest req, HttpServletResponse res, String sessionID) throws Exception { |
||||
String id = NetworkHelper.getHTTPRequestParameter(req, "imageid"); |
||||
ImageManager.getInstance().removeImage(id); |
||||
WebUtils.printAsJSON(res, JSONObject.create().put("result", "success")); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,45 @@
|
||||
package com.fr.plugin.external.web; |
||||
|
||||
import com.fr.data.NetworkHelper; |
||||
import com.fr.general.IOUtils; |
||||
import com.fr.general.xml.GeneralXMLTools; |
||||
import com.fr.plugin.external.ImageManager; |
||||
import com.fr.stable.fun.impl.AbstractRequestInterceptor; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.awt.*; |
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.OutputStream; |
||||
|
||||
public class DownloadImageAction extends AbstractRequestInterceptor { |
||||
@Override |
||||
public String getCMD() { |
||||
return "download"; |
||||
} |
||||
|
||||
@Override |
||||
public void actionCMD(HttpServletRequest req, HttpServletResponse res) throws Exception { |
||||
actionCMD(req, res, null); |
||||
} |
||||
|
||||
@Override |
||||
public void actionCMD(HttpServletRequest req, HttpServletResponse res, String sessionID) throws Exception { |
||||
String id = NetworkHelper.getHTTPRequestParameter(req, "imageid"); |
||||
Image image = ImageManager.getInstance().findImageById(id); |
||||
|
||||
if (image == null) { |
||||
return; |
||||
} |
||||
String disposition = "attachment; filename=" + id + ".png"; |
||||
res.setContentType("image/png"); |
||||
res.setHeader("extension", "png"); |
||||
res.setHeader("Content-disposition", disposition); |
||||
|
||||
byte[] content = GeneralXMLTools.imageEncode(image); |
||||
OutputStream out = res.getOutputStream(); |
||||
IOUtils.copyBinaryTo(new ByteArrayInputStream(content), out); |
||||
out.close(); |
||||
|
||||
} |
||||
} |
@ -0,0 +1,120 @@
|
||||
package com.fr.plugin.external.web; |
||||
|
||||
import com.fr.base.TemplateUtils; |
||||
import com.fr.json.JSONArray; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.plugin.external.ImageManager; |
||||
import com.fr.stable.StableUtils; |
||||
import com.fr.stable.fun.impl.AbstractRequestInterceptor; |
||||
import com.fr.stable.project.ProjectConstants; |
||||
import com.fr.web.utils.WebUtils; |
||||
import com.fr.workspace.WorkContext; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.BufferedReader; |
||||
import java.io.File; |
||||
import java.io.FileInputStream; |
||||
import java.io.InputStreamReader; |
||||
import java.util.Arrays; |
||||
import java.util.HashMap; |
||||
import java.util.HashSet; |
||||
import java.util.Iterator; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
public class GetAllImageInfoAction extends AbstractRequestInterceptor { |
||||
|
||||
@Override |
||||
public String getCMD() { |
||||
return "allImage"; |
||||
} |
||||
|
||||
@Override |
||||
public void actionCMD(HttpServletRequest req, HttpServletResponse res) throws Exception { |
||||
actionCMD(req, res, null); |
||||
} |
||||
|
||||
@Override |
||||
public void actionCMD(HttpServletRequest req, HttpServletResponse res, String sessionID) throws Exception { |
||||
final String[] ids = ImageManager.getInstance().listAllIds(); |
||||
final Map<String, String> idFile = new HashMap<String, String>(); |
||||
// 寻找图片所在的模板
|
||||
findIdInFile(ids, idFile); |
||||
|
||||
JSONObject tableConfig = JSONObject.create(); |
||||
tableConfig.put("count", ids.length); |
||||
tableConfig.put("code", 0); |
||||
JSONArray tabledata = JSONArray.create(); |
||||
tableConfig.put("data", tabledata); |
||||
String folderPath = StableUtils.pathJoin(WorkContext.getCurrent().getPath(), |
||||
ProjectConstants.ASSETS_NAME, "background"); |
||||
|
||||
for (String id : ids) { |
||||
JSONObject jo = JSONObject.create(); |
||||
jo.put("id", id); |
||||
renderImageURL(id, jo); |
||||
String path = StableUtils.pathJoin(folderPath, id + ".png"); |
||||
File imageFile = new File(path); |
||||
jo.put("size", imageFile.exists() ? imageFile.length() / 1024 : 0); |
||||
jo.put("template", idFile.get(id) == null ? "无" : idFile.get(id)); |
||||
|
||||
tabledata.put(jo); |
||||
} |
||||
WebUtils.printAsJSON(res, tableConfig); |
||||
|
||||
} |
||||
|
||||
private void findIdInFile(String[] ids, final Map<String, String> idFile) throws Exception { |
||||
final Set<String> idSet = new HashSet<String>(Arrays.asList(ids)); |
||||
|
||||
String reportlets = StableUtils.pathJoin(WorkContext.getCurrent().getPath(), ProjectConstants.REPORTLETS_NAME); |
||||
File folder = new File(reportlets); |
||||
iteratorFolder(folder, new FileCallable<File>() { |
||||
|
||||
public void call(File file) throws Exception { |
||||
// 目前只有表单用了外置背景
|
||||
if (file.getName().endsWith(".frm")) { |
||||
//逐行读取, 匹配到就返回.
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file))); |
||||
String temp; |
||||
while ((temp = br.readLine()) != null) { |
||||
Iterator<String> it = idSet.iterator(); |
||||
while (it.hasNext()) { |
||||
String value = it.next(); |
||||
if (temp.indexOf(value) != -1) { |
||||
idFile.put(value, file.getName()); |
||||
it.remove(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
private void renderImageURL(String id, JSONObject jo) throws Exception { |
||||
Map<String, String> para = new HashMap<String, String>(); |
||||
para.put("id", id); |
||||
String imageUrl = TemplateUtils.renderParameter4Tpl("${serverURL}${servletURL}?op=im&cmd=show&imageid=${id}", para); |
||||
jo.put("image", imageUrl); |
||||
} |
||||
|
||||
private static void iteratorFolder(File file, FileCallable callable) throws Exception { |
||||
if (file.isDirectory()) { |
||||
File[] files = file.listFiles(); |
||||
for (File temp : files) { |
||||
iteratorFolder(temp, callable); |
||||
} |
||||
} else { |
||||
callable.call(file); |
||||
} |
||||
} |
||||
|
||||
private interface FileCallable<T> { |
||||
|
||||
void call(T file) throws Exception; |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,69 @@
|
||||
package com.fr.plugin.external.web; |
||||
|
||||
import com.fr.plugin.external.ImageManager; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.fun.RequestInterceptor; |
||||
import com.fr.stable.fun.Service; |
||||
import com.fr.stable.web.ServletContext; |
||||
import com.fr.stable.web.ServletContextAdapter; |
||||
import com.fr.web.core.WebActionsDispatcher; |
||||
import com.fr.web.utils.WebUtils; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.util.HashMap; |
||||
import java.util.concurrent.ExecutorService; |
||||
import java.util.concurrent.Executors; |
||||
|
||||
public class ImageViewService implements Service{ |
||||
|
||||
static { |
||||
ServletContext.addServletContextListener(new ServletContextAdapter() { |
||||
@Override |
||||
public void onServletStop() { |
||||
ImageManager.getInstance().release(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public ImageViewService() { |
||||
ExecutorService executorService = Executors.newSingleThreadExecutor(); |
||||
executorService.execute(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
// 预初始化
|
||||
ImageManager.getInstance(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
private RequestInterceptor[] actions = { |
||||
new ShowImageAction(), |
||||
new GetAllImageInfoAction(), |
||||
new DownloadImageAction(), |
||||
new DeleteImageAction(), |
||||
new UpdateImageAction() |
||||
}; |
||||
|
||||
@Override |
||||
public String actionOP() { |
||||
return "im"; |
||||
} |
||||
|
||||
@Override |
||||
public void process(HttpServletRequest req, HttpServletResponse res, String op, String sessionID) throws Exception { |
||||
// if (isAdmin(req)) {
|
||||
// WebUtils.printAsString(res, "Please log on as an admin, and then try again.");
|
||||
// return;
|
||||
// }
|
||||
|
||||
String cmd = WebUtils.getHTTPRequestParameter(req, "cmd"); |
||||
if (StringUtils.isEmpty(cmd)) { |
||||
String errorTemplate = "/com/fr/plugin/external/web/ui/im/manager.html"; |
||||
WebUtils.writeOutTemplate(errorTemplate, res, new HashMap()); |
||||
} else { |
||||
WebActionsDispatcher.dealForActionCMD(req, res, sessionID, actions); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,41 @@
|
||||
package com.fr.plugin.external.web; |
||||
|
||||
import com.fr.data.NetworkHelper; |
||||
import com.fr.general.IOUtils; |
||||
import com.fr.general.xml.GeneralXMLTools; |
||||
import com.fr.plugin.external.ImageManager; |
||||
import com.fr.stable.fun.impl.AbstractRequestInterceptor; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.awt.*; |
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.OutputStream; |
||||
|
||||
public class ShowImageAction extends AbstractRequestInterceptor { |
||||
@Override |
||||
public String getCMD() { |
||||
return "show"; |
||||
} |
||||
|
||||
@Override |
||||
public void actionCMD(HttpServletRequest req, HttpServletResponse res) throws Exception { |
||||
actionCMD(req, res, null); |
||||
} |
||||
|
||||
@Override |
||||
public void actionCMD(HttpServletRequest req, HttpServletResponse res, String sessionID) throws Exception { |
||||
String id = NetworkHelper.getHTTPRequestParameter(req, "imageid"); |
||||
Image image = ImageManager.getInstance().findImageById(id); |
||||
|
||||
if (image == null) { |
||||
return; |
||||
} |
||||
res.setContentType("image/png"); |
||||
byte[] content = GeneralXMLTools.imageEncode(image); |
||||
OutputStream out = res.getOutputStream(); |
||||
IOUtils.copyBinaryTo(new ByteArrayInputStream(content), out); |
||||
out.close(); |
||||
|
||||
} |
||||
} |
@ -0,0 +1,30 @@
|
||||
package com.fr.plugin.external.web; |
||||
|
||||
import com.fr.plugin.external.ImageManager; |
||||
import com.fr.stable.fun.impl.AbstractRequestInterceptor; |
||||
import com.fr.web.utils.WebUtils; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.util.HashMap; |
||||
|
||||
public class UpdateImageAction extends AbstractRequestInterceptor { |
||||
|
||||
@Override |
||||
public String getCMD() { |
||||
return "update"; |
||||
} |
||||
|
||||
@Override |
||||
public void actionCMD(HttpServletRequest req, HttpServletResponse res) throws Exception { |
||||
actionCMD(req, res, null); |
||||
} |
||||
|
||||
@Override |
||||
public void actionCMD(HttpServletRequest req, HttpServletResponse res, String sessionID) throws Exception { |
||||
ImageManager.getInstance().updateImageFromDisk(); |
||||
String errorTemplate = "/com/fr/plugin/external/web/ui/im/manager.html"; |
||||
WebUtils.writeOutTemplate(errorTemplate, res, new HashMap()); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,2 @@
|
||||
/** layui-v2.2.3 MIT License By http://www.layui.com */ |
||||
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none} |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 701 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 222 KiB |
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> |
||||
<title>图片管理</title> |
||||
<link rel="stylesheet" href="${remoteServletURL}?op=resource&resource=/com/fr/plugin/external/web/ui/css/layui.css" media="all"> |
||||
<style> |
||||
body{margin: 10px;} |
||||
.layui-table-cell{ |
||||
height:40px; |
||||
line-height: 40px; |
||||
} |
||||
</style> |
||||
<script src="${remoteServletURL}?op=resource&resource=/com/fr/plugin/external/web/ui/layui.js"></script> |
||||
<script type="text/javascript" |
||||
src="${remoteServletURL}?op=emb&resource=finereport.js&inter=${__locale__}&__fr_locale__=${__fr_locale__}&__v__=${__v__}&jsVersion=${jsVersion}"></script> |
||||
<script src="${remoteServletURL}?op=resource&resource=/com/fr/plugin/external/web/ui/im/manager.js"></script> |
||||
|
||||
</head> |
||||
<body> |
||||
<div class="layui-container"> |
||||
<fieldset class="layui-elem-field" style="margin-top: 1px;padding: 10px;border-color: #009688"> |
||||
<legend>图片管理</legend> |
||||
<table id="demo" lay-filter="test"></table> |
||||
</fieldset> |
||||
</div> |
||||
</body> |
||||
</html> |
@ -0,0 +1,17 @@
|
||||
layui.use('table', function(){ |
||||
var table = layui.table; |
||||
|
||||
//第一个实例
|
||||
table.render({ |
||||
elem: '#demo', |
||||
url: FR.serverURL + FR.servletURL + '?op=im&cmd=allImage', //数据接口
|
||||
page: false, //开启分页
|
||||
cols: [[ //表头
|
||||
{field: 'image', title: '图片', width:200, fixed: 'left',templet:'<div><img src="{{ d.image}}"></div>'}, |
||||
{field: 'id', title: 'ID', width:400}, |
||||
{field: 'size', title: '大小(KB)', width:200, sort : true}, |
||||
{field: 'template', title: '所在模板', width: 350} |
||||
]] |
||||
}); |
||||
|
||||
}); |
@ -0,0 +1,2 @@
|
||||
/** layui-v2.2.3 MIT License By http://www.layui.com */ |
||||
;layui.define("jquery",function(e){"use strict";var i=layui.$,n=(layui.hint(),layui.device(),{config:{},set:function(e){var n=this;return n.config=i.extend({},n.config,e),n},on:function(e,i){return layui.onevent.call(this,t,e,i)}}),t="carousel",a="layui-this",l=">*[carousel-item]>*",o="layui-carousel-left",r="layui-carousel-right",d="layui-carousel-prev",s="layui-carousel-next",u="layui-carousel-arrow",c="layui-carousel-ind",m=function(e){var t=this;t.config=i.extend({},t.config,n.config,e),t.render()};m.prototype.config={width:"600px",height:"280px",full:!1,arrow:"hover",indicator:"inside",autoplay:!0,interval:3e3,anim:"",trigger:"click",index:0},m.prototype.render=function(){var e=this,n=e.config;n.elem=i(n.elem),n.elem[0]&&(e.elemItem=n.elem.find(l),n.index<0&&(n.index=0),n.index>=e.elemItem.length&&(n.index=e.elemItem.length-1),n.interval<800&&(n.interval=800),n.full?n.elem.css({position:"fixed",width:"100%",height:"100%",zIndex:9999}):n.elem.css({width:n.width,height:n.height}),n.elem.attr("lay-anim",n.anim),e.elemItem.eq(n.index).addClass(a),e.elemItem.length<=1||(e.indicator(),e.arrow(),e.autoplay(),e.events()))},m.prototype.reload=function(e){var n=this;clearInterval(n.timer),n.config=i.extend({},n.config,e),n.render()},m.prototype.prevIndex=function(){var e=this,i=e.config,n=i.index-1;return n<0&&(n=e.elemItem.length-1),n},m.prototype.nextIndex=function(){var e=this,i=e.config,n=i.index+1;return n>=e.elemItem.length&&(n=0),n},m.prototype.addIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index+e,n.index>=i.elemItem.length&&(n.index=0)},m.prototype.subIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index-e,n.index<0&&(n.index=i.elemItem.length-1)},m.prototype.autoplay=function(){var e=this,i=e.config;i.autoplay&&(e.timer=setInterval(function(){e.slide()},i.interval))},m.prototype.arrow=function(){var e=this,n=e.config,t=i(['<button class="layui-icon '+u+'" lay-type="sub">'+("updown"===n.anim?"":"")+"</button>",'<button class="layui-icon '+u+'" lay-type="add">'+("updown"===n.anim?"":"")+"</button>"].join(""));n.elem.attr("lay-arrow",n.arrow),n.elem.find("."+u)[0]&&n.elem.find("."+u).remove(),n.elem.append(t),t.on("click",function(){var n=i(this),t=n.attr("lay-type");e.slide(t)})},m.prototype.indicator=function(){var e=this,n=e.config,t=e.elemInd=i(['<div class="'+c+'"><ul>',function(){var i=[];return layui.each(e.elemItem,function(e){i.push("<li"+(n.index===e?' class="layui-this"':"")+"></li>")}),i.join("")}(),"</ul></div>"].join(""));n.elem.attr("lay-indicator",n.indicator),n.elem.find("."+c)[0]&&n.elem.find("."+c).remove(),n.elem.append(t),"updown"===n.anim&&t.css("margin-top",-(t.height()/2)),t.find("li").on("hover"===n.trigger?"mouseover":n.trigger,function(){var t=i(this),a=t.index();a>n.index?e.slide("add",a-n.index):a<n.index&&e.slide("sub",n.index-a)})},m.prototype.slide=function(e,i){var n=this,l=n.elemItem,u=n.config,c=u.index,m=u.elem.attr("lay-filter");n.haveSlide||("sub"===e?(n.subIndex(i),l.eq(u.index).addClass(d),setTimeout(function(){l.eq(c).addClass(r),l.eq(u.index).addClass(r)},50)):(n.addIndex(i),l.eq(u.index).addClass(s),setTimeout(function(){l.eq(c).addClass(o),l.eq(u.index).addClass(o)},50)),setTimeout(function(){l.removeClass(a+" "+d+" "+s+" "+o+" "+r),l.eq(u.index).addClass(a),n.haveSlide=!1},300),n.elemInd.find("li").eq(u.index).addClass(a).siblings().removeClass(a),n.haveSlide=!0,layui.event.call(this,t,"change("+m+")",{index:u.index,prevIndex:c,item:l.eq(u.index)}))},m.prototype.events=function(){var e=this,i=e.config;i.elem.data("haveEvents")||(i.elem.on("mouseenter",function(){clearInterval(e.timer)}).on("mouseleave",function(){e.autoplay()}),i.elem.data("haveEvents",!0))},n.render=function(e){var i=new m(e);return i},e(t,n)}); |
@ -0,0 +1,2 @@
|
||||
/** layui-v2.2.3 MIT License By http://www.layui.com */ |
||||
;layui.define("jquery",function(e){"use strict";var a=layui.$,l="http://www.layui.com/doc/modules/code.html";e("code",function(e){var t=[];e=e||{},e.elem=a(e.elem||".layui-code"),e.about=!("about"in e)||e.about,e.elem.each(function(){t.push(this)}),layui.each(t.reverse(),function(t,i){var c=a(i),o=c.html();(c.attr("lay-encode")||e.encode)&&(o=o.replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/'/g,"'").replace(/"/g,""")),c.html('<ol class="layui-code-ol"><li>'+o.replace(/[\r\t\n]+/g,"</li><li>")+"</li></ol>"),c.find(">.layui-code-h3")[0]||c.prepend('<h3 class="layui-code-h3">'+(c.attr("lay-title")||e.title||"code")+(e.about?'<a href="'+l+'" target="_blank">layui.code</a>':"")+"</h3>");var d=c.find(">.layui-code-ol");c.addClass("layui-box layui-code-view"),(c.attr("lay-skin")||e.skin)&&c.addClass("layui-code-"+(c.attr("lay-skin")||e.skin)),(d.find("li").length/100|0)>0&&d.css("margin-left",(d.find("li").length/100|0)+"px"),(c.attr("lay-height")||e.height)&&d.css("max-height",c.attr("lay-height")||e.height)})})}).addcss("modules/code.css","skincodecss"); |
@ -0,0 +1,2 @@
|
||||
/** layui-v2.2.3 MIT License By http://www.layui.com */ |
||||
;layui.define("jquery",function(e){"use strict";var l=layui.$,o=function(e){},t='<i class="layui-anim layui-anim-rotate layui-anim-loop layui-icon "></i>';o.prototype.load=function(e){var o,i,n,r,a=this,c=0;e=e||{};var f=l(e.elem);if(f[0]){var m=l(e.scrollElem||document),u=e.mb||50,s=!("isAuto"in e)||e.isAuto,v=e.end||"没有更多了",y=e.scrollElem&&e.scrollElem!==document,d="<cite>加载更多</cite>",h=l('<div class="layui-flow-more"><a href="javascript:;">'+d+"</a></div>");f.find(".layui-flow-more")[0]||f.append(h);var p=function(e,t){e=l(e),h.before(e),t=0==t||null,t?h.html(v):h.find("a").html(d),i=t,o=null,n&&n()},g=function(){o=!0,h.find("a").html(t),"function"==typeof e.done&&e.done(++c,p)};if(g(),h.find("a").on("click",function(){l(this);i||o||g()}),e.isLazyimg)var n=a.lazyimg({elem:e.elem+" img",scrollElem:e.scrollElem});return s?(m.on("scroll",function(){var e=l(this),t=e.scrollTop();r&&clearTimeout(r),i||(r=setTimeout(function(){var i=y?e.height():l(window).height(),n=y?e.prop("scrollHeight"):document.documentElement.scrollHeight;n-t-i<=u&&(o||g())},100))}),a):a}},o.prototype.lazyimg=function(e){var o,t=this,i=0;e=e||{};var n=l(e.scrollElem||document),r=e.elem||"img",a=e.scrollElem&&e.scrollElem!==document,c=function(e,l){var o=n.scrollTop(),r=o+l,c=a?function(){return e.offset().top-n.offset().top+o}():e.offset().top;if(c>=o&&c<=r&&!e.attr("src")){var m=e.attr("lay-src");layui.img(m,function(){var l=t.lazyimg.elem.eq(i);e.attr("src",m).removeAttr("lay-src"),l[0]&&f(l),i++})}},f=function(e,o){var f=a?(o||n).height():l(window).height(),m=n.scrollTop(),u=m+f;if(t.lazyimg.elem=l(r),e)c(e,f);else for(var s=0;s<t.lazyimg.elem.length;s++){var v=t.lazyimg.elem.eq(s),y=a?function(){return v.offset().top-n.offset().top+m}():v.offset().top;if(c(v,f),i=s,y>u)break}};if(f(),!o){var m;n.on("scroll",function(){var e=l(this);m&&clearTimeout(m),m=setTimeout(function(){f(null,e)},50)}),o=!0}return f},e("flow",new o)}); |
@ -0,0 +1,2 @@
|
||||
/** layui-v2.2.3 MIT License By http://www.layui.com */ |
||||
;layui.define(function(e){"use strict";var a=document,t="getElementById",n="getElementsByTagName",i="laypage",r="layui-disabled",u=function(e){var a=this;a.config=e||{},a.config.index=++s.index,a.render(!0)};u.prototype.type=function(){var e=this.config;if("object"==typeof e.elem)return void 0===e.elem.length?2:3},u.prototype.view=function(){var e=this,a=e.config,t=a.groups="groups"in a?0|a.groups:5;a.layout="object"==typeof a.layout?a.layout:["prev","page","next"],a.count=0|a.count,a.curr=0|a.curr||1,a.limits="object"==typeof a.limits?a.limits:[10,20,30,40,50],a.limit=0|a.limit||10,a.pages=Math.ceil(a.count/a.limit)||1,a.curr>a.pages&&(a.curr=a.pages),t<0?t=1:t>a.pages&&(t=a.pages),a.prev="prev"in a?a.prev:"上一页",a.next="next"in a?a.next:"下一页";var n=a.pages>t?Math.ceil((a.curr+(t>1?1:0))/(t>0?t:1)):1,i={prev:function(){return a.prev?'<a href="javascript:;" class="layui-laypage-prev'+(1==a.curr?" "+r:"")+'" data-page="'+(a.curr-1)+'">'+a.prev+"</a>":""}(),page:function(){var e=[];if(a.count<1)return"";n>1&&a.first!==!1&&0!==t&&e.push('<a href="javascript:;" class="layui-laypage-first" data-page="1" title="首页">'+(a.first||1)+"</a>");var i=Math.floor((t-1)/2),r=n>1?a.curr-i:1,u=n>1?function(){var e=a.curr+(t-i-1);return e>a.pages?a.pages:e}():t;for(u-r<t-1&&(r=u-t+1),a.first!==!1&&r>2&&e.push('<span class="layui-laypage-spr">…</span>');r<=u;r++)r===a.curr?e.push('<span class="layui-laypage-curr"><em class="layui-laypage-em" '+(/^#/.test(a.theme)?'style="background-color:'+a.theme+';"':"")+"></em><em>"+r+"</em></span>"):e.push('<a href="javascript:;" data-page="'+r+'">'+r+"</a>");return a.pages>t&&a.pages>u&&a.last!==!1&&(u+1<a.pages&&e.push('<span class="layui-laypage-spr">…</span>'),0!==t&&e.push('<a href="javascript:;" class="layui-laypage-last" title="尾页" data-page="'+a.pages+'">'+(a.last||a.pages)+"</a>")),e.join("")}(),next:function(){return a.next?'<a href="javascript:;" class="layui-laypage-next'+(a.curr==a.pages?" "+r:"")+'" data-page="'+(a.curr+1)+'">'+a.next+"</a>":""}(),count:'<span class="layui-laypage-count">共 '+a.count+" 条</span>",limit:function(){var e=['<span class="layui-laypage-limits"><select lay-ignore>'];return layui.each(a.limits,function(t,n){e.push('<option value="'+n+'"'+(n===a.limit?"selected":"")+">"+n+" 条/页</option>")}),e.join("")+"</select></span>"}(),skip:function(){return['<span class="layui-laypage-skip">到第','<input type="text" min="1" value="'+a.curr+'" class="layui-input">','页<button type="button" class="layui-laypage-btn">确定</button>',"</span>"].join("")}()};return['<div class="layui-box layui-laypage layui-laypage-'+(a.theme?/^#/.test(a.theme)?"molv":a.theme:"default")+'" id="layui-laypage-'+a.index+'">',function(){var e=[];return layui.each(a.layout,function(a,t){i[t]&&e.push(i[t])}),e.join("")}(),"</div>"].join("")},u.prototype.jump=function(e,a){if(e){var t=this,i=t.config,r=e.children,u=e[n]("button")[0],l=e[n]("input")[0],p=e[n]("select")[0],c=function(){var e=0|l.value.replace(/\s|\D/g,"");e&&(i.curr=e,t.render())};if(a)return c();for(var o=0,y=r.length;o<y;o++)"a"===r[o].nodeName.toLowerCase()&&s.on(r[o],"click",function(){var e=0|this.getAttribute("data-page");e<1||e>i.pages||(i.curr=e,t.render())});p&&s.on(p,"change",function(){var e=this.value;i.curr*e>i.count&&(i.curr=Math.ceil(i.count/e)),i.limit=e,t.render()}),u&&s.on(u,"click",function(){c()})}},u.prototype.skip=function(e){if(e){var a=this,t=e[n]("input")[0];t&&s.on(t,"keyup",function(t){var n=this.value,i=t.keyCode;/^(37|38|39|40)$/.test(i)||(/\D/.test(n)&&(this.value=n.replace(/\D/,"")),13===i&&a.jump(e,!0))})}},u.prototype.render=function(e){var n=this,i=n.config,r=n.type(),u=n.view();2===r?i.elem&&(i.elem.innerHTML=u):3===r?i.elem.html(u):a[t](i.elem)&&(a[t](i.elem).innerHTML=u),i.jump&&i.jump(i,e);var s=a[t]("layui-laypage-"+i.index);n.jump(s),i.hash&&!e&&(location.hash="!"+i.hash+"="+i.curr),n.skip(s)};var s={render:function(e){var a=new u(e);return a.index},index:layui.laypage?layui.laypage.index+1e4:0,on:function(e,a,t){return e.attachEvent?e.attachEvent("on"+a,function(a){a.target=a.srcElement,t.call(e,a)}):e.addEventListener(a,t,!1),this}};e(i,s)}); |
@ -0,0 +1,2 @@
|
||||
/** layui-v2.2.3 MIT License By http://www.layui.com */ |
||||
;layui.define(function(e){"use strict";var r={open:"{{",close:"}}"},c={exp:function(e){return new RegExp(e,"g")},query:function(e,c,t){var o=["#([\\s\\S])+?","([^{#}])*?"][e||0];return n((c||"")+r.open+o+r.close+(t||""))},escape:function(e){return String(e||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/'/g,"'").replace(/"/g,""")},error:function(e,r){var c="Laytpl Error:";return"object"==typeof console&&console.error(c+e+"\n"+(r||"")),c+e}},n=c.exp,t=function(e){this.tpl=e};t.pt=t.prototype,window.errors=0,t.pt.parse=function(e,t){var o=this,p=e,a=n("^"+r.open+"#",""),l=n(r.close+"$","");e=e.replace(/\s+|\r|\t|\n/g," ").replace(n(r.open+"#"),r.open+"# ").replace(n(r.close+"}"),"} "+r.close).replace(/\\/g,"\\\\").replace(n(r.open+"!(.+?)!"+r.close),function(e){return e=e.replace(n("^"+r.open+"!"),"").replace(n("!"+r.close),"").replace(n(r.open+"|"+r.close),function(e){return e.replace(/(.)/g,"\\$1")})}).replace(/(?="|')/g,"\\").replace(c.query(),function(e){return e=e.replace(a,"").replace(l,""),'";'+e.replace(/\\/g,"")+';view+="'}).replace(c.query(1),function(e){var c='"+(';return e.replace(/\s/g,"")===r.open+r.close?"":(e=e.replace(n(r.open+"|"+r.close),""),/^=/.test(e)&&(e=e.replace(/^=/,""),c='"+_escape_('),c+e.replace(/\\/g,"")+')+"')}),e='"use strict";var view = "'+e+'";return view;';try{return o.cache=e=new Function("d, _escape_",e),e(t,c.escape)}catch(u){return delete o.cache,c.error(u,p)}},t.pt.render=function(e,r){var n,t=this;return e?(n=t.cache?t.cache(e,c.escape):t.parse(t.tpl,e),r?void r(n):n):c.error("no data")};var o=function(e){return"string"!=typeof e?c.error("Template not found"):new t(e)};o.config=function(e){e=e||{};for(var c in e)r[c]=e[c]},o.v="1.2.0",e("laytpl",o)}); |
@ -0,0 +1,2 @@
|
||||
/** layui-v2.2.3 MIT License By http://www.layui.com */ |
||||
;layui.define("jquery",function(e){"use strict";var o=layui.$,a=layui.hint(),i="layui-tree-enter",r=function(e){this.options=e},t={arrow:["",""],checkbox:["",""],radio:["",""],branch:["",""],leaf:""};r.prototype.init=function(e){var o=this;e.addClass("layui-box layui-tree"),o.options.skin&&e.addClass("layui-tree-skin-"+o.options.skin),o.tree(e),o.on(e)},r.prototype.tree=function(e,a){var i=this,r=i.options,n=a||r.nodes;layui.each(n,function(a,n){var l=n.children&&n.children.length>0,c=o('<ul class="'+(n.spread?"layui-show":"")+'"></ul>'),s=o(["<li "+(n.spread?'data-spread="'+n.spread+'"':"")+">",function(){return l?'<i class="layui-icon layui-tree-spread">'+(n.spread?t.arrow[1]:t.arrow[0])+"</i>":""}(),function(){return r.check?'<i class="layui-icon layui-tree-check">'+("checkbox"===r.check?t.checkbox[0]:"radio"===r.check?t.radio[0]:"")+"</i>":""}(),function(){return'<a href="'+(n.href||"javascript:;")+'" '+(r.target&&n.href?'target="'+r.target+'"':"")+">"+('<i class="layui-icon layui-tree-'+(l?"branch":"leaf")+'">'+(l?n.spread?t.branch[1]:t.branch[0]:t.leaf)+"</i>")+("<cite>"+(n.name||"未命名")+"</cite></a>")}(),"</li>"].join(""));l&&(s.append(c),i.tree(c,n.children)),e.append(s),"function"==typeof r.click&&i.click(s,n),i.spread(s,n),r.drag&&i.drag(s,n)})},r.prototype.click=function(e,o){var a=this,i=a.options;e.children("a").on("click",function(e){layui.stope(e),i.click(o)})},r.prototype.spread=function(e,o){var a=this,i=(a.options,e.children(".layui-tree-spread")),r=e.children("ul"),n=e.children("a"),l=function(){e.data("spread")?(e.data("spread",null),r.removeClass("layui-show"),i.html(t.arrow[0]),n.find(".layui-icon").html(t.branch[0])):(e.data("spread",!0),r.addClass("layui-show"),i.html(t.arrow[1]),n.find(".layui-icon").html(t.branch[1]))};r[0]&&(i.on("click",l),n.on("dblclick",l))},r.prototype.on=function(e){var a=this,r=a.options,t="layui-tree-drag";e.find("i").on("selectstart",function(e){return!1}),r.drag&&o(document).on("mousemove",function(e){var i=a.move;if(i.from){var r=(i.to,o('<div class="layui-box '+t+'"></div>'));e.preventDefault(),o("."+t)[0]||o("body").append(r);var n=o("."+t)[0]?o("."+t):r;n.addClass("layui-show").html(i.from.elem.children("a").html()),n.css({left:e.pageX+10,top:e.pageY+10})}}).on("mouseup",function(){var e=a.move;e.from&&(e.from.elem.children("a").removeClass(i),e.to&&e.to.elem.children("a").removeClass(i),a.move={},o("."+t).remove())})},r.prototype.move={},r.prototype.drag=function(e,a){var r=this,t=(r.options,e.children("a")),n=function(){var t=o(this),n=r.move;n.from&&(n.to={item:a,elem:e},t.addClass(i))};t.on("mousedown",function(){var o=r.move;o.from={item:a,elem:e}}),t.on("mouseenter",n).on("mousemove",n).on("mouseleave",function(){var e=o(this),a=r.move;a.from&&(delete a.to,e.removeClass(i))})},e("tree",function(e){var i=new r(e=e||{}),t=o(e.elem);return t[0]?void i.init(t):a.error("layui.tree 没有找到"+e.elem+"元素")})}); |
@ -0,0 +1,2 @@
|
||||
/** layui-v2.2.3 MIT License By http://www.layui.com */ |
||||
;layui.define("jquery",function(e){"use strict";var t=layui.$,i={fixbar:function(e){var i,o,a="layui-fixbar",r="layui-fixbar-top",n=t(document),l=t("body");e=t.extend({showHeight:200},e),e.bar1=e.bar1===!0?"":e.bar1,e.bar2=e.bar2===!0?"":e.bar2,e.bgcolor=e.bgcolor?"background-color:"+e.bgcolor:"";var c=[e.bar1,e.bar2,""],g=t(['<ul class="'+a+'">',e.bar1?'<li class="layui-icon" lay-type="bar1" style="'+e.bgcolor+'">'+c[0]+"</li>":"",e.bar2?'<li class="layui-icon" lay-type="bar2" style="'+e.bgcolor+'">'+c[1]+"</li>":"",'<li class="layui-icon '+r+'" lay-type="top" style="'+e.bgcolor+'">'+c[2]+"</li>","</ul>"].join("")),s=g.find("."+r),u=function(){var t=n.scrollTop();t>=e.showHeight?i||(s.show(),i=1):i&&(s.hide(),i=0)};t("."+a)[0]||("object"==typeof e.css&&g.css(e.css),l.append(g),u(),g.find("li").on("click",function(){var i=t(this),o=i.attr("lay-type");"top"===o&&t("html,body").animate({scrollTop:0},200),e.click&&e.click.call(this,o)}),n.on("scroll",function(){clearTimeout(o),o=setTimeout(function(){u()},100)}))},countdown:function(e,t,i){var o=this,a="function"==typeof t,r=new Date(e).getTime(),n=new Date(!t||a?(new Date).getTime():t).getTime(),l=r-n,c=[Math.floor(l/864e5),Math.floor(l/36e5)%24,Math.floor(l/6e4)%60,Math.floor(l/1e3)%60];a&&(i=t);var g=setTimeout(function(){o.countdown(e,n+1e3,i)},1e3);return i&&i(l>0?c:[0,0,0,0],t,g),l<=0&&clearTimeout(g),g},timeAgo:function(e,t){var i=this,o=[[],[]],a=(new Date).getTime()-new Date(e).getTime();return a>6912e5?(a=new Date(e),o[0][0]=i.digit(a.getFullYear(),4),o[0][1]=i.digit(a.getMonth()+1),o[0][2]=i.digit(a.getDate()),t||(o[1][0]=i.digit(a.getHours()),o[1][1]=i.digit(a.getMinutes()),o[1][2]=i.digit(a.getSeconds())),o[0].join("-")+" "+o[1].join(":")):a>=864e5?(a/1e3/60/60/24|0)+"天前":a>=36e5?(a/1e3/60/60|0)+"小时前":a>=12e4?(a/1e3/60|0)+"分钟前":a<0?"未来":"刚刚"},digit:function(e,t){var i="";e=String(e),t=t||2;for(var o=e.length;o<t;o++)i+="0";return e<Math.pow(10,t)?i+(0|e):e},toDateString:function(e,t){var i=this,o=new Date(e||new Date),a=[i.digit(o.getFullYear(),4),i.digit(o.getMonth()+1),i.digit(o.getDate())],r=[i.digit(o.getHours()),i.digit(o.getMinutes()),i.digit(o.getSeconds())];return t=t||"yyyy-MM-dd HH:mm:ss",t.replace(/yyyy/g,a[0]).replace(/MM/g,a[1]).replace(/dd/g,a[2]).replace(/HH/g,r[0]).replace(/mm/g,r[1]).replace(/ss/g,r[2])}};e("util",i)}); |