Browse Source

提交代码

master
neil 4 years ago
parent
commit
79d4eb7426
  1. 5
      build.bat
  2. 117
      build.xml
  3. BIN
      icon.jpg
  4. 13
      plugin-external.iml
  5. 201
      plugin-externalImage.iml
  6. 26
      plugin.xml
  7. 39
      src/main/java/com/fr/plugin/external/DebugComponent.java
  8. 17
      src/main/java/com/fr/plugin/external/EngineDebugResourceProvider.java
  9. 31
      src/main/java/com/fr/plugin/external/EngineTestComponent.java
  10. 194
      src/main/java/com/fr/plugin/external/ExpandFileChooser.java
  11. 525
      src/main/java/com/fr/plugin/external/ExternalImageBackground.java
  12. 49
      src/main/java/com/fr/plugin/external/ImageBean.java
  13. 256
      src/main/java/com/fr/plugin/external/ImageFileChooser.java
  14. 211
      src/main/java/com/fr/plugin/external/ImageManager.java
  15. 181
      src/main/java/com/fr/plugin/external/ImageUtils.java
  16. 14
      src/main/java/com/fr/plugin/external/design/ExternalBackgroundUI.java
  17. 238
      src/main/java/com/fr/plugin/external/design/ExternalImageBackgroundQuickPane.java
  18. 26
      src/main/java/com/fr/plugin/external/locale/LocaleFinder.java
  19. 3763
      src/main/java/com/fr/plugin/external/locale/locale.properties
  20. 3763
      src/main/java/com/fr/plugin/external/locale/locale_en_US.properties
  21. 3716
      src/main/java/com/fr/plugin/external/locale/locale_ja_JP.properties
  22. 3715
      src/main/java/com/fr/plugin/external/locale/locale_ko_KR.properties
  23. 3765
      src/main/java/com/fr/plugin/external/locale/locale_zh_CN.properties
  24. 3737
      src/main/java/com/fr/plugin/external/locale/locale_zh_TW.properties
  25. 31
      src/main/java/com/fr/plugin/external/web/DeleteImageAction.java
  26. 45
      src/main/java/com/fr/plugin/external/web/DownloadImageAction.java
  27. 120
      src/main/java/com/fr/plugin/external/web/GetAllImageInfoAction.java
  28. 69
      src/main/java/com/fr/plugin/external/web/ImageViewService.java
  29. 41
      src/main/java/com/fr/plugin/external/web/ShowImageAction.java
  30. 30
      src/main/java/com/fr/plugin/external/web/UpdateImageAction.java
  31. 2
      src/main/java/com/fr/plugin/external/web/ui/css/layui.css
  32. 2
      src/main/java/com/fr/plugin/external/web/ui/css/layui.mobile.css
  33. 2
      src/main/java/com/fr/plugin/external/web/ui/css/modules/code.css
  34. 2
      src/main/java/com/fr/plugin/external/web/ui/css/modules/laydate/default/laydate.css
  35. BIN
      src/main/java/com/fr/plugin/external/web/ui/css/modules/layer/default/icon-ext.png
  36. BIN
      src/main/java/com/fr/plugin/external/web/ui/css/modules/layer/default/icon.png
  37. 2
      src/main/java/com/fr/plugin/external/web/ui/css/modules/layer/default/layer.css
  38. BIN
      src/main/java/com/fr/plugin/external/web/ui/css/modules/layer/default/loading-0.gif
  39. BIN
      src/main/java/com/fr/plugin/external/web/ui/css/modules/layer/default/loading-1.gif
  40. BIN
      src/main/java/com/fr/plugin/external/web/ui/css/modules/layer/default/loading-2.gif
  41. BIN
      src/main/java/com/fr/plugin/external/web/ui/font/iconfont.eot
  42. 447
      src/main/java/com/fr/plugin/external/web/ui/font/iconfont.svg
  43. BIN
      src/main/java/com/fr/plugin/external/web/ui/font/iconfont.ttf
  44. BIN
      src/main/java/com/fr/plugin/external/web/ui/font/iconfont.woff
  45. 29
      src/main/java/com/fr/plugin/external/web/ui/im/manager.html
  46. 17
      src/main/java/com/fr/plugin/external/web/ui/im/manager.js
  47. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/carousel.js
  48. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/code.js
  49. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/element.js
  50. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/flow.js
  51. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/form.js
  52. 5
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/jquery.js
  53. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/laydate.js
  54. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/layedit.js
  55. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/layer.js
  56. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/laypage.js
  57. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/laytpl.js
  58. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/mobile.js
  59. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/table.js
  60. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/tree.js
  61. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/upload.js
  62. 2
      src/main/java/com/fr/plugin/external/web/ui/lay/modules/util.js
  63. 5
      src/main/java/com/fr/plugin/external/web/ui/layui.all.js
  64. 2
      src/main/java/com/fr/plugin/external/web/ui/layui.js

5
build.bat

@ -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

117
build.xml

@ -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>

BIN
icon.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

13
plugin-external.iml

@ -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>

201
plugin-externalImage.iml

@ -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>

26
plugin.xml

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin>
<id>com.fr.plugin.external.v10</id>
<name><![CDATA[外置图片背景]]></name>
<active>yes</active>
<version>1.4.8</version>
<env-version>10.0</env-version>
<jartime>2019-8-1</jartime>
<vendor>(;´༎Д༎`)</vendor>
<description><![CDATA[本插件可以将决策报表背景图片外置, 并且可以通过op=im对图片进行管理.]]></description>
<change-notes><![CDATA[
2020-07-13 修复 op = im 问题<br>
2019-11-11 修复代码逻辑问题 <br>
2019-01-03 图片延迟加载<br>
2018-08-27 适配10.0 修改图片以及uuid生成规则<br>
]]></change-notes>
<function-recorder class="com.fr.plugin.external.locale.LocaleFinder"/>
<extra-core>
<LocaleFinder class="com.fr.plugin.external.locale.LocaleFinder"/>
<WebService class="com.fr.plugin.external.web.ImageViewService"/>
</extra-core>
<extra-platform>
</extra-platform>
<extra-designer>
<BackgroundQuickUIProvider class="com.fr.plugin.external.design.ExternalBackgroundUI"/>
</extra-designer>
</plugin>

39
src/main/java/com/fr/plugin/external/DebugComponent.java vendored

@ -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;
}
}

17
src/main/java/com/fr/plugin/external/EngineDebugResourceProvider.java vendored

@ -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;
}
}

31
src/main/java/com/fr/plugin/external/EngineTestComponent.java vendored

@ -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);
}
}

194
src/main/java/com/fr/plugin/external/ExpandFileChooser.java vendored

@ -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) {
}
}
}

525
src/main/java/com/fr/plugin/external/ExternalImageBackground.java vendored

@ -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_DEFAULTConstants.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;
}
}
}

49
src/main/java/com/fr/plugin/external/ImageBean.java vendored

@ -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;
}
}

256
src/main/java/com/fr/plugin/external/ImageFileChooser.java vendored

@ -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;
}
}
}

211
src/main/java/com/fr/plugin/external/ImageManager.java vendored

@ -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());
}
}
});
}
}

181
src/main/java/com/fr/plugin/external/ImageUtils.java vendored

@ -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;
}
}

14
src/main/java/com/fr/plugin/external/design/ExternalBackgroundUI.java vendored

@ -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();
}
}

238
src/main/java/com/fr/plugin/external/design/ExternalImageBackgroundQuickPane.java vendored

@ -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);
}
}

26
src/main/java/com/fr/plugin/external/locale/LocaleFinder.java vendored

@ -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";
}
}

3763
src/main/java/com/fr/plugin/external/locale/locale.properties vendored

File diff suppressed because it is too large Load Diff

3763
src/main/java/com/fr/plugin/external/locale/locale_en_US.properties vendored

File diff suppressed because it is too large Load Diff

3716
src/main/java/com/fr/plugin/external/locale/locale_ja_JP.properties vendored

File diff suppressed because it is too large Load Diff

3715
src/main/java/com/fr/plugin/external/locale/locale_ko_KR.properties vendored

File diff suppressed because it is too large Load Diff

3765
src/main/java/com/fr/plugin/external/locale/locale_zh_CN.properties vendored

File diff suppressed because it is too large Load Diff

3737
src/main/java/com/fr/plugin/external/locale/locale_zh_TW.properties vendored

File diff suppressed because it is too large Load Diff

31
src/main/java/com/fr/plugin/external/web/DeleteImageAction.java vendored

@ -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"));
}
}

45
src/main/java/com/fr/plugin/external/web/DownloadImageAction.java vendored

@ -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();
}
}

120
src/main/java/com/fr/plugin/external/web/GetAllImageInfoAction.java vendored

@ -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;
}
}

69
src/main/java/com/fr/plugin/external/web/ImageViewService.java vendored

@ -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);
}
}
}

41
src/main/java/com/fr/plugin/external/web/ShowImageAction.java vendored

@ -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();
}
}

30
src/main/java/com/fr/plugin/external/web/UpdateImageAction.java vendored

@ -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());
}
}

2
src/main/java/com/fr/plugin/external/web/ui/css/layui.css vendored

File diff suppressed because one or more lines are too long

2
src/main/java/com/fr/plugin/external/web/ui/css/layui.mobile.css vendored

File diff suppressed because one or more lines are too long

2
src/main/java/com/fr/plugin/external/web/ui/css/modules/code.css vendored

@ -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}

2
src/main/java/com/fr/plugin/external/web/ui/css/modules/laydate/default/laydate.css vendored

File diff suppressed because one or more lines are too long

BIN
src/main/java/com/fr/plugin/external/web/ui/css/modules/layer/default/icon-ext.png vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
src/main/java/com/fr/plugin/external/web/ui/css/modules/layer/default/icon.png vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

2
src/main/java/com/fr/plugin/external/web/ui/css/modules/layer/default/layer.css vendored

File diff suppressed because one or more lines are too long

BIN
src/main/java/com/fr/plugin/external/web/ui/css/modules/layer/default/loading-0.gif vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
src/main/java/com/fr/plugin/external/web/ui/css/modules/layer/default/loading-1.gif vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 B

BIN
src/main/java/com/fr/plugin/external/web/ui/css/modules/layer/default/loading-2.gif vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/main/java/com/fr/plugin/external/web/ui/font/iconfont.eot vendored

Binary file not shown.

447
src/main/java/com/fr/plugin/external/web/ui/font/iconfont.svg vendored

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 222 KiB

BIN
src/main/java/com/fr/plugin/external/web/ui/font/iconfont.ttf vendored

Binary file not shown.

BIN
src/main/java/com/fr/plugin/external/web/ui/font/iconfont.woff vendored

Binary file not shown.

29
src/main/java/com/fr/plugin/external/web/ui/im/manager.html vendored

@ -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>

17
src/main/java/com/fr/plugin/external/web/ui/im/manager.js vendored

@ -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}
]]
});
});

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/carousel.js vendored

@ -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?"&#xe619;":"&#xe603;")+"</button>",'<button class="layui-icon '+u+'" lay-type="add">'+("updown"===n.anim?"&#xe61a;":"&#xe602;")+"</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)});

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/code.js vendored

@ -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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#39;").replace(/"/g,"&quot;")),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");

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/element.js vendored

File diff suppressed because one or more lines are too long

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/flow.js vendored

@ -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 ">&#xe63e;</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)});

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/form.js vendored

File diff suppressed because one or more lines are too long

5
src/main/java/com/fr/plugin/external/web/ui/lay/modules/jquery.js vendored

File diff suppressed because one or more lines are too long

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/laydate.js vendored

File diff suppressed because one or more lines are too long

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/layedit.js vendored

File diff suppressed because one or more lines are too long

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/layer.js vendored

File diff suppressed because one or more lines are too long

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/laypage.js vendored

@ -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:"&#x4E0A;&#x4E00;&#x9875;",a.next="next"in a?a.next:"&#x4E0B;&#x4E00;&#x9875;";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="&#x9996;&#x9875;">'+(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">&#x2026;</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">&#x2026;</span>'),0!==t&&e.push('<a href="javascript:;" class="layui-laypage-last" title="&#x5C3E;&#x9875;" 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">&#x5230;&#x7B2C;','<input type="text" min="1" value="'+a.curr+'" class="layui-input">','&#x9875;<button type="button" class="layui-laypage-btn">&#x786e;&#x5b9a;</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)});

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/laytpl.js vendored

@ -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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#39;").replace(/"/g,"&quot;")},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)});

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/mobile.js vendored

File diff suppressed because one or more lines are too long

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/table.js vendored

File diff suppressed because one or more lines are too long

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/tree.js vendored

@ -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:["&#xe623;","&#xe625;"],checkbox:["&#xe626;","&#xe627;"],radio:["&#xe62b;","&#xe62a;"],branch:["&#xe622;","&#xe624;"],leaf:"&#xe621;"};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+"元素")})});

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/upload.js vendored

File diff suppressed because one or more lines are too long

2
src/main/java/com/fr/plugin/external/web/ui/lay/modules/util.js vendored

@ -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?"&#xe606;":e.bar1,e.bar2=e.bar2===!0?"&#xe607;":e.bar2,e.bgcolor=e.bgcolor?"background-color:"+e.bgcolor:"";var c=[e.bar1,e.bar2,"&#xe604;"],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)});

5
src/main/java/com/fr/plugin/external/web/ui/layui.all.js vendored

File diff suppressed because one or more lines are too long

2
src/main/java/com/fr/plugin/external/web/ui/layui.js vendored

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save