Browse Source

Default Changelist

echo587 2 years ago
commit
f4bcb61d88
100 changed files with 8632 additions and 0 deletions
  1. 53 0
      .project
  2. 1 0
      mybatis-generator.bat
  3. 378 0
      pom.xml
  4. 234 0
      sookaCms.iml
  5. 3 0
      src/main/java/META-INF/MANIFEST.MF
  6. 3 0
      src/main/java/META-INF/spring-devtools.properties
  7. 38 0
      src/main/java/com/sooka/CmsApplication.java
  8. 12 0
      src/main/java/com/sooka/ServletInitializer.java
  9. 161 0
      src/main/java/com/sooka/Test.java
  10. 104 0
      src/main/java/com/sooka/common/MyApplicationRunner.java
  11. 15 0
      src/main/java/com/sooka/common/annotation/ApiValidate.java
  12. 20 0
      src/main/java/com/sooka/common/annotation/ExcelField.java
  13. 15 0
      src/main/java/com/sooka/common/annotation/FormToken.java
  14. 19 0
      src/main/java/com/sooka/common/annotation/ParamNotNull.java
  15. 15 0
      src/main/java/com/sooka/common/annotation/SysLog.java
  16. 89 0
      src/main/java/com/sooka/common/aop/ApiValidateAspect.java
  17. 69 0
      src/main/java/com/sooka/common/aop/FormTokenAspect.java
  18. 103 0
      src/main/java/com/sooka/common/aop/LogAspect.java
  19. 35 0
      src/main/java/com/sooka/common/aop/ParamNotNullAspect.java
  20. 23 0
      src/main/java/com/sooka/common/base/BaseController.java
  21. 22 0
      src/main/java/com/sooka/common/base/BaseService.java
  22. 44 0
      src/main/java/com/sooka/common/captcha/CaptchaConfiguration.java
  23. 72 0
      src/main/java/com/sooka/common/captcha/CaptchaController.java
  24. 27 0
      src/main/java/com/sooka/common/captcha/ChineseTextProducer.java
  25. 40 0
      src/main/java/com/sooka/common/constant/CmsConst.java
  26. 14 0
      src/main/java/com/sooka/common/constant/Const.java
  27. 37 0
      src/main/java/com/sooka/common/db/DbTableAssistant.java
  28. 95 0
      src/main/java/com/sooka/common/db/DbTableAssistantService.java
  29. 48 0
      src/main/java/com/sooka/common/db/impl/M.java
  30. 215 0
      src/main/java/com/sooka/common/db/impl/MysqlDbTableAssistant.java
  31. 132 0
      src/main/java/com/sooka/common/db/kit/DbTableKit.java
  32. 71 0
      src/main/java/com/sooka/common/db/kit/MysqlFiledUtil.java
  33. 42 0
      src/main/java/com/sooka/common/db/vo/FiledTypeVo.java
  34. 15 0
      src/main/java/com/sooka/common/exception/ApiException.java
  35. 13 0
      src/main/java/com/sooka/common/exception/CmsException.java
  36. 128 0
      src/main/java/com/sooka/common/exception/DefaultExceptionHandler.java
  37. 14 0
      src/main/java/com/sooka/common/exception/SystemException.java
  38. 120 0
      src/main/java/com/sooka/common/jwt/Jwt.java
  39. 58 0
      src/main/java/com/sooka/common/jwt/TokenState.java
  40. 49 0
      src/main/java/com/sooka/common/jwt/vo/PayloadVo.java
  41. 28 0
      src/main/java/com/sooka/common/jwt/vo/ResultVo.java
  42. 127 0
      src/main/java/com/sooka/common/keyword/SensitiveWordInit.java
  43. 146 0
      src/main/java/com/sooka/common/keyword/SensitivewordFilter.java
  44. 62 0
      src/main/java/com/sooka/common/template/TemplateFile.java
  45. 25 0
      src/main/java/com/sooka/common/template/TemplateFileService.java
  46. 133 0
      src/main/java/com/sooka/common/template/TemplateFileServiceImpl.java
  47. 257 0
      src/main/java/com/sooka/common/upload/UploadComponent.java
  48. 91 0
      src/main/java/com/sooka/common/upload/UploadController.java
  49. 19 0
      src/main/java/com/sooka/common/upload/bean/UploadBean.java
  50. 66 0
      src/main/java/com/sooka/common/utils/CheckSumUtil.java
  51. 50 0
      src/main/java/com/sooka/common/utils/CmsUtil.java
  52. 432 0
      src/main/java/com/sooka/common/utils/ControllerUtil.java
  53. 287 0
      src/main/java/com/sooka/common/utils/DateUtil.java
  54. 137 0
      src/main/java/com/sooka/common/utils/EncryptUtil.java
  55. 304 0
      src/main/java/com/sooka/common/utils/ExcelUtil.java
  56. 139 0
      src/main/java/com/sooka/common/utils/HtmlKit.java
  57. 106 0
      src/main/java/com/sooka/common/utils/Http.java
  58. 157 0
      src/main/java/com/sooka/common/utils/HttpRequest.java
  59. 175 0
      src/main/java/com/sooka/common/utils/JsonUtil.java
  60. 35 0
      src/main/java/com/sooka/common/utils/MD5.java
  61. 36 0
      src/main/java/com/sooka/common/utils/MMain.java
  62. 72 0
      src/main/java/com/sooka/common/utils/ObjectExcelView.java
  63. 122 0
      src/main/java/com/sooka/common/utils/PageData.java
  64. 99 0
      src/main/java/com/sooka/common/utils/PathUtil.java
  65. 118 0
      src/main/java/com/sooka/common/utils/PinyinUtil.java
  66. 78 0
      src/main/java/com/sooka/common/utils/Pojo2MapUtil.java
  67. 38 0
      src/main/java/com/sooka/common/utils/QiniuUtil.java
  68. 50 0
      src/main/java/com/sooka/common/utils/SmsUtil.java
  69. 125 0
      src/main/java/com/sooka/common/utils/StrUtil.java
  70. 258 0
      src/main/java/com/sooka/common/utils/Tools.java
  71. 22 0
      src/main/java/com/sooka/common/utils/UserUtil.java
  72. 151 0
      src/main/java/com/sooka/component/beetl/BeetlConfiguration.java
  73. 37 0
      src/main/java/com/sooka/component/beetl/BeetlWebErrorHandler.java
  74. 68 0
      src/main/java/com/sooka/component/beetl/format/DateFormat.java
  75. 45 0
      src/main/java/com/sooka/component/beetl/format/XSSDefenseFormat.java
  76. 65 0
      src/main/java/com/sooka/component/beetl/fun/ContentSelectCategoryFunction.java
  77. 64 0
      src/main/java/com/sooka/component/beetl/fun/ContentTreeCategoryFunction.java
  78. 74 0
      src/main/java/com/sooka/component/beetl/fun/OrganizationFunction.java
  79. 79 0
      src/main/java/com/sooka/component/beetl/fun/PermissionFunction.java
  80. 35 0
      src/main/java/com/sooka/component/beetl/fun/PrintModelFiledClassFunction.java
  81. 46 0
      src/main/java/com/sooka/component/beetl/fun/PrintTimeFunction.java
  82. 68 0
      src/main/java/com/sooka/component/beetl/fun/SelectCategoryFunction.java
  83. 72 0
      src/main/java/com/sooka/component/beetl/fun/SelectOrganizationFunction.java
  84. 72 0
      src/main/java/com/sooka/component/beetl/fun/SelectPermissionFunction.java
  85. 50 0
      src/main/java/com/sooka/component/beetl/fun/TreeCategoryFunction.java
  86. 49 0
      src/main/java/com/sooka/component/beetl/fun/TreeContentCategoryFunction.java
  87. 51 0
      src/main/java/com/sooka/component/beetl/fun/TreeOrganizationFunction.java
  88. 49 0
      src/main/java/com/sooka/component/beetl/fun/TreePermissionFunction.java
  89. 65 0
      src/main/java/com/sooka/component/beetl/fun/TreeTopicCatagoryFunction.java
  90. 63 0
      src/main/java/com/sooka/component/beetl/html/BeetlHtmlUtil.java
  91. 24 0
      src/main/java/com/sooka/component/beetl/html/HtmlObject.java
  92. 210 0
      src/main/java/com/sooka/component/beetl/tag/ShiroTag.java
  93. 223 0
      src/main/java/com/sooka/component/beetl/tag/TagRegisterFactory.java
  94. 88 0
      src/main/java/com/sooka/component/beetl/tag/cms/CategoryListTag.java
  95. 78 0
      src/main/java/com/sooka/component/beetl/tag/cms/CategoryTag.java
  96. 119 0
      src/main/java/com/sooka/component/beetl/tag/cms/ContentListTag.java
  97. 93 0
      src/main/java/com/sooka/component/beetl/tag/cms/ContentPageTag.java
  98. 87 0
      src/main/java/com/sooka/component/beetl/tag/cms/ContentTag.java
  99. 67 0
      src/main/java/com/sooka/component/beetl/tag/cms/DbtListTag.java
  100. 0 0
      src/main/java/com/sooka/component/beetl/tag/cms/DbtUserListPageTag.java

+ 53 - 0
.project

@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>sookaCms</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.validation.validationbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.springframework.ide.eclipse.core.springbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.springframework.ide.eclipse.core.springnature</nature>
+		<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
+		<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
+	</natures>
+</projectDescription>

+ 1 - 0
mybatis-generator.bat

@@ -0,0 +1 @@
+mvn mybatis-generator:generate

+ 378 - 0
pom.xml

@@ -0,0 +1,378 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.sooka</groupId>
+    <artifactId>sookaCms</artifactId>
+    <version>0.1</version>
+    <packaging>war</packaging>
+
+    <name>sookaCms</name>
+    <description>This an content manage system</description>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>1.5.11.RELEASE</version>
+        <relativePath/>
+    </parent>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>1.8</java.version>
+        <shiro.version>1.8.0</shiro.version>
+        <pac4j.version>2.0.0</pac4j.version>
+        <!-- MyBatis Generator master Java接口和实体类 -->
+        <masterTargetJavaProject>${basedir}/src/main/java</masterTargetJavaProject>
+        <masterTargetMapperPackage>com.sooka.mybatis.mapper</masterTargetMapperPackage>
+        <masterTargetModelPackage>com.sooka.mybatis.model</masterTargetModelPackage>
+        <masterTargetResourcesProject>${basedir}/src/main/resources</masterTargetResourcesProject>
+        <masterTargetXMLPackage>com.sooka.mybatis.mapper</masterTargetXMLPackage>
+
+        <!-- MyBatis Generator slave Java接口和实体类 -->
+        <slaveTargetJavaProject>${basedir}/src/main/java</slaveTargetJavaProject>
+        <slaveTargetMapperPackage>com.sooka.mybatis.mapper.slave</slaveTargetMapperPackage>
+        <slaveTargetModelPackage>com.sooka.mybatis.model.slave</slaveTargetModelPackage>
+        <slaveTargetResourcesProject>${basedir}/src/main/resources</slaveTargetResourcesProject>
+        <slaveTargetXMLPackage>com.sooka.mybatis.mapper.slave</slaveTargetXMLPackage>
+    </properties>
+
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-cache</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-jdbc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.session</groupId>
+            <artifactId>spring-session</artifactId>
+            <version>1.3.2.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-tomcat</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mybatis</groupId>
+            <artifactId>mybatis-spring</artifactId>
+            <version>1.3.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mybatis</groupId>
+            <artifactId>mybatis</artifactId>
+            <version>3.4.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>1.1.6</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid</artifactId>
+            <version>1.1.6</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper</artifactId>
+            <version>5.1.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.5</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jsoup</groupId>
+            <artifactId>jsoup</artifactId>
+            <version>1.9.2</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.penggle</groupId>
+            <artifactId>kaptcha</artifactId>
+            <version>2.3.2</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.44</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.quartz-scheduler</groupId>
+            <artifactId>quartz</artifactId>
+            <version>2.2.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.quartz-scheduler</groupId>
+            <artifactId>quartz-jobs</artifactId>
+            <version>2.2.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context-support</artifactId>
+        </dependency>
+        <!-- Shiro -->
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-core</artifactId>
+            <version>${shiro.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-spring</artifactId>
+            <version>${shiro.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-web</artifactId>
+            <version>${shiro.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-ehcache</artifactId>
+            <version>${shiro.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+            <version>1.3.2</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>19.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jodd</groupId>
+            <artifactId>jodd-http</artifactId>
+            <version>3.8.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.nimbusds</groupId>
+            <artifactId>nimbus-jose-jwt</artifactId>
+            <version>4.34.2</version>
+        </dependency>
+        <dependency>
+            <groupId>com.ibeetl</groupId>
+            <artifactId>beetl</artifactId>
+            <version>2.7.14</version>
+        </dependency>
+        <dependency>
+            <groupId>net.minidev</groupId>
+            <artifactId>json-smart</artifactId>
+            <version>2.2.1</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.6</version>
+        </dependency>
+        <!--pinyin4j-->
+        <dependency>
+            <groupId>com.belerweb</groupId>
+            <artifactId>pinyin4j</artifactId>
+            <version>2.5.0</version>
+        </dependency>
+        <!--mapper-->
+        <dependency>
+            <groupId>tk.mybatis</groupId>
+            <artifactId>mapper</artifactId>
+            <version>4.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>2.8.2</version>
+        </dependency>
+        <dependency>
+            <groupId>com.qiniu</groupId>
+            <artifactId>qiniu-java-sdk</artifactId>
+            <version>[7.0.0, 7.2.99]</version>
+        </dependency>
+        <!--luncene-->
+        <dependency>
+            <groupId>org.apache.lucene</groupId>
+            <artifactId>lucene-core</artifactId>
+            <version>6.4.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.lucene</groupId>
+            <artifactId>lucene-queryparser</artifactId>
+            <version>6.4.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.lucene</groupId>
+            <artifactId>lucene-analyzers-common</artifactId>
+            <version>6.4.1</version>
+        </dependency>
+        <!-- 中文分词查询器smartcn-->
+        <dependency>
+            <groupId>com.janeluo</groupId>
+            <artifactId>ikanalyzer</artifactId>
+            <version>2012_u6</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-highlighter -->
+        <dependency>
+            <groupId>org.apache.lucene</groupId>
+            <artifactId>lucene-highlighter</artifactId>
+            <version>6.4.1</version>
+        </dependency>
+        <!-- Ehcache -->
+        <dependency>
+            <groupId>net.sf.ehcache</groupId>
+            <artifactId>ehcache-core</artifactId>
+            <version>2.6.6</version>
+        </dependency>
+        <dependency>
+            <groupId>org.owasp</groupId>
+            <artifactId>antisamy</artifactId>
+            <version>1.4</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>2.6.1</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>2.6.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>3.10.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>3.10.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.seleniumhq.selenium</groupId>
+            <artifactId>selenium-java</artifactId>
+            <version>3.4.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.0.2</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+            <version>5.0.0.Alpha2</version>
+        </dependency><dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-client</artifactId>
+        <version>11.0.6</version>
+        <scope>compile</scope>
+    </dependency>
+        <dependency>
+            <groupId>com.jayway.jsonpath</groupId>
+            <artifactId>json-path</artifactId>
+            <version>2.4.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.13</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <version>4.3.15.RELEASE</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-maven-plugin</artifactId>
+        </plugin>
+            <plugin>
+                <groupId>org.mybatis.generator</groupId>
+                <artifactId>mybatis-generator-maven-plugin</artifactId>
+                <version>1.4.0</version>
+                <configuration>
+                    <configurationFile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile>
+                    <verbose>true</verbose>
+                    <overwrite>true</overwrite>
+                </configuration>
+                <dependencies>
+                    <dependency>
+                        <groupId>mysql</groupId>
+                        <artifactId>mysql-connector-java</artifactId>
+                        <version>8.0.26</version>
+                    </dependency>
+                    <!-- 增加mybatis 通用mapper -->
+                    <dependency>
+                        <groupId>tk.mybatis</groupId>
+                        <artifactId>mapper</artifactId>
+                        <version>4.0.1</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>

+ 234 - 0
sookaCms.iml

@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
+    <facet type="web" name="Web">
+      <configuration>
+        <webroots>
+          <root url="file://$MODULE_DIR$/src/main/webapp" relative="/" />
+        </webroots>
+        <sourceRoots>
+          <root url="file://$MODULE_DIR$/src/main/java" />
+          <root url="file://$MODULE_DIR$/src/main/resources" />
+        </sourceRoots>
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" exported="" name="sqljdbc4" level="project" />
+    <orderEntry type="library" exported="" name="json-1.5-20090211" level="project" />
+    <orderEntry type="library" exported="" name="commons-httpclient-3.1" level="project" />
+    <orderEntry type="library" exported="" name="commons-lang-2.6" level="project" />
+    <orderEntry type="library" exported="" name="commons-lang3-3.3.2" level="project" />
+    <orderEntry type="library" exported="" name="ezmorph-1.0.6" level="project" />
+    <orderEntry type="library" exported="" name="json-lib-2.4-jdk15" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:1.5.11.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:1.5.11.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:1.5.11.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.1.11" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.1.11" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.25" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:log4j-over-slf4j:1.7.25" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.17" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-aop:4.3.15.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.8.13" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:1.5.11.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context:4.3.15.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:1.5.11.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:1.8.11.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:1.2.11.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:1.13.11.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-tx:4.3.15.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-oxm:4.3.15.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.25" level="project" />
+    <orderEntry type="library" name="Maven: redis.clients:jedis:2.9.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.4.3" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:1.5.11.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-jdbc:8.5.29" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-juli:8.5.29" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jdbc:4.3.15.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.session:spring-session:1.3.2.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:1.5.11.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate:hibernate-validator:5.3.6.Final" level="project" />
+    <orderEntry type="library" name="Maven: javax.validation:validation-api:1.1.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.2.Final" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.11.1" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.0" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.11" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-web:4.3.15.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-devtools:1.5.11.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:1.5.11.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:1.5.11.RELEASE" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.46" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:1.5.11.RELEASE" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:1.5.11.RELEASE" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:2.6.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:1.10.19" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.4.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-core:4.3.15.RELEASE" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:4.3.15.RELEASE" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:1.5.11.RELEASE" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:8.5.29" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.tomcat:tomcat-annotations-api:8.5.29" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:8.5.29" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:8.5.29" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:1.5.11.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.0" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.1.6" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid:1.1.6" level="project" />
+    <orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.1.3" level="project" />
+    <orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:1.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.jsoup:jsoup:1.9.2" level="project" />
+    <orderEntry type="library" name="Maven: com.github.penggle:kaptcha:2.3.2" level="project" />
+    <orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" />
+    <orderEntry type="library" name="Maven: com.jhlabs:filters:2.0.235-1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.44" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
+    <orderEntry type="library" name="Maven: org.quartz-scheduler:quartz:2.2.3" level="project" />
+    <orderEntry type="library" name="Maven: c3p0:c3p0:0.9.1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" />
+    <orderEntry type="library" name="Maven: org.quartz-scheduler:quartz-jobs:2.2.3" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context-support:4.3.15.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-beans:4.3.15.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-lang:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-cache:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-hash:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-core:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-cipher:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-config-core:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-config-ogdl:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-event:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-spring:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-web:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: org.owasp.encoder:encoder:1.2.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.3.2" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.2" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:guava:19.0" level="project" />
+    <orderEntry type="library" name="Maven: org.jodd:jodd-http:3.8.1" level="project" />
+    <orderEntry type="library" name="Maven: org.jodd:jodd-core:3.8.1" level="project" />
+    <orderEntry type="library" name="Maven: org.jodd:jodd-upload:3.8.1" level="project" />
+    <orderEntry type="library" name="Maven: com.nimbusds:nimbus-jose-jwt:4.34.2" level="project" />
+    <orderEntry type="library" name="Maven: com.github.stephenc.jcip:jcip-annotations:1.0-1" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.55" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.55" level="project" />
+    <orderEntry type="library" name="Maven: com.ibeetl:beetl:2.7.14" level="project" />
+    <orderEntry type="library" name="Maven: org.antlr:antlr4-runtime:4.2" level="project" />
+    <orderEntry type="library" name="Maven: org.abego.treelayout:org.abego.treelayout.core:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: org.antlr:antlr4-annotations:4.2" level="project" />
+    <orderEntry type="library" name="Maven: net.minidev:json-smart:2.2.1" level="project" />
+    <orderEntry type="library" name="Maven: net.minidev:accessors-smart:1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.ow2.asm:asm:5.0.3" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
+    <orderEntry type="library" name="Maven: com.belerweb:pinyin4j:2.5.0" level="project" />
+    <orderEntry type="library" name="Maven: tk.mybatis:mapper:4.0.1" level="project" />
+    <orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
+    <orderEntry type="library" name="Maven: joda-time:joda-time:2.8.2" level="project" />
+    <orderEntry type="library" name="Maven: com.qiniu:qiniu-java-sdk:7.2.29" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.squareup.okhttp3:okhttp:3.14.4" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.squareup.okio:okio:1.17.2" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.google.code.gson:gson:2.8.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.lucene:lucene-core:6.4.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.lucene:lucene-queryparser:6.4.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.lucene:lucene-queries:6.4.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.lucene:lucene-sandbox:6.4.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.lucene:lucene-analyzers-common:6.4.1" level="project" />
+    <orderEntry type="library" name="Maven: com.janeluo:ikanalyzer:2012_u6" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.lucene:lucene-highlighter:6.4.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.lucene:lucene-join:6.4.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.lucene:lucene-memory:6.4.1" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.6" level="project" />
+    <orderEntry type="library" name="Maven: org.owasp:antisamy:1.4" level="project" />
+    <orderEntry type="library" name="Maven: xerces:xercesImpl:2.8.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.xmlgraphics:batik-css:1.7" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.xmlgraphics:batik-ext:1.7" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.xmlgraphics:batik-util:1.7" level="project" />
+    <orderEntry type="library" name="Maven: xml-apis:xml-apis-ext:1.3.04" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.nekohtml:nekohtml:1.9.22" level="project" />
+    <orderEntry type="library" name="Maven: commons-httpclient:commons-httpclient:3.1" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:2.6.1" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.10" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.10" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spi:2.6.1" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-core:2.6.1" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-schema:2.6.1" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:2.6.1" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:2.6.1" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml:classmate:1.3.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.0.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:2.6.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi:3.10.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:3.10.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.10.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.6.0" level="project" />
+    <orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: dom4j:dom4j:1.6.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.seleniumhq.selenium:selenium-java:3.4.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.seleniumhq.selenium:selenium-api:2.53.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.seleniumhq.selenium:selenium-chrome-driver:2.53.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.seleniumhq.selenium:selenium-edge-driver:2.53.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.seleniumhq.selenium:selenium-firefox-driver:2.53.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.seleniumhq.selenium:selenium-ie-driver:2.53.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.seleniumhq.selenium:selenium-opera-driver:3.4.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.seleniumhq.selenium:selenium-remote-driver:2.53.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.seleniumhq.selenium:selenium-safari-driver:2.53.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: io.netty:netty:3.5.7.Final" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.seleniumhq.selenium:selenium-support:2.53.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: cglib:cglib-nodep:3.2.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.commons:commons-exec:1.3" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.w3c.css:sac:1.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: net.sourceforge.cssparser:cssparser:0.9.22" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: net.sourceforge.htmlunit:htmlunit:2.21" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: net.sourceforge.htmlunit:htmlunit-core-js:2.26" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: net.sourceforge.htmlunit:neko-htmlunit:2.25" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.9" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.httpcomponents:httpmime:4.5.5" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.4.9.v20180320" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.4.9.v20180320" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: net.java.dev.jna:jna:4.2.2" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: net.java.dev.jna:jna-platform:4.2.2" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.codeborne:phantomjsdriver:1.4.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.seleniumhq.selenium:htmlunit-driver:2.21" level="project" />
+    <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.9.v20180320" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.9.v20180320" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.eclipse.jetty:jetty-xml:9.4.9.v20180320" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.9.v20180320" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: xalan:serializer:2.7.2" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: xalan:xalan:2.7.2" level="project" />
+    <orderEntry type="library" name="Maven: xml-apis:xml-apis:1.4.01" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.13" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-all:5.0.0.Alpha2" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:11.0.6" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-http:9.4.9.v20180320" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-alpn-client:9.4.9.v20180320" level="project" />
+    <orderEntry type="library" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.projectlombok:lombok:1.16.20" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-webmvc:4.3.15.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-expression:4.3.15.RELEASE" level="project" />
+  </component>
+</module>

+ 3 - 0
src/main/java/META-INF/MANIFEST.MF

@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: com.sooka.CmsApplication
+

+ 3 - 0
src/main/java/META-INF/spring-devtools.properties

@@ -0,0 +1,3 @@
+restart.include.mapper=/mapper-[\\w-\\.]+jar
+restart.include.pagehelper=/pagehelper-[\\w-\\.]+jar
+restart.include.beetl=/beetl-[\\w-\\.]+jar

+ 38 - 0
src/main/java/com/sooka/CmsApplication.java

@@ -0,0 +1,38 @@
+package com.sooka;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.MultipartConfigFactory;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.servlet.MultipartConfigElement;
+
+
+@SpringBootApplication
+@EnableTransactionManagement
+@EnableCaching
+public class CmsApplication {
+
+	public static void main(String[] args){
+		SpringApplication.run(CmsApplication.class, args);
+	}
+	
+
+
+	/**
+	 * 文件上传配置
+	 *
+	 * @return
+	 */
+	@Bean
+	public MultipartConfigElement multipartConfigElement() {
+		MultipartConfigFactory factory = new MultipartConfigFactory();
+		//  单个数据大小
+		factory.setMaxFileSize("512000KB"); // KB,MB
+		/// 总上传数据大小
+		factory.setMaxRequestSize("10240000KB");
+		return factory.createMultipartConfig();
+	}
+}

+ 12 - 0
src/main/java/com/sooka/ServletInitializer.java

@@ -0,0 +1,12 @@
+package com.sooka;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+
+
+public class ServletInitializer extends SpringBootServletInitializer {
+    @Override
+    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+        return application.sources(CmsApplication.class);
+    }
+}

File diff suppressed because it is too large
+ 161 - 0
src/main/java/com/sooka/Test.java


+ 104 - 0
src/main/java/com/sooka/common/MyApplicationRunner.java

@@ -0,0 +1,104 @@
+package com.sooka.common;
+
+import com.sooka.common.aop.FormTokenAspect;
+import com.sooka.common.utils.DateUtil;
+import com.sooka.common.utils.StrUtil;
+import com.sooka.component.lucene.LuceneManager;
+import com.sooka.component.lucene.util.IndexObject;
+import com.sooka.module.web.cms.service.ContentService;
+import com.sooka.module.web.cms.service.SiteService;
+import com.sooka.mybatis.model.TCmsContent;
+import com.sooka.mybatis.model.TCmsSite;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.context.annotation.Scope;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.List;
+//import java.util.Timer;
+//import java.util.TimerTask;
+
+@Component//被spring容器管理
+@Order(1)//如果多个自定义ApplicationRunner,用来标明执行顺序
+@Scope("prototype")
+public class MyApplicationRunner implements ApplicationRunner {
+
+    @Value("${system.http.protocol}")
+    private String httpProtocol;
+
+    @Value("${system.site.subfix}")
+    private String siteSubfix;
+
+    @Value("${system.http.host}")
+    private String httpHost;
+
+    @Value("${system.site.prefix}")
+    private String sitePrefix;
+
+    @Autowired
+    private SiteService siteService;
+    @Autowired
+    LuceneManager luceneManager;
+    @Autowired
+    private ContentService contentService;
+
+    private static final Logger log = LoggerFactory.getLogger(FormTokenAspect.class);
+
+    @Override
+    public void run(ApplicationArguments applicationArguments)  {
+        System.out.println("-------------->" + "项目启动,now=" + new Date());
+        //清空防止重复
+        System.out.println("-------------->" + "清空lucene索引,now=" + new Date());
+        luceneManager.deleteAll();
+        System.out.println("-------------->" + "查询所有content数据,now=" + new Date());
+        List<TCmsContent> list=contentService.findAll();
+        System.out.println("-------------->" + "创建lucene索引,now=" + new Date());
+
+
+
+        for (TCmsContent content:list) {
+            IndexObject object2 = new IndexObject();
+            TCmsSite site = siteService.findById(content.getSiteId());
+            if(site!=null){
+                String url = httpProtocol + "://" + (StrUtil.isBlank(site.getDomain())?httpHost:site.getDomain()) + "/"+sitePrefix+"/"+site.getSiteId()+"/";
+                url+=content.getCategoryId()+"/"+content.getContentId();
+                object2.setUrl(url+siteSubfix);
+            }else {
+                object2.setUrl("");
+            }
+            try {
+                object2.setTitle(content.getTitle());
+                object2.setId(content.getContentId().toString());
+                object2.setKeywords(content.getKeywords());
+                object2.setPostDate(DateUtil.formatDate(content.getInputdate()));
+                object2.setDescription(content.getDescription());
+                luceneManager.create(object2);
+            }catch (Exception e ){
+                System.out.println("-------------->" + "创建lucene报错,now=" + e.getMessage());
+            }
+
+        }
+
+
+
+
+
+//        myTimer();
+    }
+
+//    public static void myTimer(){
+//        Timer timer = new Timer();
+//        timer.schedule(new TimerTask() {
+//            @Override
+//            public void run() {
+//                System.out.println("------定时任务--------");
+//            }
+//        }, 0, 1000);
+//    }
+}

+ 15 - 0
src/main/java/com/sooka/common/annotation/ApiValidate.java

@@ -0,0 +1,15 @@
+package com.sooka.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Created by binary on 2017/4/10.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface ApiValidate {
+
+    boolean checkSignature() default true;
+
+}

+ 20 - 0
src/main/java/com/sooka/common/annotation/ExcelField.java

@@ -0,0 +1,20 @@
+package com.sooka.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Created by binary on 2017/4/10.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface ExcelField {
+
+    String value() default "";
+
+    String dateFormat() default "";
+
+    boolean isOnlyImport() default false;
+
+    String isNullDefaultValue() default "N/A";
+}

+ 15 - 0
src/main/java/com/sooka/common/annotation/FormToken.java

@@ -0,0 +1,15 @@
+package com.sooka.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Created by binary on 2017/4/10.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface FormToken {
+
+    /*TODO 验证码校验 */
+    boolean value() default false;
+}

+ 19 - 0
src/main/java/com/sooka/common/annotation/ParamNotNull.java

@@ -0,0 +1,19 @@
+package com.sooka.common.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 参数非空校验注解
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface ParamNotNull {
+
+	/**校验的参数,多个参数用,号分割,如 parameter="userId,userName"*/
+    String parameter();
+}

+ 15 - 0
src/main/java/com/sooka/common/annotation/SysLog.java

@@ -0,0 +1,15 @@
+package com.sooka.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Created by binary on 2017/4/10.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface SysLog {
+
+    String value() default "";
+
+}

+ 89 - 0
src/main/java/com/sooka/common/aop/ApiValidateAspect.java

@@ -0,0 +1,89 @@
+package com.sooka.common.aop;
+
+import com.sooka.common.annotation.ApiValidate;
+import com.sooka.common.exception.ApiException;
+import com.sooka.common.utils.CheckSumUtil;
+import com.sooka.common.utils.StrUtil;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.lang.reflect.Method;
+
+@Aspect
+@Component
+public class ApiValidateAspect {
+
+	private String appSecrt ="jdeFDS89HFassdsfFDNDS73FDJK";
+	private String[] appids={"1000","2000"};
+
+	private static final Logger log = LoggerFactory.getLogger(ApiValidateAspect.class);
+
+	@Around("@annotation(com.sooka.common.annotation.ApiValidate)")
+	public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
+		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+		HttpServletRequest request = attributes.getRequest();
+		HttpServletResponse response =  attributes.getResponse();
+        return this.validation(joinPoint,request,response);
+
+	}
+
+
+	public Object validation(ProceedingJoinPoint joinPoint, HttpServletRequest request,HttpServletResponse response) throws Throwable {
+		/*获取请求参数*/
+		String appId= request.getParameter("appid");
+		String nonce= request.getParameter("nonce");
+		String signature= request.getParameter("signature");
+		String timestamp= request.getParameter("timestamp");
+        /*获取方法名称*/
+		String methodName = joinPoint.getSignature().getName();
+		Method method = currentMethod(joinPoint, methodName);
+		ApiValidate log = method.getAnnotation(ApiValidate.class);
+		/* 验证appId */
+		if(StrUtil.isBlank(appId)) {
+            throw new ApiException("appId Can not be empty!");
+        }
+		if(!StrUtil.isContain(appids,appId)) {
+            throw new ApiException("appId validate failed!");
+        }
+		/* 是否需要验证 Signature */
+		if(!log.checkSignature()) {
+            return joinPoint.proceed();
+        }
+		/* 验证timestamp */
+		if(StrUtil.isBlank(timestamp)) {
+            throw new ApiException("timestamp Can not be empty!");
+        }
+		if((Long.parseLong(CheckSumUtil.getTimestamp())-Long.parseLong(timestamp))>220) {
+            throw new ApiException("the signature has be Expired!");
+        }
+		/* 验证signature */
+		if(StrUtil.isBlank(signature)) {
+            throw new ApiException("signature Can not be empty!");
+        }
+        if(!CheckSumUtil.getCheckSum(appSecrt,nonce,timestamp).trim().equals(signature.trim())) {
+            throw new ApiException("API interface parameter validation failed!");
+        }
+		return joinPoint.proceed();
+	}
+
+
+	public  Method currentMethod(ProceedingJoinPoint joinPoint,String methodName){
+		Method[] methods = joinPoint.getTarget().getClass().getMethods();
+		Method resultMethod = null;
+		for (Method method : methods) {
+			if (method.getName().equals(methodName)) {
+				resultMethod = method;
+				break;
+			}
+		}
+		return resultMethod;
+	}
+}

+ 69 - 0
src/main/java/com/sooka/common/aop/FormTokenAspect.java

@@ -0,0 +1,69 @@
+package com.sooka.common.aop;
+
+import com.sooka.common.exception.SystemException;
+import com.sooka.common.utils.StrUtil;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+@Aspect
+@Component
+public class FormTokenAspect {
+
+	private static final String PARAM_TOKEN = "token";
+	private static final String PARAM_TOKEN_FLAG = "TokenFlag_";
+
+	private static final Logger log = LoggerFactory.getLogger(FormTokenAspect.class);
+
+	@Around("@annotation(com.sooka.common.annotation.FormToken)")
+	public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
+		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+		HttpServletRequest request = attributes.getRequest();
+		HttpServletResponse response =  attributes.getResponse();
+		String className = joinPoint.getTarget().getClass().getName();
+		HttpSession session = request.getSession();
+		if ("GET".equalsIgnoreCase(request.getMethod())) {
+			log.info("生成token");
+			/* GET 生成 token */
+		 return   this.generate(joinPoint, request, session, PARAM_TOKEN_FLAG + className);
+		} else {
+			log.info("验证token");
+			/* POST 验证 token */
+		 return   this.validation(joinPoint, request,response, session, PARAM_TOKEN_FLAG + className);
+		}
+
+	}
+
+
+	public Object generate(ProceedingJoinPoint joinPoint, HttpServletRequest request, HttpSession session,
+			String tokenFlag) throws Throwable {
+		String uuid = StrUtil.getUUID().toString();
+		String tokenInput = "<input id=\"token\"  type=\"hidden\" name=\""+PARAM_TOKEN+"\" value=\"" + uuid + "\">";
+		session.setAttribute(tokenFlag, uuid);
+		request.setAttribute(PARAM_TOKEN, tokenInput);
+		return joinPoint.proceed();
+	}
+
+
+	public Object validation(ProceedingJoinPoint joinPoint, HttpServletRequest request,HttpServletResponse response, HttpSession session,
+			String tokenFlag) throws Throwable {
+		Object sessionFlag = session.getAttribute(tokenFlag);
+		Object requestFlag = request.getParameter(PARAM_TOKEN);
+		if (requestFlag!=null&&sessionFlag != null && sessionFlag.equals(requestFlag)) {
+			session.removeAttribute(tokenFlag);
+		}else {
+			throw new SystemException("不能重复提交表单!");
+		}
+		return joinPoint.proceed();
+	}
+
+}

+ 103 - 0
src/main/java/com/sooka/common/aop/LogAspect.java

@@ -0,0 +1,103 @@
+package com.sooka.common.aop;
+
+import com.sooka.module.web.system.service.LogService;
+import com.sooka.common.annotation.SysLog;
+import com.sooka.common.utils.ControllerUtil;
+import com.sooka.common.utils.StrUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.Enumeration;
+
+
+@Aspect
+@Component
+public class LogAspect {
+
+    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
+    private static final String LOG_CONTENT = "[类名]:%s <br/>[方法]:%s <br>[参数]:%s <br/>[  IP ]:%s";
+
+    @Autowired
+    @Lazy
+    private LogService logService;
+
+    @Around("@annotation(com.sooka.common.annotation.SysLog)")
+    public Object saveLog(ProceedingJoinPoint joinPoint) throws Throwable {
+
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+        String methodName = joinPoint.getSignature().getName();
+        Method method = currentMethod(joinPoint, methodName);
+        SysLog log = method.getAnnotation(SysLog.class);
+        HttpSession session = request.getSession();
+        String principal =(String) session.getAttribute("username");
+        if(StrUtil.isBlank(principal)) {
+            principal = " - ";
+        }
+        if (log != null) {
+            logger.info("@Syslog value : {} username:{}",log.value());
+            String content =buildeContent(joinPoint, methodName, request);
+            logService.saveLog(content,new Date(),principal,log.value());
+        }
+        return joinPoint.proceed();
+    }
+
+
+    /**
+     * 获取当前方法
+     * @param joinPoint
+     * @param methodName
+     * @return
+     */
+    public  Method currentMethod(ProceedingJoinPoint joinPoint,String methodName){
+        Method[] methods = joinPoint.getTarget().getClass().getMethods();
+        Method resultMethod = null;
+        for (Method method : methods) {
+            if (method.getName().equals(methodName)) {
+                resultMethod = method;
+                break;
+            }
+        }
+        return resultMethod;
+    }
+
+    /**
+     * 日志内容
+     * @param joinPoint
+     * @param methodName
+     * @param request
+     * @return
+     */
+    public String buildeContent(ProceedingJoinPoint joinPoint, String methodName, HttpServletRequest request) {
+        String className = joinPoint.getTarget().getClass().getName();
+        Object[] params = joinPoint.getArgs();
+        StringBuffer bf = new StringBuffer();
+        if (params != null && params.length > 0) {
+            Enumeration<String> paraNames = request.getParameterNames();
+            while (paraNames.hasMoreElements()) {
+                String key = paraNames.nextElement();
+                bf.append(key).append("=");
+                bf.append(request.getParameter(key)).append("&");
+            }
+            if (StringUtils.isBlank(bf.toString())) {
+                bf.append(request.getQueryString());
+            }
+        }
+        logger.info("REQUEST PARAMS :"+bf.toString());
+        return String.format(LOG_CONTENT, className, methodName, bf.toString(), ControllerUtil.getRemoteAddress(request));
+    }
+
+}

+ 35 - 0
src/main/java/com/sooka/common/aop/ParamNotNullAspect.java

@@ -0,0 +1,35 @@
+package com.sooka.common.aop;
+
+import com.sooka.common.annotation.ParamNotNull;
+import com.sooka.common.exception.ApiException;
+import org.apache.commons.lang.StringUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+
+@Component
+@Aspect
+public class ParamNotNullAspect {
+
+	@Autowired
+	private HttpServletRequest request;
+
+
+	/**参数是否为空统一校验*/
+	@Around("@annotation(com.sooka.common.annotation.ParamNotNull) && @annotation(paramNotNull)")
+	public Object advice(ProceedingJoinPoint joinPoint,ParamNotNull paramNotNull) throws Throwable{
+		String[] paraName = paramNotNull.parameter().split(",");
+		for (String para : paraName) {
+			String parameter2 = request.getParameter(para);
+			if (StringUtils.isEmpty(parameter2)) {
+				throw new ApiException("参数[" + para + "]不能为空");
+			}
+		}
+		return joinPoint.proceed();
+	}
+	
+}

+ 23 - 0
src/main/java/com/sooka/common/base/BaseController.java

@@ -0,0 +1,23 @@
+package com.sooka.common.base;
+
+import org.springframework.ui.Model;
+
+import java.sql.SQLException;
+
+public abstract class BaseController<T> {
+
+     /*首页方法*/
+   public abstract String index(Integer pageNumber,
+                  Integer pageSize,
+                  T pojo,
+                  Model model);
+
+     /*输入页面*/
+     public abstract String input(Integer Id, Model model);
+
+     /*保存方法*/
+     public  abstract  String save(T pojo) throws SQLException;
+
+     /*删除方法*/
+     public abstract String delete(Integer[] ids) throws SQLException;
+}

+ 22 - 0
src/main/java/com/sooka/common/base/BaseService.java

@@ -0,0 +1,22 @@
+package com.sooka.common.base;
+
+import com.github.pagehelper.PageInfo;
+
+import java.io.Serializable;
+import java.util.List;
+
+
+public interface BaseService<T,I extends Serializable> {
+
+    String save(T pojo);
+    String update(T pojo);
+    String delete(I[] ids);
+    T findById(I id);
+    List<T> findList(T pojo);
+    List<T> findAll();
+    PageInfo<T> page(Integer pageNumber, Integer pageSize, T pojo);
+    PageInfo<T> page(Integer pageNumber, Integer pageSize);
+
+
+
+}

+ 44 - 0
src/main/java/com/sooka/common/captcha/CaptchaConfiguration.java

@@ -0,0 +1,44 @@
+package com.sooka.common.captcha;
+
+
+import com.google.code.kaptcha.Constants;
+import com.google.code.kaptcha.impl.DefaultKaptcha;
+import com.google.code.kaptcha.util.Config;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Properties;
+
+@Configuration
+public class CaptchaConfiguration {
+
+    @Bean
+    public DefaultKaptcha getCaptchaProducer(@Value("${kcaptcha.img.width}") String imgWidth,
+                                              @Value("${kcaptcha.img.hight}") String imgHight,
+                                              @Value("${kcaptcha.font.size}")  String fontSize,
+                                              @Value("${kcaptcha.font.color}") String fontColor,
+                                              @Value("${kcaptcha.char.length}") String charLength){
+
+        DefaultKaptcha kcaptcha = new DefaultKaptcha();
+        Properties prop= new Properties();
+        prop.setProperty(Constants.KAPTCHA_BORDER,"no");
+        prop.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR,fontColor);
+        prop.setProperty(Constants.KAPTCHA_IMAGE_WIDTH,imgWidth);
+        prop.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT,imgHight);
+        prop.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE,fontSize);
+        prop.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH,charLength);
+        prop.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE,"4");
+//        prop.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_NAMES,"宋体,楷体,微软雅黑");
+        prop.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL,"com.google.code.kaptcha.impl.ShadowGimpy");
+        prop.setProperty(Constants.KAPTCHA_NOISE_COLOR,"green");
+        prop.setProperty(Constants.KAPTCHA_NOISE_IMPL,"com.google.code.kaptcha.impl.NoNoise");
+//        prop.setProperty(Constants.KAPTCHA_TEXTPRODUCER_IMPL,"ChineseTextProducer");
+        Config cfg = new Config(prop);
+        kcaptcha.setConfig(cfg);
+        return kcaptcha;
+
+    }
+
+
+}

+ 72 - 0
src/main/java/com/sooka/common/captcha/CaptchaController.java

@@ -0,0 +1,72 @@
+package com.sooka.common.captcha;
+
+import com.alibaba.fastjson.JSONObject;
+import com.google.code.kaptcha.Constants;
+import com.google.code.kaptcha.Producer;
+import com.sooka.common.utils.StrUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.imageio.ImageIO;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.awt.image.BufferedImage;
+
+@Controller
+public class CaptchaController {
+
+    Logger log = LoggerFactory.getLogger(this.getClass());
+
+    @Autowired
+    private Producer captchaProducer;
+
+
+    @RequestMapping("/verify")
+    public ModelAndView doGet(HttpServletResponse response, HttpSession session)  {
+        response.setDateHeader("Expires", 0);
+        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
+        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
+        response.setHeader("Pragma", "no-cache");
+        response.setContentType("image/jpeg");
+        String capText = captchaProducer.createText();
+        BufferedImage bi = captchaProducer.createImage(capText);
+        session.setAttribute(Constants.KAPTCHA_SESSION_KEY,capText);
+        try {
+        ServletOutputStream out = response.getOutputStream();
+        log.debug("captchaProducer.createText:"+capText);
+        ImageIO.write(bi, "jpg", out);
+        out.flush();
+        out.close();
+        }catch(Exception e){
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    @RequestMapping("/verify/validate")
+    @ResponseBody
+    public String validateVerifyCode(@RequestParam("verifyCode") String verify,HttpSession session){
+        JSONObject result = new JSONObject();
+        if (validate(verify,session)){
+            result.put("ok","验证码输入正确!");
+        }else{
+            result.put("error","验证码错误,请刷新或重新输入!");
+        }
+    return result.toJSONString();
+    }
+
+    public static  boolean validate(String verifyCode,HttpSession session) {
+        String text = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
+        if (StrUtil.isBlank(text)) {
+            return false;
+        }
+        return verifyCode.equals(text);
+    }
+}

+ 27 - 0
src/main/java/com/sooka/common/captcha/ChineseTextProducer.java

@@ -0,0 +1,27 @@
+package com.sooka.common.captcha;
+
+import com.google.code.kaptcha.text.TextProducer;
+import java.util.Random;
+
+public class ChineseTextProducer implements TextProducer {
+    private String[] simplifiedChineseTexts = new String[]{
+            "渔父引 ", "闲中好" ,"纥那曲" ,"拜新月" ,"梧桐影","罗贡曲" ,"醉妆词" ,
+            "庆先和", "南歌子" ,"占春芳" ,"荷叶杯" ,"回波集" ,"舞马词" ,"柘枝词 " ,
+            "晴偏好 " , "凭栏人" ,"花非花" ,"摘得新" ,"梧叶儿" ,"唉乃曲" ,"采莲子" ,
+            "浪淘沙" , "杨柳枝" ,"八拍蛮" ,"字字变" ,"十样花" ,"天净沙" ,"甘州曲" ,
+            "喜春来" , "踏歌词" , "秋风清" , "抛球乐" , "一叶秋" ,"忆王孙" ,"金字经" ,
+            "古调笑" , "遐方怨","西溪子" ,"天仙子 " ,"风流子 " , "归字谣 " ,"饮马歌 " ,
+            "相见欢 " ,"定西番 " , "江城子 " , "望江怨", "平易近人", "宽宏大度", "冰清玉洁",
+            "足智多谋", "融会贯通", "举一反三", "相貌堂堂", "神采奕奕", "悠然自得", "欣喜若狂", "呆若木鸡",
+            "望梅止渴", "铁杵成针", "欢呼雀跃", "血浓于水", "温故知新", "画龙点睛", "滥竽充数", "守株待兔",
+            "无懈可击", "春意盎然", "冰天雪地", "热火朝天", "巧夺天工", "高耸入云", "水天一色", "波光粼粼",
+            "湖光山色", "大雨如注", "百依百顺", "道听途说", "南辕北辙", "左推右挡" };
+
+    public ChineseTextProducer() {
+    }
+
+    @Override
+    public String getText() {
+        return this.simplifiedChineseTexts[(new Random()).nextInt(this.simplifiedChineseTexts.length)];
+    }
+}

+ 40 - 0
src/main/java/com/sooka/common/constant/CmsConst.java

@@ -0,0 +1,40 @@
+package com.sooka.common.constant;
+
+/**
+ * Description:内容管理系统字典
+ *
+ *
+ * @create 2017-06-01
+ **/
+public class CmsConst {
+
+    public static  final String SITE_NOT_FOUND ="站点不存在或已经被删除,请与系统管理员联系!";
+
+    public static  final String SITE_LOCKED ="当前站点已经停用,请与系统管理员联系!";
+
+    public static  final  String PAGE_NOT_FOUND ="页面被删除或者不存在!";
+
+    public static  final  String CATEGORY_NOT_FOUND ="栏目已经被删除或者不存在!";
+
+    public static  final  String CONTENT_NOT_FOUND ="内容已经被删除或者不存在!";
+
+    public static  final  String TOPIC_NOT_FOUND ="专题已经被删除或者不存在!";
+
+    public static  final  String SEARCH_KEYWORD_NOT_FOUND ="搜索关键字不能为空!";
+
+    public static final String SITE_USER_SESSION_KEY = "SysUser";
+
+    public static final String TEMPLATE_PATH = "theme/";
+
+    public static final String INDEX_TPL= "index";
+
+    public static final String CATEGORY_INDEX_TPL= "category";
+
+    public static final String CATEGORY_LIST_TPL= "category_list";
+
+    public static final String CONTENT_TPL= "content";
+
+    public static final String SEARCH_TPL= "search";
+
+    public static final String TOPIC_TPL= "topic";
+}

+ 14 - 0
src/main/java/com/sooka/common/constant/Const.java

@@ -0,0 +1,14 @@
+package com.sooka.common.constant;
+
+/**
+ * Description:
+ *
+ *
+ * @create 2017-07-10
+ **/
+public class Const {
+    public static final String STATUS_RUNNING = "1";
+    public static final String STATUS_NOT_RUNNING = "0";
+    public static final String CONCURRENT_IS = "1";
+    public static final String CONCURRENT_NOT = "0";
+}

+ 37 - 0
src/main/java/com/sooka/common/db/DbTableAssistant.java

@@ -0,0 +1,37 @@
+package com.sooka.common.db;
+
+import com.sooka.common.db.impl.M;
+
+/**
+ * Description:数据库建表
+ *
+ *
+ * @create 2017-04-18
+ **/
+public interface DbTableAssistant<T> {
+
+    T create();
+
+    T edit();
+
+    T delete();
+
+    String BuilderSQL();
+
+    T TableName(String tableName);
+
+    T InitColumn(String columnName, M columnType, Integer length, boolean autoIncrement, String defaultValue, boolean isNotNull,boolean isPrimaryKey);
+
+    T AddColumn(String columnName,M columnType,Integer length, boolean autoIncrement,String defaultValue,boolean isNotNull,boolean isPrimaryKey);
+
+    T ChangeColumn(String columnName,String newColumnNane,M columnType,Integer length,boolean autoIncrement,String defaultValue,boolean isNotNull);
+
+    T DropColumn(String columnName,boolean isPrimaryKey);
+
+    T AddIndex(String cloumnName,Integer length);
+
+    T Engine(String engineName);
+
+    T CharSet(String charset);
+
+}

+ 95 - 0
src/main/java/com/sooka/common/db/DbTableAssistantService.java

@@ -0,0 +1,95 @@
+package com.sooka.common.db;
+
+import com.sooka.common.db.impl.M;
+import com.sooka.common.db.impl.MysqlDbTableAssistant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import static com.sooka.common.db.impl.M.BIG_INT_TYPE;
+
+/**
+ * Description:很神奇的一个类 哈哈
+ *
+ *
+ * @create 2017-05-08
+ *
+ **/
+@Service
+public class DbTableAssistantService{
+
+
+    private final static Logger log = LoggerFactory.getLogger(DbTableAssistantService.class);
+
+    private final String PRIMARY_KEY = "content_id";
+    private final String TABLE_PREFIX = "t_cms_content_";
+
+    @Autowired
+    private MysqlDbTableAssistant mysql;
+
+    @Autowired
+    @Qualifier("masterDataSource")
+    private DataSource dataSource;
+
+
+    public void createDbtable(String tableName) throws SQLException {
+            String sql = mysql.create().TableName(TABLE_PREFIX+tableName).InitColumn(PRIMARY_KEY, BIG_INT_TYPE,20,false,"0",true,true).BuilderSQL();
+            Connection connection = dataSource.getConnection();
+            Statement statement = connection.createStatement();
+            statement.execute(sql);
+            statement.close();
+            connection.close();
+    }
+
+    public void deleteDbtable(String tableName) throws SQLException {
+        log.info("create table  [{}] begin",tableName);
+
+        String sql = mysql.delete().TableName(TABLE_PREFIX+tableName).BuilderSQL();
+        Connection connection = dataSource.getConnection();
+        Statement statement = connection.createStatement();
+        statement.execute(sql);
+        statement.close();
+        connection.close();
+    }
+
+    public void addDbTableColumn(String tableName, String columnName, M columnType, Integer length, boolean autoIncrement, String defaultValue, boolean isNotNull, boolean isPrimaryKey) throws SQLException {
+           log.info("create table [{}] column [{}] begin",tableName,columnName);
+            String sql = mysql.edit().TableName(TABLE_PREFIX+tableName).AddColumn(columnName,columnType,length,autoIncrement,defaultValue,isNotNull,isPrimaryKey).BuilderSQL();
+            Connection connection = dataSource.getConnection();
+            Statement statement = connection.createStatement();
+            statement.execute(sql);
+            statement.close();
+            connection.close();
+    }
+
+
+    public void editDbTableColumn(String tableName, String columnName,String newColumnName, M columnType, Integer length, boolean autoIncrement, String defaultValue, boolean isNotNull) throws SQLException {
+        log.info("create table [{}] column [{}] begin",tableName,columnName);
+            String sql = mysql.edit().TableName(TABLE_PREFIX+tableName).ChangeColumn(columnName,newColumnName,columnType,length,autoIncrement,defaultValue,isNotNull).BuilderSQL();
+            Connection connection = dataSource.getConnection();
+            Statement statement = connection.createStatement();
+            statement.execute(sql);
+            statement.close();
+            connection.close();
+    }
+
+    public void deleteDbTableColumn(String tableName, String columnName, boolean isPrimaryKey) throws SQLException {
+        log.info("create table [{}]  column [{}] begin",tableName,columnName);
+
+            String sql = mysql.edit().TableName(TABLE_PREFIX+tableName).DropColumn(columnName,isPrimaryKey).BuilderSQL();
+            Connection connection = dataSource.getConnection();
+            Statement statement = connection.createStatement();
+            statement.execute(sql);
+            statement.close();
+            connection.close();
+        log.info("created table [{}] column [{}] success",tableName,columnName);
+    }
+
+}

+ 48 - 0
src/main/java/com/sooka/common/db/impl/M.java

@@ -0,0 +1,48 @@
+package com.sooka.common.db.impl;
+
+
+/**
+ * Description:token
+ *
+ *
+ * @create 2017-04-05
+ **/
+public enum M{
+
+
+	INT_TYPE("int"),
+	TNY_INT_TYPE("tinyint"),
+	BIG_INT_TYPE("bigint"),
+	SMALL_INT_TYPE("smallint"),
+	MEDIUM_INT_TYPE("mediumint"),
+
+	/* 小数 */
+	DECIMAL_TYPE("decimal"),
+
+	/*日期*/
+	DATE_TYPE("date"),
+	TIMESTAMP_TYPE("timestamp"),
+
+	/* 文本 */
+	CHAR_TYPE("char"),
+	VARCHAR_TYPE("varchar"),
+	TEXT_TYPE("text"),
+	MEDIUM_TEXT_TYPE("mediumText"),
+	LONG_TEXT_TYPE("longText");
+
+	private String value;
+
+	M(String _value){
+		this.value=_value;
+	}
+
+
+	@Override
+	public String toString() {
+		return value;
+	}
+
+	public  static void  main(String [] args){
+		System.out.println(M.valueOf("CHAR_TYPE"));
+	}
+}

+ 215 - 0
src/main/java/com/sooka/common/db/impl/MysqlDbTableAssistant.java

@@ -0,0 +1,215 @@
+package com.sooka.common.db.impl;
+
+import com.sooka.common.db.DbTableAssistant;
+import com.sooka.common.db.kit.MysqlFiledUtil;
+import com.sooka.common.exception.SystemException;
+import com.sooka.common.utils.StrUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+/**
+ * Description:mysql
+ *
+ *
+ * @create 2017-04-18
+ **/
+@Component
+@Scope("prototype")
+public class MysqlDbTableAssistant implements DbTableAssistant<MysqlDbTableAssistant> {
+
+    private final static Logger log = LoggerFactory.getLogger(MysqlDbTableAssistant.class);
+
+    /* 创建表 开始*/
+    private final static String CREATE_TABLE_BEGIN = "CREATE TABLE `{table}` (";
+
+    /* 创建表 结束*/
+    private final static String CREATE_TABLE_END = ") ";
+
+    /*删除表*/
+    private final static String DROP_TABLE = "DROP TABLE `{table}` ";
+
+    /*编辑表*/
+    private final static String ALTER_TABLE_BEGIN = "ALTER TABLE `{table}`";
+
+    private final static String CHANGE_COLUMN = " CHANGE COLUMN ";
+
+    private final static String ADD_COLUMN = " ADD COLUMN ";
+
+    private final static String DROP_COLUMN = " DROP COLUMN ";
+
+    private String sql_head = "";
+
+    private String sql_body="";
+
+    private String sql_foot="";
+
+    private void init(){
+
+        this.sql_head = "";
+
+        this.sql_body = "";
+
+        this.sql_foot = "";
+    }
+
+    @Override
+    public MysqlDbTableAssistant create() {
+        this.init();
+        this.sql_head=CREATE_TABLE_BEGIN;
+        this.sql_foot=CREATE_TABLE_END;
+        return this;
+    }
+
+    @Override
+    public MysqlDbTableAssistant edit() {
+        this.init();
+        this.sql_head = ALTER_TABLE_BEGIN;
+        return this;
+    }
+
+    @Override
+    public MysqlDbTableAssistant delete() {
+        this.init();
+        this.sql_head = DROP_TABLE;
+
+        return this;
+    }
+
+    @Override
+    public String BuilderSQL() {
+        String SQL = this.sql_head+this.sql_body+this.sql_foot;
+        log.info(SQL);
+        return SQL;
+    }
+
+    @Override
+    public MysqlDbTableAssistant TableName(String tableName) {
+        this.sql_head=this.sql_head.replace("{table}",tableName);
+        return this;
+    }
+
+    @Override
+    public MysqlDbTableAssistant InitColumn(String columnName, M columnType, Integer length,boolean autoIncrement, String defaultValue, boolean isNotNull,boolean isPrimaryKey) {
+        if(MysqlFiledUtil.isCharTextFiled(columnType))/*判断字段是否允许设置长度*/ {
+            this.sql_body = " `"+columnName+"`" + columnType+"("+length+")";
+        } else {
+            this.sql_body = " `"+columnName+"`" + columnType;
+        }
+        if(isNotNull)/*判断字段是否不为空*/ {
+            this.sql_body+=" NOT null";
+        }
+        if (!autoIncrement) {
+            if(!isNotNull)/*判断字段是否允许为空*/ {
+                this.sql_body+=" NULL ";
+            }
+            this.sql_body += " DEFAULT " +  (StrUtil.isBlank(defaultValue)?null:"'"+defaultValue+"'");
+        } else { /* 判断字段类型是否支持自动增长 */
+            if(MysqlFiledUtil.isAutoIncrementFiled(columnType)) {
+                if (!isNotNull) {
+                    this.sql_body += " NOT null";
+                }
+                this.sql_body += " AUTO_INCREMENT";
+            }
+        }
+        if(isPrimaryKey)/*是否为主键*/ {
+            this.sql_body +=" , PRIMARY KEY (`"+columnName+"`) ";
+        }
+        return this;
+    }
+
+    @Override
+    public MysqlDbTableAssistant AddColumn(String columnName,M columnType,Integer length, boolean autoIncrement,String defaultValue,boolean isNotNull,boolean isPrimaryKey) {
+        this.sql_body = ADD_COLUMN;
+        if(MysqlFiledUtil.isCharTextFiled(columnType))/*判断字段是否允许设置长度*/ {
+            this.sql_body += " `"+columnName+"` " + columnType+"("+length+")";
+        } else {
+            this.sql_body += " `"+columnName+"` " + columnType;
+        }
+        if(isNotNull)/*判断字段是否不为空*/ {
+            this.sql_body+=" NOT NULL";
+        }
+        if(autoIncrement) { /* 判断字段类型是否支持自动增长 */
+            if(MysqlFiledUtil.isAutoIncrementFiled(columnType)) {
+                if (!isNotNull) {
+                    this.sql_body += " NOT null";
+                }
+                this.sql_body += " AUTO_INCREMENT";
+            }
+        }else {
+            if(!isNotNull)/*判断字段是否允许为空*/ {
+                this.sql_body+=" NULL ";
+            }
+            if(!MysqlFiledUtil.isNotDefaultValue(columnType)) {
+                /*判断字段类型是否为数值型*/
+                if(MysqlFiledUtil.isAutoIncrementFiled(columnType)&& !StringUtils.isNumeric(defaultValue))
+                    /*todo 有待做日期类型验证*/ {
+                    throw new SystemException("数值型字段不能设置默认值为字符");
+                }
+                this.sql_body += " DEFAULT " + (StrUtil.isBlank(defaultValue) ? null : "'" + defaultValue + "'");
+            }
+        }
+        if(isPrimaryKey)/*是否为主键*/ {
+            this.sql_body +="  , ADD PRIMARY KEY (`"+columnName+"`) ";
+        }
+        return this;
+    }
+
+    @Override
+    public MysqlDbTableAssistant ChangeColumn(String columnName,String newColumnName,M columnType,Integer length,boolean autoIncrement,String defaultValue,boolean isNotNull) {
+        this.sql_body = MysqlDbTableAssistant.CHANGE_COLUMN;
+        if(MysqlFiledUtil.isCharTextFiled(columnType))/*判断字段是否允许设置长度*/ {
+            this.sql_body += " `"+columnName+"` " +" `"+newColumnName+"` "+ columnType+"("+length+")";
+        } else {
+            this.sql_body += " `"+columnName+"` " +" `"+newColumnName+"` " + columnType;
+        }
+        if(isNotNull) {
+            this.sql_body+=" NOT null";
+        }
+        if(autoIncrement) { /* 判断字段类型是否支持自动增长 */
+            if(MysqlFiledUtil.isAutoIncrementFiled(columnType)) {
+                if (!isNotNull) {
+                    this.sql_body += " NOT null";
+                }
+                this.sql_body += " AUTO_INCREMENT ;";
+            }
+        }else {
+            if(!isNotNull)/*判断字段是否允许为空*/ {
+                this.sql_body+=" NULL ";
+            }
+            if(MysqlFiledUtil.isNotDefaultValue(columnType)) {
+                this.sql_body += " DEFAULT " +  (StrUtil.isBlank(defaultValue)?null:"'"+defaultValue+"'")+";";
+            }
+        }
+
+        return this;
+    }
+
+    @Override
+    public MysqlDbTableAssistant DropColumn(String columnName,boolean isPrimaryKey) {
+        this.sql_body=DROP_COLUMN +"`"+columnName+"`";
+        return this;
+    }
+
+
+    @Override
+    public MysqlDbTableAssistant AddIndex(String cloumnName, Integer length) {
+        return null;
+    }
+
+    @Override
+    public MysqlDbTableAssistant Engine(String engineName) {
+        this.sql_foot+=" ENGINE="+engineName+" ";
+        return this;
+    }
+
+    @Override
+    public MysqlDbTableAssistant CharSet(String charset) {
+        this.sql_foot+=" DEFAULT CHARSET="+charset+" ";
+        return this;
+    }
+
+
+}

+ 132 - 0
src/main/java/com/sooka/common/db/kit/DbTableKit.java

@@ -0,0 +1,132 @@
+package com.sooka.common.db.kit;
+
+import com.sooka.common.db.impl.M;
+import com.sooka.common.db.vo.FiledTypeVo;
+import com.sooka.common.exception.SystemException;
+import com.sooka.common.utils.StrUtil;
+
+/**
+ * Description:cms 工具类
+ *
+ *
+ * @create 2017-05-12
+ **/
+public class DbTableKit {
+
+     public static final String[] MODEL_FILED_CLASS ={"input#单文本","file#文件","image#单图上传","editor#编辑器","textarea#多文本框","radio#单选","select#列表","checkbox#多选","dateInput#日期输入"};
+
+     public static final String[] PREPARED_MODEL_FILED_NAME={"title","site_id","siteId","user_id","userId","category_id","categoryId","model_id","modelId","keywords","description","top","recommend","thumb","status","inputdate","updatedate","url","author","view_num","viewNum"};
+
+
+     public static FiledTypeVo getFiledTypeVo(String filedClass, String filedType,Integer length,String defaultValue){
+          FiledTypeVo f = new FiledTypeVo();
+
+          if (filedClass.equals("input")){
+               if(!StrUtil.isBlank(filedType)&&length!=null){
+                    f.setM(M.valueOf(filedType));
+                    f.setLength(length);
+               }else {
+                    f.setM(M.VARCHAR_TYPE);
+                    f.setLength(255);
+               }
+               f.setDefaultValue(defaultValue);
+          }
+
+          if (filedClass.equals("file")){
+               if(!StrUtil.isBlank(filedType)&&length!=null){
+                    f.setM(M.valueOf(filedType));
+                    f.setLength(length);
+               }else {
+                    f.setM(M.VARCHAR_TYPE);
+                    f.setLength(128);
+               }
+               f.setDefaultValue(null);
+          }
+
+          if (filedClass.equals("image")){
+               if(!StrUtil.isBlank(filedType)&&length!=null){
+                    f.setM(M.valueOf(filedType));
+                    f.setLength(length);
+               }else {
+                    f.setM(M.TEXT_TYPE);
+                    f.setLength(null);
+               }
+               f.setDefaultValue(defaultValue);
+          }
+
+          if (filedClass.equals("editor")){
+               if(!StrUtil.isBlank(filedType)&&length!=null){
+                    if(MysqlFiledUtil.isAutoIncrementFiled(M.valueOf(filedType))) {
+                        throw new SystemException("请选择非数字的字段类型类型!");
+                    }
+                    f.setM(M.valueOf(filedType));
+                    f.setLength(length);
+
+               }else {
+                    f.setM(M.MEDIUM_TEXT_TYPE);
+                    f.setLength(null);
+               }
+               f.setDefaultValue(defaultValue);
+          }
+
+          if (filedClass.equals("textarea")){
+               if(!StrUtil.isBlank(filedType)&&length!=null){
+                    if(MysqlFiledUtil.isAutoIncrementFiled(M.valueOf(filedType))) {
+                        throw new SystemException("请选择非数字的字段类型类型!");
+                    }
+                    f.setM(M.valueOf(filedType));
+                    f.setLength(length);
+               }else {
+                    f.setM(M.TEXT_TYPE);
+                    f.setLength(null);
+               }
+               f.setDefaultValue(defaultValue);
+          }
+
+          if (filedClass.equals("radio")){
+               if(!StrUtil.isBlank(filedType)&&length!=null){
+                    f.setM(M.valueOf(filedType));
+                    f.setLength(length);
+               }else {
+                    f.setM(M.VARCHAR_TYPE);
+                    f.setLength(200);
+               }
+               f.setDefaultValue(" ");
+          }
+
+          if (filedClass.equals("checkbox")){
+               if(!StrUtil.isBlank(filedType)&&length!=null){
+                    f.setM(M.valueOf(filedType));
+                    f.setLength(length);
+               }else {
+                    f.setM(M.VARCHAR_TYPE);
+                    f.setLength(200);
+               }
+               f.setDefaultValue(" ");
+          }
+
+          if (filedClass.equals("select")){
+               if(!StrUtil.isBlank(filedType)&&length!=null){
+                    f.setM(M.valueOf(filedType));
+                    f.setLength(length);
+               }else {
+                    f.setM(M.VARCHAR_TYPE);
+                    f.setLength(200);
+               }
+               f.setDefaultValue(null);
+          }
+          if (filedClass.equals("dateInput")){
+               if(!StrUtil.isBlank(filedType)&&length!=null){
+                    f.setM(M.valueOf(filedType));
+                    f.setLength(length);
+               }else {
+                    f.setM(M.CHAR_TYPE);
+                    f.setLength(32);
+               }
+               f.setDefaultValue(" ");
+          }
+
+      return f;
+     }
+
+}

+ 71 - 0
src/main/java/com/sooka/common/db/kit/MysqlFiledUtil.java

@@ -0,0 +1,71 @@
+package com.sooka.common.db.kit;
+
+import com.sooka.common.db.impl.M;
+
+/**
+ * Description:Mysql db table filed utils
+ *
+ *
+ * @create 2017-05-11
+ **/
+public class MysqlFiledUtil {
+
+    public static boolean isAutoIncrementFiled(M FiledType){
+        if(FiledType== M.BIG_INT_TYPE) {
+            return true;
+        }
+         if(FiledType== M.INT_TYPE) {
+             return true;
+         }
+         if(FiledType== M.TNY_INT_TYPE) {
+             return true;
+         }
+         if(FiledType== M.SMALL_INT_TYPE) {
+             return true;
+         }
+         if(FiledType== M.MEDIUM_INT_TYPE) {
+             return true;
+         }
+         return false;
+    }
+
+    public static boolean isCharTextFiled(M FiledType){
+
+        if(FiledType== M.DATE_TYPE) {
+            return false;
+        }
+        if(FiledType== M.TIMESTAMP_TYPE) {
+            return false;
+        }
+        if(FiledType== M.TEXT_TYPE) {
+            return false;
+        }
+        if(FiledType== M.MEDIUM_TEXT_TYPE) {
+            return false;
+        }
+        if(FiledType== M.LONG_TEXT_TYPE) {
+            return false;
+        }
+        return true;
+    }
+
+    public static boolean isNotDefaultValue(M FiledType){
+        if(FiledType== M.TEXT_TYPE) {
+            return true;
+        }
+        if(FiledType== M.MEDIUM_TEXT_TYPE) {
+            return true;
+        }
+        if(FiledType== M.LONG_TEXT_TYPE) {
+            return true;
+        }
+        return false;
+    }
+
+    public static void main(String[] ARGS){
+        System.out.println(isAutoIncrementFiled(M.INT_TYPE));
+
+        System.out.println( isCharTextFiled(M.TEXT_TYPE));
+    }
+
+}

+ 42 - 0
src/main/java/com/sooka/common/db/vo/FiledTypeVo.java

@@ -0,0 +1,42 @@
+package com.sooka.common.db.vo;
+
+import com.sooka.common.db.impl.M;
+
+/**
+ * Description:数据库字段类型VO
+ *
+ *
+ * @create 2017-05-13
+ **/
+public class FiledTypeVo {
+
+    private M m;
+
+    public M getM() {
+        return m;
+    }
+
+    public void setM(M m) {
+        this.m = m;
+    }
+
+    public Integer getLength() {
+        return length;
+    }
+
+    public void setLength(Integer length) {
+        this.length = length;
+    }
+
+    private Integer length;
+
+    private String defaultValue;
+
+    public String getDefaultValue() {
+        return defaultValue;
+    }
+
+    public void setDefaultValue(String defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+}

+ 15 - 0
src/main/java/com/sooka/common/exception/ApiException.java

@@ -0,0 +1,15 @@
+package com.sooka.common.exception;
+
+/**
+ * Description:自定义Exception,主要是为了返回JSON信息
+ *
+ *
+ * @create 2017-04-09
+ **/
+public class ApiException extends RuntimeException{
+
+    public ApiException(String message) {
+        super(message);
+    }
+
+}

+ 13 - 0
src/main/java/com/sooka/common/exception/CmsException.java

@@ -0,0 +1,13 @@
+package com.sooka.common.exception;
+
+/**
+ * Description:内容管理exception
+ *
+ *
+ * @create 2017-06-01
+ **/
+public class CmsException extends RuntimeException{
+    public CmsException(String message) {
+        super(message);
+    }
+}

+ 128 - 0
src/main/java/com/sooka/common/exception/DefaultExceptionHandler.java

@@ -0,0 +1,128 @@
+package com.sooka.common.exception;
+
+import com.sooka.common.utils.ControllerUtil;
+import com.sooka.common.utils.JsonUtil;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.authz.UnauthenticatedException;
+import org.apache.shiro.authz.UnauthorizedException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Date;
+
+/**
+ * Description:自定义统一错误控制器
+ *
+ *
+ * @create 2017-04-09
+ **/
+@ControllerAdvice
+public class DefaultExceptionHandler {
+
+
+    /**
+     * 接口异常
+     * @param e
+     * @return
+     */
+    @ExceptionHandler({ApiException.class})
+    @ResponseBody
+    public String ApiException(Exception e){
+        return JsonUtil.toErrorResultJSON(e.getMessage());
+    }
+
+
+    /**
+     * cms异常
+     * @param e
+     * @return
+     */
+    @ExceptionHandler({CmsException.class,Exception.class})
+    public ModelAndView CmsException(Exception e,HttpServletRequest request,HttpServletResponse response){
+        if (ControllerUtil.isAjaxRequest(request)) {
+            ControllerUtil.renderErrorJson(e.getMessage(),response);
+            return null;
+        } else {
+            return this.renderErrorView(404,"Not Found",e.getMessage());
+        }
+    }
+
+
+    /**
+     * 系统异常
+     * @param e
+     * @return
+     */
+    @ExceptionHandler({SystemException.class})
+    public ModelAndView  SystemException(Exception e,HttpServletRequest request,HttpServletResponse response){
+
+            if (ControllerUtil.isAjaxRequest(request)) {
+                ControllerUtil.renderErrorJson(e.getMessage(),response);
+                return null;
+            } else {
+                return this.renderErrorView(500,"HTTP-Internal Server Error",e.getMessage());
+            }
+    }
+
+
+    /**
+     * 统一错误系统
+     * @param e
+     * @return
+     */
+    @ExceptionHandler({NullPointerException.class})
+    public ModelAndView DefaultException(Exception e,HttpServletRequest request,HttpServletResponse response) {
+        if (ControllerUtil.isAjaxRequest(request)) {
+             /* 输出JSON */
+            ControllerUtil.renderErrorJson(e.getMessage(),response);
+            return null;
+        } else {
+            return this.renderErrorView(500,"HTTP-Internal Server Error",e.getMessage());
+        }
+    }
+
+    /**
+     *访问异常
+     */
+    @ExceptionHandler({ UnauthenticatedException.class, AuthenticationException.class })
+    public ModelAndView authenticationException(Exception e,HttpServletRequest request, HttpServletResponse response) {
+        if (ControllerUtil.isAjaxRequest(request)) {
+             /* 输出JSON */
+            ControllerUtil.renderTimeoutJson("对不起,请登录后再访问!",response);
+            return null;
+        } else {
+            return this.renderErrorView(401,"Authentication Failed",e.getMessage());
+        }
+    }
+
+    /**
+     * 权限异常
+     */
+    @ExceptionHandler({ UnauthorizedException.class, AuthorizationException.class })
+    public ModelAndView authorizationException(Exception e,HttpServletRequest request, HttpServletResponse response) throws IOException {
+        if (ControllerUtil.isAjaxRequest(request)) {
+            /* 输出JSON */
+           ControllerUtil.renderErrorJson("对不起,您没有此权限",response);
+           return null;
+        } else {
+            return this.renderErrorView(401,"Unauthorized",e.getMessage());
+        }
+
+    }
+
+    private ModelAndView renderErrorView(Integer errorCode,String error,String message){
+        ModelAndView view =new ModelAndView("error");
+        view.addObject("status",errorCode);
+        view.addObject("error",error);
+        view.addObject("message",message);
+        view.addObject("timestamp",new Date());
+        return view;
+    }
+
+}

+ 14 - 0
src/main/java/com/sooka/common/exception/SystemException.java

@@ -0,0 +1,14 @@
+package com.sooka.common.exception;
+
+/**
+ * Description:系统异常
+ *
+ *
+ * @create 2017-05-13
+ **/
+public class SystemException extends RuntimeException{
+
+    public SystemException(String message) {
+        super(message);
+    }
+}

+ 120 - 0
src/main/java/com/sooka/common/jwt/Jwt.java

@@ -0,0 +1,120 @@
+package com.sooka.common.jwt;
+
+import com.alibaba.fastjson.JSON;
+import com.nimbusds.jose.*;
+import com.nimbusds.jose.crypto.MACSigner;
+import com.nimbusds.jose.crypto.MACVerifier;
+import com.sooka.common.jwt.vo.PayloadVo;
+import com.sooka.common.jwt.vo.ResultVo;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * Description:jwt
+ *
+ *
+ * @create 2017-04-05
+ **/
+public class Jwt {
+	
+    
+    /**
+     * 秘钥
+     */
+    private static final byte[] SECRET="z122NNNlasewqWWefffdmhjSDccsdsa9//*-".getBytes();
+    
+    /**
+     * 初始化head部分的数据为
+     * {
+     * 		"alg":"HS256",
+     * 		"type":"JWT"
+     * }
+     */
+    private static final JWSHeader header=new JWSHeader(JWSAlgorithm.HS256, JOSEObjectType.JWT, null, null, null, null, null, null, null, null, null, null, null);
+
+	/**
+	 *生成Token
+	 * @param payload
+	 * @return
+	 */
+	public static String createToken(PayloadVo payload) {
+		String tokenString=null;
+		// 创建一个 JWS object
+		JWSObject jwsObject = new JWSObject(header, new Payload(JSON.toJSONString(payload)));
+		try {
+			// 将jwsObject 进行HMAC签名
+			jwsObject.sign(new MACSigner(SECRET));
+			tokenString=jwsObject.serialize();
+		} catch (JOSEException e) {
+			System.err.println("签名失败:" + e.getMessage());
+			e.printStackTrace();
+		}
+		return tokenString;
+	}
+
+
+	/**
+	 *生成Token
+	 * @param  map
+	 * @return
+	 */
+	public static String createToken(Map map) {
+		String tokenString=null;
+		// 创建一个 JWS object
+		JWSObject jwsObject = new JWSObject(header, new Payload(JSON.toJSONString(map)));
+		try {
+			// 将jwsObject 进行HMAC签名
+			jwsObject.sign(new MACSigner(SECRET));
+			tokenString=jwsObject.serialize();
+		} catch (JOSEException e) {
+			System.err.println("签名失败:" + e.getMessage());
+			e.printStackTrace();
+		}
+		return tokenString;
+	}
+
+
+	/**
+     * 校验token是否合法,返回Map集合,集合中主要包含    state状态码   data鉴权成功后从token中提取的数据
+     * 该方法在过滤器中调用,每次请求API时都校验
+     * @param token
+     * @return  Map<String, Object>
+     */
+	public static ResultVo validToken(String token) {
+		ResultVo result = new ResultVo();
+		try {
+
+			JWSObject jwsObject = JWSObject.parse(token);
+			Payload payload = jwsObject.getPayload();
+			PayloadVo payloadVo = JSON.parseObject(String.valueOf(payload.toJSONObject()),PayloadVo.class);
+
+			JWSVerifier verifier = new MACVerifier(SECRET);
+
+			if (jwsObject.verify(verifier)) {
+
+				// token校验成功(此时没有校验是否过期)
+				result.setStatus(TokenState.VALID.toString());
+				// 若payload包含ext字段,则校验是否过期
+				if (payloadVo.getExt()!=0) {
+					long curTime = System.currentTimeMillis();
+					// 过期了
+					if (curTime > payloadVo.getExt()) {
+						result.setStatus(TokenState.EXPIRED.toString());
+					}
+				}
+				result.setPayloadVo(payloadVo);
+
+			} else {
+				// 校验失败
+				result.setStatus(TokenState.INVALID.toString());
+			}
+
+		} catch (Exception e) {
+			e.printStackTrace();
+			result.setStatus(TokenState.INVALID.toString());
+		}
+		return result;
+	}	
+    
+}

+ 58 - 0
src/main/java/com/sooka/common/jwt/TokenState.java

@@ -0,0 +1,58 @@
+package com.sooka.common.jwt;
+
+
+/**
+ * Description:token
+ *
+ *
+ * @create 2017-04-05
+ **/
+ public enum TokenState {
+    /**
+	  * 过期
+	  */
+	EXPIRED("EXPIRED"),
+	/**
+	 * 无效(token不合法)
+	 */
+	INVALID("INVALID"), 
+	/**
+	 * 有效的
+	 */
+	VALID("VALID");  
+	
+    private String  state;  
+      
+    TokenState(String state) {
+
+    	this.state = state;
+    }
+    
+    /**
+     * 根据状态字符串获取token状态枚举对象
+     * @param tokenState
+     * @return
+     */
+    public static TokenState getTokenState(String tokenState){
+    	TokenState[] states=TokenState.values();
+    	TokenState ts=null;
+    	for (TokenState state : states) {
+			if(state.toString().equals(tokenState)){
+				ts=state;
+				break;
+			}
+		}
+    	return ts;
+    }
+    @Override
+    public String toString() {
+    	return this.state;
+    }
+	public String getState() {
+		return state;
+	}
+	public void setState(String state) {
+		this.state = state;
+	}
+    
+} 

+ 49 - 0
src/main/java/com/sooka/common/jwt/vo/PayloadVo.java

@@ -0,0 +1,49 @@
+package com.sooka.common.jwt.vo;
+
+/**
+ * Description:payload vo
+ *
+ *
+ * @create 2017-04-05
+ **/
+public class PayloadVo {
+
+    private String appId;
+    //签发时间
+    private long iat;
+    //过期时间
+    private long ext;
+
+    public String getAppId() {
+        return appId;
+    }
+
+    public void setAppId(String appId) {
+        this.appId = appId;
+    }
+
+    public long getIat() {
+        return iat;
+    }
+
+    public void setIat(long iat) {
+        this.iat = iat;
+    }
+
+    public long getExt() {
+        return ext;
+    }
+
+    public void setExt(long  ext) {
+        this.ext = ext;
+    }
+
+    @Override
+    public String toString() {
+        return "PayloadVo{" +
+                "appId='" + appId + '\'' +
+                ", iat=" + iat +
+                ", ext=" + ext +
+                '}';
+    }
+}

+ 28 - 0
src/main/java/com/sooka/common/jwt/vo/ResultVo.java

@@ -0,0 +1,28 @@
+package com.sooka.common.jwt.vo;
+
+/**
+ * Description:token验证结果集
+*
+ **/
+public class ResultVo {
+
+    private String status;
+    private PayloadVo payloadVo;
+
+    public PayloadVo getPayloadVo() {
+        return payloadVo;
+    }
+
+    public void setPayloadVo(PayloadVo payloadVo) {
+        this.payloadVo = payloadVo;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+}

+ 127 - 0
src/main/java/com/sooka/common/keyword/SensitiveWordInit.java

@@ -0,0 +1,127 @@
+package com.sooka.common.keyword;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+public class SensitiveWordInit {
+	private String ENCODING = "UTF-8";
+	@SuppressWarnings("rawtypes")
+	public HashMap sensitiveWordMap;
+
+	public SensitiveWordInit(){
+		super();
+	}
+
+	@SuppressWarnings("rawtypes")
+	public Map initKeyWord(){
+		try {
+
+			Set<String> keyWordSet = readSensitiveWordFile();
+
+			addSensitiveWordToHashMap(keyWordSet);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return sensitiveWordMap;
+	}
+
+	/**
+	 * 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型:<br>
+	 * 中 = {
+	 *      isEnd = 0
+	 *      国 = {<br>
+	 *      	 isEnd = 1
+	 *           人 = {isEnd = 0
+	 *                民 = {isEnd = 1}
+	 *                }
+	 *           男  = {
+	 *           	   isEnd = 0
+	 *           		人 = {
+	 *           			 isEnd = 1
+	 *           			}
+	 *           	}
+	 *           }
+	 *      }
+	 *  五 = {
+	 *      isEnd = 0
+	 *      星 = {
+	 *      	isEnd = 0
+	 *      	红 = {
+	 *              isEnd = 0
+	 *              旗 = {
+	 *                   isEnd = 1
+	 *                  }
+	 *              }
+	 *      	}
+	 *      }
+	 */
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	private void addSensitiveWordToHashMap(Set<String> keyWordSet) {
+		sensitiveWordMap = new HashMap(keyWordSet.size());     //初始化敏感词容器,减少扩容操作
+		String key = null;
+		Map nowMap = null;
+		Map<String, String> newWorMap = null;
+		//迭代keyWordSet
+		Iterator<String> iterator = keyWordSet.iterator();
+		while(iterator.hasNext()){
+			key = iterator.next();    //关键字
+			nowMap = sensitiveWordMap;
+			for(int i = 0 ; i < key.length() ; i++){
+				char keyChar = key.charAt(i);       //转换成char型
+				Object wordMap = nowMap.get(keyChar);       //获取
+
+				if(wordMap != null){        //如果存在该key,直接赋值
+					nowMap = (Map) wordMap;
+				}
+				else{     //不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个
+					newWorMap = new HashMap<String,String>();
+					newWorMap.put("isEnd", "0");     //不是最后一个
+					nowMap.put(keyChar, newWorMap);
+					nowMap = newWorMap;
+				}
+
+				if(i == key.length() - 1){
+					nowMap.put("isEnd", "1");    //最后一个
+				}
+			}
+		}
+	}
+
+
+	@SuppressWarnings("resource")
+	private Set<String> readSensitiveWordFile() throws Exception{
+		Set<String> set = null;
+
+		File file = new File("D:\\SensitiveWord.txt");
+		InputStreamReader read = new InputStreamReader(new FileInputStream(file),ENCODING);
+		try {
+			if(file.isFile() && file.exists()){
+				set = new HashSet<String>();
+				BufferedReader bufferedReader = new BufferedReader(read);
+				String txt = null;
+				while((txt = bufferedReader.readLine()) != null){
+					set.add(txt);
+				}
+			}
+			else{
+				throw new Exception("敏感词库文件不存在");
+			}
+		} catch (Exception e) {
+			throw e;
+		}finally{
+			try{
+				read.close();
+			}catch (Exception e){
+				e.printStackTrace();
+			}
+		}
+		return set;
+	}
+}

+ 146 - 0
src/main/java/com/sooka/common/keyword/SensitivewordFilter.java

@@ -0,0 +1,146 @@
+package com.sooka.common.keyword;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+
+public class SensitivewordFilter {
+	@SuppressWarnings("rawtypes")
+	private Map sensitiveWordMap = null;
+	public static int minMatchTYpe = 1;      //最小匹配规则
+	public static int maxMatchType = 2;      //最大匹配规则
+
+
+	public SensitivewordFilter(){
+		sensitiveWordMap = new SensitiveWordInit().initKeyWord();
+	}
+
+	/**
+	 * 判断文字是否包含敏感字符
+	 * @param txt  文字
+	 * @param matchType  匹配规则&nbsp;1:最小匹配规则,2:最大匹配规则
+	 * @return 若包含返回true,否则返回false
+	 * @version 1.0
+	 */
+	public boolean isContaintSensitiveWord(String txt,int matchType){
+		boolean flag = false;
+		for(int i = 0 ; i < txt.length() ; i++){
+			int matchFlag = this.CheckSensitiveWord(txt, i, matchType); //判断是否包含敏感字符
+			if(matchFlag > 0){    //大于0存在,返回true
+				flag = true;
+			}
+		}
+		return flag;
+	}
+
+	/**
+	 * 获取文字中的敏感词
+	 * @param txt 文字
+	 * @param matchType 匹配规则&nbsp;1:最小匹配规则,2:最大匹配规则
+	 * @return
+	 * @version 1.0
+	 */
+	public Set<String> getSensitiveWord(String txt , int matchType){
+		Set<String> sensitiveWordList = new HashSet<String>();
+
+		for(int i = 0 ; i < txt.length() ; i++){
+			int length = CheckSensitiveWord(txt, i, matchType);    //判断是否包含敏感字符
+			if(length > 0){    //存在,加入list中
+				sensitiveWordList.add(txt.substring(i, i+length));
+				i = i + length - 1;    //减1的原因,是因为for会自增
+			}
+		}
+
+		return sensitiveWordList;
+	}
+
+	/**
+	 * 替换敏感字字符
+	 * @param txt
+	 * @param matchType
+	 * @param replaceChar 替换字符,默认*
+	 * @version 1.0
+	 */
+	public String replaceSensitiveWord(String txt,int matchType,String replaceChar){
+		String resultTxt = txt;
+		Set<String> set = getSensitiveWord(txt, matchType);     //获取所有的敏感词
+		Iterator<String> iterator = set.iterator();
+		String word = null;
+		String replaceString = null;
+		while (iterator.hasNext()) {
+			word = iterator.next();
+			replaceString = getReplaceChars(replaceChar, word.length());
+			resultTxt = resultTxt.replaceAll(word, replaceString);
+		}
+
+		return resultTxt;
+	}
+
+	/**
+	 * 获取替换字符串
+	 * @param replaceChar
+	 * @param length
+	 * @return
+	 * @version 1.0
+	 */
+	private String getReplaceChars(String replaceChar,int length){
+		String resultReplace = replaceChar;
+		for(int i = 1 ; i < length ; i++){
+			resultReplace += replaceChar;
+		}
+
+		return resultReplace;
+	}
+
+	/**
+	 * 检查文字中是否包含敏感字符,检查规则如下:<br>
+	 * @param txt
+	 * @param beginIndex
+	 * @param matchType
+	 * @return,如果存在,则返回敏感词字符的长度,不存在返回0
+	 * @version 1.0
+	 */
+	@SuppressWarnings({ "rawtypes"})
+	public int CheckSensitiveWord(String txt,int beginIndex,int matchType){
+		boolean  flag = false;    //敏感词结束标识位:用于敏感词只有1位的情况
+		int matchFlag = 0;     //匹配标识数默认为0
+		char word = 0;
+		Map nowMap = sensitiveWordMap;
+		for(int i = beginIndex; i < txt.length() ; i++){
+			word = txt.charAt(i);
+			nowMap = (Map) nowMap.get(word);     //获取指定key
+			if(nowMap != null){     //存在,则判断是否为最后一个
+				matchFlag++;     //找到相应key,匹配标识+1
+				if("1".equals(nowMap.get("isEnd"))){       //如果为最后一个匹配规则,结束循环,返回匹配标识数
+					flag = true;       //结束标志位为true
+					if(SensitivewordFilter.minMatchTYpe == matchType){    //最小规则,直接返回,最大规则还需继续查找
+						break;
+					}
+				}
+			}
+			else{     //不存在,直接返回
+				break;
+			}
+		}
+		if(matchFlag < 2 || !flag){        //长度必须大于等于1,为词
+			matchFlag = 0;
+		}
+		return matchFlag;
+	}
+
+	public static void main(String[] args) {
+		SensitivewordFilter filter = new SensitivewordFilter();
+		System.out.println("敏感词的数量:" + filter.sensitiveWordMap.size());
+		String string = "太多的伤感情怀也许只局限于饲养基地 荧幕中的情节,主人公尝试着去用某种方式渐渐的很潇洒地释自杀指南怀那些自己经历的伤感。"
+				+ "然后法轮功 我们的扮演的角色就是跟随着主人公的喜红客联盟 怒哀乐而过于牵强的把自己的情感也附加于银幕情节中,然后感动就流泪,"
+				+ "难过就躺在某一个人的怀里尽情的阐述心扉或者手机卡复制器一个人一杯红酒一部电影在夜三级片 深人静的晚上,关上电话静静的发呆着。";
+		System.out.println("待检测语句字数:" + string.length());
+		long beginTime = System.currentTimeMillis();
+		Set<String> set = filter.getSensitiveWord(string, 1);
+		long endTime = System.currentTimeMillis();
+		System.out.println("语句中包含敏感词的个数为:" + set.size() + "。包含:" + set);
+		System.out.println("总共消耗时间为:" + (endTime - beginTime));
+	}
+}

+ 62 - 0
src/main/java/com/sooka/common/template/TemplateFile.java

@@ -0,0 +1,62 @@
+package com.sooka.common.template;
+
+import java.util.List;
+
+/**
+ * Description:
+ *
+ *
+ * @create 2017-08-11
+ **/
+public class TemplateFile {
+
+    private String fileName;
+
+    private String filePath;
+
+    private Boolean isDirectory;
+
+    private String content;
+
+    private List<TemplateFile> childList;
+
+    public List<TemplateFile> getChildList() {
+        return childList;
+    }
+
+    public void setChildList(List<TemplateFile> childList) {
+        this.childList = childList;
+    }
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    public void setFileName(String fileName) {
+        this.fileName = fileName;
+    }
+
+    public String getFilePath() {
+        return filePath;
+    }
+
+    public void setFilePath(String filePath) {
+        this.filePath = filePath;
+    }
+
+    public Boolean getIsDirectory() {
+        return isDirectory;
+    }
+
+    public void setIsDirectory(Boolean _isDirectory) {
+        isDirectory = _isDirectory;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+}

+ 25 - 0
src/main/java/com/sooka/common/template/TemplateFileService.java

@@ -0,0 +1,25 @@
+package com.sooka.common.template;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Description:
+ *
+ *
+ * @create 2017-08-11
+ **/
+public interface TemplateFileService {
+
+    List<TemplateFile> findAll();
+
+    TemplateFile findByPath(String path);
+
+    void writeTemplateFileContent(TemplateFile templateFile);
+
+    String readTemplateFileContent(File file);
+
+    String delete();
+
+
+}

+ 133 - 0
src/main/java/com/sooka/common/template/TemplateFileServiceImpl.java

@@ -0,0 +1,133 @@
+package com.sooka.common.template;
+
+import com.google.common.collect.Lists;
+import com.sooka.common.utils.PathUtil;
+import com.sooka.common.exception.SystemException;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.io.*;
+import java.util.List;
+
+/**
+ * Description:
+ *
+ *
+ * @create 2017-08-11
+ **/
+@Service
+public class TemplateFileServiceImpl implements TemplateFileService{
+
+    private final String TEMPLATE_PATH = PathUtil.getRootClassPath()+ File.separator+"templates"+File.separator+"www";
+
+    @Override
+    public List<TemplateFile> findAll() {
+        List<TemplateFile> result = Lists.newArrayList();
+        File mainFile = new File(TEMPLATE_PATH);
+        if(!mainFile.exists()||mainFile.listFiles().length<1) {
+            throw new SystemException("请检查模板目录是否存在!");
+        }
+        /*只遍历三级级目录*/
+        for(File file :mainFile.listFiles()){
+            TemplateFile templateFile = new TemplateFile();
+            templateFile.setFileName(file.getName());
+            templateFile.setFilePath(file.getAbsolutePath());
+            templateFile.setIsDirectory(file.isDirectory());
+            if(file.isDirectory()){
+                File subFile = new File(file.getAbsolutePath());
+                List<TemplateFile> childList = Lists.newArrayList();
+                for(File subfile :subFile.listFiles()) {
+                    TemplateFile subTemplateFile = new TemplateFile();
+                    subTemplateFile.setFileName(subfile.getName());
+                    subTemplateFile.setFilePath(subfile.getAbsolutePath());
+                    subTemplateFile.setIsDirectory(subfile.isDirectory());
+                    if(subfile.isDirectory()){
+                        List<TemplateFile> subChildList = Lists.newArrayList();
+                        File subChildFile = new File(subfile.getAbsolutePath());
+                        if(!subChildFile.exists()||mainFile.listFiles().length<1) {
+                            continue;
+                        }
+                        for(File subChildfile :subChildFile.listFiles()) {
+                            TemplateFile subChildTemplateFile = new TemplateFile();
+                            subChildTemplateFile.setFileName(subChildfile.getName());
+                            subChildTemplateFile.setFilePath(subChildfile.getAbsolutePath());
+                            subChildTemplateFile.setIsDirectory(subChildfile.isDirectory());
+                            subChildList.add(subChildTemplateFile);
+                        }
+                        subTemplateFile.setChildList(subChildList);
+                    }
+                    childList.add(subTemplateFile);
+                }
+                templateFile.setChildList(childList);
+            }
+            result.add(templateFile);
+        }
+        return result;
+    }
+
+    @Override
+    public TemplateFile findByPath(String path) {
+        File file = new File(path);
+        if(!file.exists()) {
+            throw new SystemException("模板不存在请检查!");
+        }
+        TemplateFile templateFile = new TemplateFile();
+        templateFile.setFileName(file.getName());
+        templateFile.setFilePath(file.getAbsolutePath());
+        templateFile.setContent(this.readTemplateFileContent(file));
+        return templateFile;
+    }
+
+
+    public static void main(String[]args) {
+        List<TemplateFile> list = new TemplateFileServiceImpl().findAll();
+        for (TemplateFile templateFile : list){
+           System.out.println(templateFile.getFileName());
+           if(templateFile.getIsDirectory()){
+               for (TemplateFile t : templateFile.getChildList()){
+                   System.out.println(templateFile.getFileName()+"---->"+t.getFileName()+"["+t.getFilePath()+"]");
+                   if(t.getIsDirectory()){
+                       for (TemplateFile st : t.getChildList()){ System.out.println(t.getFileName()+"---------->"+ st.getFileName()+"["+ st.getFilePath()+"]");}
+                   }
+               }
+           }
+        }
+    }
+
+    @Override
+    public  String readTemplateFileContent(File file) {
+        try {
+            InputStream inputStream = new FileInputStream(file);
+            byte[] buffer = new byte[1024];
+            int len;
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            while((len = inputStream.read(buffer)) != -1) {
+              bos.write(buffer, 0, len);
+            }
+            bos.close();
+            return new String(bos.toByteArray(), "utf-8");
+        }catch (Exception e){
+            throw  new SystemException(e.getMessage());
+        }
+    }
+
+    @Override
+    @Async
+    public  void writeTemplateFileContent(TemplateFile templateFile){
+        try {
+            OutputStream outputStream = new FileOutputStream(new File(templateFile.getFilePath()));
+            OutputStreamWriter os = new OutputStreamWriter(outputStream, "utf-8");
+            os.write(templateFile.getContent());
+            os.flush();
+            os.close();
+        }catch (Exception e){
+            throw  new SystemException(e.getMessage());
+        }
+    }
+
+
+    @Override
+    public String delete() {
+        return null;
+    }
+}

File diff suppressed because it is too large
+ 257 - 0
src/main/java/com/sooka/common/upload/UploadComponent.java


+ 91 - 0
src/main/java/com/sooka/common/upload/UploadController.java

@@ -0,0 +1,91 @@
+package com.sooka.common.upload;
+
+
+import com.sooka.common.upload.bean.UploadBean;
+import com.sooka.common.utils.CmsUtil;
+import com.sooka.common.utils.JsonUtil;
+import com.sooka.module.web.system.service.AttachmentService;
+import com.sooka.mybatis.model.TSysAttachment;
+import com.sooka.common.exception.CmsException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.FileCopyUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.FileInputStream;
+import java.net.URLEncoder;
+
+
+@Controller
+public class UploadController {
+
+    @Autowired
+    private UploadComponent uploadComponent;
+
+    @Autowired
+    private AttachmentService attachmentService;
+
+    @RequestMapping("/uploads")
+    @ResponseBody
+    public String upload(@RequestParam("file") MultipartFile multipartFile,
+                         HttpServletRequest request){
+        UploadBean result = uploadComponent.uploadFile(multipartFile,request);
+
+        return JsonUtil.toUploadSUCCESS("上传成功!",result.getFileUrl());
+    }
+
+
+    @RequestMapping("/uploads/wangEditorUpload")
+    @ResponseBody
+    public String WangEditorUpload(@RequestParam("file") MultipartFile multipartFile,
+                         HttpServletRequest request) {
+        UploadBean result = uploadComponent.uploadFile(multipartFile,request);
+        return result.getFileUrl();
+
+    }
+
+    @RequestMapping("/uploads/CKEditorUpload")
+    @ResponseBody
+    public String CKEditorUpload(@RequestParam("upload") MultipartFile multipartFile,
+                                 HttpServletRequest request) {
+        StringBuffer sb=new StringBuffer();
+        UploadBean result = uploadComponent.uploadFile(multipartFile,request);
+        sb.append("<script type=\"text/javascript\">");
+        sb.append("window.parent.CKEDITOR.tools.callFunction("+ request.getParameter("CKEditorFuncNum") + ",'" +result.getFileUrl()+"','')");
+        sb.append("</script>");
+        return sb.toString();
+
+    }
+
+    @RequestMapping(value = "/res/{key}.{resType}")
+    public void showAttr(@PathVariable(value = "key",required = false) String key,
+                         @PathVariable(value = "resType",required = false) String resType,
+                         HttpServletRequest request,HttpServletResponse response) {
+        if(CmsUtil.isNullOrEmpty(key)) {
+            return;
+        }
+        TSysAttachment attachment = attachmentService.findByKey(key);
+        if(CmsUtil.isNullOrEmpty(attachment)||!attachment.getFileName().contains(resType)) {
+            throw new CmsException("文件不存在!");
+        }
+        try {
+            response.reset();
+            /* 判断浏览器类型,设置文件下载名 */
+            String userAgent = request.getHeader("user-agent").toLowerCase();
+            if (userAgent.contains("msie") || userAgent.contains("like gecko")||userAgent.contains("trident")||userAgent.contains("edge")) {
+                attachment.setOriginalFilename(URLEncoder.encode(attachment.getOriginalFilename(), "UTF-8"));
+            } else {
+                attachment.setOriginalFilename(new String(attachment.getOriginalFilename().getBytes("utf-8"), "ISO8859-1"));
+            }
+            response.setHeader("Content-disposition", "attachment;filename="+attachment.getOriginalFilename());
+            response.setContentType(attachment.getFileExtname());
+            FileCopyUtils.copy(new FileInputStream(uploadComponent.getUploadPath()+attachment.getFilePath()), response.getOutputStream());
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+}

+ 19 - 0
src/main/java/com/sooka/common/upload/bean/UploadBean.java

@@ -0,0 +1,19 @@
+package com.sooka.common.upload.bean;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class UploadBean {
+
+    @ApiModelProperty("附件地址")
+     private String fileUrl;
+
+
+    public String getFileUrl() {
+        return fileUrl;
+    }
+
+    public void setFileUrl(String fileUrl) {
+        this.fileUrl = fileUrl;
+    }
+
+}

+ 66 - 0
src/main/java/com/sooka/common/utils/CheckSumUtil.java

@@ -0,0 +1,66 @@
+package com.sooka.common.utils;
+
+import java.security.MessageDigest;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * CheckSum 工具类(可以用于API接口signature生成)
+ */
+public class CheckSumUtil {
+
+    private CheckSumUtil() {
+        throw new Error("工具类不能实例化!");
+    }
+
+    /*计算并获取CheckSum*/
+    public static String getCheckSum(String appSecrt, String nonce, String timestamp) {
+        return encode("sha1", appSecrt + nonce + timestamp);
+    }
+
+    /*获取当前日期*/
+    public static String getTimestamp(){
+        SimpleDateFormat sdf = new  SimpleDateFormat("yyyyMMddHHmmss");
+        return  sdf.format(new Date());
+    }
+
+    public static void  main(String [] args ){
+
+//        String s = getTimestamp();
+//        System.out.println(getCheckSum("jdeFDS89HFassdsfFDNDS73FDJK", "11", s));
+        System.out.println(Long.parseLong("20170608164200")-Long.parseLong("20170608164000"));
+
+    }
+
+    /* 计算并获取md5值*/
+    public static String getMD5(String str) {
+        return encode("md5", str);
+    }
+
+    /*加密*/
+    private static String encode(String algorithm, String value) {
+        if (value == null) {
+            return null;
+        }
+        try {
+            MessageDigest messageDigest
+                    = MessageDigest.getInstance(algorithm);
+            messageDigest.update(value.getBytes());
+            return getFormattedText(messageDigest.digest());
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+    private static String getFormattedText(byte[] bytes) {
+        int len = bytes.length;
+        StringBuilder buf = new StringBuilder(len * 2);
+        for (int j = 0; j < len; j++) {
+            buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
+            buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
+        }
+        return buf.toString();
+    }
+    private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5',
+            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+ }

+ 50 - 0
src/main/java/com/sooka/common/utils/CmsUtil.java

@@ -0,0 +1,50 @@
+package com.sooka.common.utils;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Description:cms 工具类
+ *
+ *
+ * @create 2017-05-15
+ **/
+public class CmsUtil {
+
+
+    /* 判断对象是否为空 */
+    public static boolean isNullOrEmpty(Object obj) {
+        if (obj == null) {
+            return true;
+        }
+
+        if (obj instanceof CharSequence) {
+            return ((CharSequence) obj).length() == 0;
+        }
+
+        if (obj instanceof Collection) {
+            return ((Collection<?>) obj).isEmpty();
+        }
+
+        if (obj instanceof Map) {
+            return ((Map<?, ?>) obj).isEmpty();
+        }
+
+        if (obj instanceof Object[]) {
+            Object[] object = (Object[]) obj;
+            if (object.length == 0) {
+                return true;
+            }
+            boolean empty = true;
+            for (int i = 0; i < object.length; i++) {
+                if (!isNullOrEmpty(object[i])) {
+                    empty = false;
+                    break;
+                }
+            }
+            return empty;
+        }
+        return false;
+    }
+
+}

+ 432 - 0
src/main/java/com/sooka/common/utils/ControllerUtil.java

@@ -0,0 +1,432 @@
+package com.sooka.common.utils;
+
+import com.google.code.kaptcha.Constants;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Description:util
+ *
+ *
+ * @create 2017-04-06
+ **/
+public class ControllerUtil {
+
+    private ControllerUtil() {
+        throw new Error("工具类不能实例化!");
+    }
+
+    /**
+     * 判断是否为Ajav请求
+     * @param request
+     * @return
+     */
+    public static boolean isAjaxRequest(HttpServletRequest request){
+
+        if (!"XMLHttpRequest" .equalsIgnoreCase(request.getHeader("X-Requested-With"))) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 判断验证码是否正确
+     * @param verifyCode
+     * @param request
+     * @return
+     */
+    public static  boolean validate(String verifyCode,HttpServletRequest request) {
+        String text = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
+        if (StrUtil.isBlank(text)) {
+            return false;
+        }
+        return verifyCode.equals(text);
+    }
+
+
+    /**
+     * post请求
+     * @return
+     */
+    public static  boolean isPost() {
+        HttpServletRequest request = getHttpServletRequest();
+        String requersMethod = request.getMethod();
+        if (requersMethod.equals("POST") || "POST".equals(requersMethod)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * get请求
+     *
+     * @return
+     */
+    public static  boolean isGet() {
+        HttpServletRequest request = getHttpServletRequest();
+        String requersMethod = request.getMethod();
+        if (requersMethod.equals("GET") || "GET".equals(requersMethod)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 获取请求域名,域名不包括http请求协议头
+     *
+     * @return 返回域名地址
+     *
+     */
+    public static  String getDomain() {
+        HttpServletRequest request = getHttpServletRequest();
+        String path =  request.getContextPath();
+        String domain = request.getServerName();
+        if (request.getServerPort() == 80) {
+            domain += path;
+        } else {
+            domain += ":" + request.getServerPort() + path;
+        }
+        return domain;
+    }
+
+    /**
+     * 读取服务器主机ip信息
+     *
+     * @return 返回主机IP,异常将会获取不到ip
+     */
+    public static  String getHostIp() {
+        InetAddress addr;
+        try {
+            addr = InetAddress.getLocalHost();
+            return addr.getHostAddress().toString();// 获得本机IP
+        } catch (UnknownHostException e) {
+            e.printStackTrace();
+        }
+        return "";
+    }
+
+    /**
+     *
+     * 获取请求客户端ip
+     *
+     * @param request
+     *
+     * @return ip地址
+     *
+     */
+    public static  String getRemoteAddress(HttpServletRequest request) {
+
+        String ip = request.getHeader("x-forwarded-for");
+        if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
+            ip = request.getRemoteAddr();
+        }
+        return ip;
+    }
+
+    public static void renderErrorHtml(String msg, String desc, HttpServletRequest request, HttpServletResponse response) {
+        try {
+            response.setHeader("Content-type", "text/html;charset=UTF-8");
+            response.setCharacterEncoding("UTF-8");
+            StringBuffer content = new StringBuffer();
+            content.append("<!DOCTYPE html>");
+            content.append("<html>");
+            content.append("<head>");
+            content.append("<meta charset=\"UTF-8\">");
+            content.append("<title>"+msg+"</title>");
+            content.append("</head>");
+            content.append("<body>");
+            content.append("<p style=\"font-size:22px;padding-left:10px;\"><b>"+msg+"</b></p>");
+            content.append("<p style=\"font-size:18px;padding-left:10px;\">描述 : " + desc + "</p>");
+            content.append("<p style=\"font-size:18px;padding-left:10px;\">地址 : " +request.getRequestURL()+"</p>");
+            content.append("</body>");
+            content.append("</html>");
+            PrintWriter out = response.getWriter();
+            out.println(content.toString());
+            out.flush();
+            out.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    public static void renderErrorJson(String msg, HttpServletResponse response) {
+        response.setHeader("Content-type", "application/x-json;charset=UTF-8");
+        response.setCharacterEncoding("UTF-8");
+        try {
+            PrintWriter out = response.getWriter();
+            out.println(JsonUtil.toERROR(msg));
+            out.flush();
+            out.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    public static void renderTimeoutJson(String msg, HttpServletResponse response){
+        response.setHeader("Content-type", "application/x-json;charset=UTF-8");
+        response.setCharacterEncoding("UTF-8");
+        try {
+            PrintWriter out = response.getWriter();
+            out.println(JsonUtil.toTIMEOUT(msg));
+            out.flush();
+            out.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    public static HttpServletRequest getHttpServletRequest(){
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+        return request;
+    }
+
+    public static HttpServletResponse getHttpServletResponse(){
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletResponse response = attributes.getResponse();
+        return response;
+    }
+
+
+    public static HttpSession getHttpSession(){
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+        return request.getSession();
+    }
+
+    public static boolean isMobile() {
+        HttpServletRequest request = getHttpServletRequest();
+        boolean b = false;
+        boolean pcFlag = false;
+        boolean mobileFlag = false;
+        String via = request.getHeader("Via");
+        String userAgent = request.getHeader("user-agent");
+        for (int i = 0; via != null && via.trim().length()!=0 && i < mobileGateWayHeaders.length; i++) {
+            if (via.contains(mobileGateWayHeaders[i])) {
+                mobileFlag = true;
+                break;
+            }
+        }
+        for (int i = 0; !mobileFlag && userAgent != null && userAgent.trim().length()!=0
+                && i < mobileUserAgents.length; i++) {
+            if (userAgent.contains(mobileUserAgents[i])) {
+                mobileFlag = true;
+                break;
+            }
+        }
+        for (int i = 0; userAgent != null && userAgent.trim().length()!=0 && i < pcHeaders.length; i++) {
+            if (userAgent.contains(pcHeaders[i])) {
+                pcFlag = true;
+                break;
+            }
+        }
+        if (mobileFlag == true && pcFlag == false) {
+            b = true;
+        }
+        return b;
+
+    }
+
+    private static String mobileGateWayHeaders[] = new String[] { "ZXWAP", // 中兴提供的wap网关的via信息,例如:Via=ZXWAP
+
+            // GateWayZTE
+
+            // Technologies,
+
+            "chinamobile.com", // 中国移动的诺基亚wap网关,例如:Via=WTP/1.1
+
+            // GDSZ-PB-GW003-WAP07.gd.chinamobile.com (Nokia
+
+            // WAP Gateway 4.1 CD1/ECD13_D/4.1.04)
+
+            "monternet.com", // 移动梦网的网关,例如:Via=WTP/1.1
+
+            // BJBJ-PS-WAP1-GW08.bj1.monternet.com. (Nokia WAP
+
+            // Gateway 4.1 CD1/ECD13_E/4.1.05)
+
+            "infoX", // 华为提供的wap网关,例如:Via=HTTP/1.1 GDGZ-PS-GW011-WAP2
+            // (infoX-WISG
+
+            // Huawei Technologies),或Via=infoX WAP Gateway V300R001
+
+            // Huawei Technologies
+
+            "XMS 724Solutions HTG", // 国外电信运营商的wap网关,不知道是哪一家
+
+            "wap.lizongbo.com", // 自己测试时模拟的头信息
+
+            "Bytemobile",// 貌似是一个给移动互联网提供解决方案提高网络运行效率的,例如:Via=1.1 Bytemobile OSN
+
+            // WebProxy/5.1
+
+    };
+
+    private static String[] pcHeaders = new String[] { "Windows 98", "Windows ME", "Windows 2000", "Windows XP",
+            "Windows NT", "Ubuntu" };
+
+    private  static String[] mobileUserAgents = new String[] { "Nokia", // 诺基亚,有山寨机也写这个的,总还算是手机,Mozilla/5.0
+
+            // (Nokia5800
+
+            // XpressMusic)UC
+
+            // AppleWebkit(like
+
+            // Gecko)
+
+            // Safari/530
+
+            "SAMSUNG", // 三星手机
+
+            // SAMSUNG-GT-B7722/1.0+SHP/VPP/R5+Dolfin/1.5+Nextreaming+SMM-MMS/1.2.0+profile/MIDP-2.1+configuration/CLDC-1.1
+
+            "MIDP-2", // j2me2.0,Mozilla/5.0 (SymbianOS/9.3; U; Series60/3.2
+
+            // NokiaE75-1 /110.48.125 Profile/MIDP-2.1
+
+            // Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML like
+
+            // Gecko) Safari/413
+
+            "CLDC1.1", // M600/MIDP2.0/CLDC1.1/Screen-240X320
+
+            "SymbianOS", // 塞班系统的,
+
+            "MAUI", // MTK山寨机默认ua
+
+            "UNTRUSTED/1.0", // 疑似山寨机的ua,基本可以确定还是手机
+
+            "Windows CE", // Windows CE,Mozilla/4.0 (compatible; MSIE 6.0;
+
+            // Windows CE; IEMobile 7.11)
+
+            "iPhone", // iPhone是否也转wap?不管它,先区分出来再说。Mozilla/5.0 (iPhone; U; CPU
+
+            // iPhone OS 4_1 like Mac OS X; zh-cn) AppleWebKit/532.9
+
+            // (KHTML like Gecko) Mobile/8B117
+
+            "iPad", // iPad的ua,Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X;
+
+            // zh-cn) AppleWebKit/531.21.10 (KHTML like Gecko)
+
+            // Version/4.0.4 Mobile/7B367 Safari/531.21.10
+
+            "Android", // Android是否也转wap?Mozilla/5.0 (Linux; U; Android
+
+            // 2.1-update1; zh-cn; XT800 Build/TITA_M2_16.22.7)
+
+            // AppleWebKit/530.17 (KHTML like Gecko) Version/4.0
+
+            // Mobile Safari/530.17
+
+            "BlackBerry", // BlackBerry8310/2.7.0.106-4.5.0.182
+
+            "UCWEB", // ucweb是否只给wap页面? Nokia5800
+
+            // XpressMusic/UCWEB7.5.0.66/50/999
+
+            "ucweb", // 小写的ucweb貌似是uc的代理服务器Mozilla/6.0 (compatible; MSIE 6.0;)
+
+            // Opera ucweb-squid
+
+            "BREW", // 很奇怪的ua,例如:REW-Applet/0x20068888 (BREW/3.1.5.20; DeviceId:
+
+            // 40105; Lang: zhcn) ucweb-squid
+
+            "J2ME", // 很奇怪的ua,只有J2ME四个字母
+
+            "YULONG", // 宇龙手机,YULONG-CoolpadN68/10.14 IPANEL/2.0 CTC/1.0
+
+            "YuLong", // 还是宇龙
+
+            "COOLPAD", // 宇龙酷派YL-COOLPADS100/08.10.S100 POLARIS/2.9 CTC/1.0
+
+            "TIANYU", // 天语手机TIANYU-KTOUCH/V209/MIDP2.0/CLDC1.1/Screen-240X320
+
+            "TY-", // 天语,TY-F6229/701116_6215_V0230 JUPITOR/2.2 CTC/1.0
+
+            "K-Touch", // 还是天语K-Touch_N2200_CMCC/TBG110022_1223_V0801 MTK/6223
+
+            // Release/30.07.2008 Browser/WAP2.0
+
+            "Haier", // 海尔手机,Haier-HG-M217_CMCC/3.0 Release/12.1.2007
+
+            // Browser/WAP2.0
+
+            "DOPOD", // 多普达手机
+
+            "Lenovo", // 联想手机,Lenovo-P650WG/S100 LMP/LML Release/2010.02.22
+
+            // Profile/MIDP2.0 Configuration/CLDC1.1
+
+            "LENOVO", // 联想手机,比如:LENOVO-P780/176A
+
+            "HUAQIN", // 华勤手机
+
+            "AIGO-", // 爱国者居然也出过手机,AIGO-800C/2.04 TMSS-BROWSER/1.0.0 CTC/1.0
+
+            "CTC/1.0", // 含义不明
+
+            "CTC/2.0", // 含义不明
+
+            "CMCC", // 移动定制手机,K-Touch_N2200_CMCC/TBG110022_1223_V0801 MTK/6223
+
+            // Release/30.07.2008 Browser/WAP2.0
+
+            "DAXIAN", // 大显手机DAXIAN X180 UP.Browser/6.2.3.2(GUI) MMP/2.0
+
+            "MOT-", // 摩托罗拉,MOT-MOTOROKRE6/1.0 LinuxOS/2.4.20 Release/8.4.2006
+
+            // Browser/Opera8.00 Profile/MIDP2.0 Configuration/CLDC1.1
+
+            // Software/R533_G_11.10.54R
+
+            "SonyEricsson", // 索爱手机,SonyEricssonP990i/R100 Mozilla/4.0
+
+            // (compatible; MSIE 6.0; Symbian OS; 405) Opera
+
+            // 8.65 [zh-CN]
+
+            "GIONEE", // 金立手机
+
+            "HTC", // HTC手机
+
+            "ZTE", // 中兴手机,ZTE-A211/P109A2V1.0.0/WAP2.0 Profile
+
+            "HUAWEI", // 华为手机,
+
+            "webOS", // palm手机,Mozilla/5.0 (webOS/1.4.5; U; zh-CN)
+
+            // AppleWebKit/532.2 (KHTML like Gecko) Version/1.0
+
+            // Safari/532.2 Pre/1.0
+
+            "GoBrowser", // 3g GoBrowser.User-Agent=Nokia5230/GoBrowser/2.0.290
+
+            // Safari
+
+            "IEMobile", // Windows CE手机自带浏览器,
+
+            "WAP2.0"// 支持wap 2.0的
+
+    };
+}

+ 287 - 0
src/main/java/com/sooka/common/utils/DateUtil.java

@@ -0,0 +1,287 @@
+package com.sooka.common.utils;
+
+import org.apache.commons.lang.time.DateUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+
+public class DateUtil extends DateUtils {
+	private static Logger logger = LoggerFactory.getLogger(DateUtil.class);
+	/** 毫秒 */
+	public final static long MS = 1;
+	/** 每秒钟的毫秒数 */
+	public final static long SECOND_MS = MS * 1000;
+	/** 每分钟的毫秒数 */
+	public final static long MINUTE_MS = SECOND_MS * 60;
+	/** 每小时的毫秒数 */
+	public final static long HOUR_MS = MINUTE_MS * 60;
+	/** 每天的毫秒数 */
+	public final static long DAY_MS = HOUR_MS * 24;
+
+	/** 标准日期(不含时间)格式化器 */
+	private final static SimpleDateFormat NORM_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
+	/** 标准日期时间格式化器 */
+	private final static SimpleDateFormat NORM_DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+	/** HTTP日期时间格式化器 */
+	private final static SimpleDateFormat HTTP_DATETIME_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",
+			Locale.US);
+
+
+	private final static SimpleDateFormat sdfDays = new SimpleDateFormat(
+			"yyyyMMdd");
+	/**
+	 * 获取YYYYMMDD格式
+	 *
+	 * @return
+	 */
+	public static String getDays(){
+		return sdfDays.format(new Date());
+	}
+
+
+	/**
+	 * 
+	 * 当前时间,格式 yyyy-MM-dd HH:mm:ss
+	 * 
+	 * @return 当前时间的标准形式字符串
+	 * 
+	 */
+	public static String now() {
+		return formatDateTime(new Date());
+	}
+
+	/**
+	 * 
+	 * 当前日期,格式 yyyy-MM-dd
+	 * 
+	 * @return 当前日期的标准形式字符串
+	 * 
+	 */
+	public static String today() {
+		return formatDate(new Date());
+	}
+
+
+	/**
+	 * 
+	 * 根据特定格式格式化日期
+	 * 
+	 * @param date
+	 *            被格式化的日期
+	 * 
+	 * @param format
+	 *            格式
+	 * 
+	 * @return 格式化后的字符串
+	 * 
+	 */
+	public static String format(Date date, String format) {
+		return new SimpleDateFormat(format).format(date);
+	}
+
+	/**
+	 * 
+	 * 格式 yyyy-MM-dd HH:mm:ss
+	 * 
+	 * @param date
+	 *            被格式化的日期
+	 * 
+	 * @return 格式化后的日期
+	 * 
+	 */
+	public static String formatDateTime(Date date) {
+		// return format(d, "yyyy-MM-dd HH:mm:ss");
+
+		return NORM_DATETIME_FORMAT.format(date);
+	}
+
+	/**
+	 * 
+	 * 格式化为Http的标准日期格式
+	 * 
+	 * @param date
+	 *            被格式化的日期
+	 * 
+	 * @return HTTP标准形式日期字符串
+	 * 
+	 */
+	public static String formatHttpDate(Date date) {
+		// return new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",
+		// Locale.US).format(date);
+
+		return HTTP_DATETIME_FORMAT.format(date);
+	}
+
+	/**
+	 * 
+	 * 格式 yyyy-MM-dd
+	 * 
+	 * @param date
+	 *            被格式化的日期
+	 * 
+	 * @return 格式化后的字符串
+	 * 
+	 */
+	public static String formatDate(Date date) {
+		// return format(d, "yyyy-MM-dd");
+
+		return NORM_DATE_FORMAT.format(date);
+	}
+	// ------------------------------------ Format end
+	// ----------------------------------------------
+
+	// ------------------------------------ Parse start
+	// ----------------------------------------------
+
+	/**
+	 * 
+	 * 将特定格式的日期转换为Date对象
+	 * 
+	 * @param dateString
+	 *            特定格式的日期
+	 * 
+	 * @param format
+	 *            格式,例如yyyy-MM-dd
+	 * 
+	 * @return 日期对象
+	 * 
+	 */
+	public static Date parse(String dateString, String format) {
+		try {
+			return (new SimpleDateFormat(format)).parse(dateString);
+		} catch (ParseException e) {
+			logger.error("Parse " + dateString + " with format " + format + " error!", e);
+		}
+		return null;
+	}
+
+	/**
+	 * 
+	 * 格式yyyy-MM-dd HH:mm:ss
+	 * 
+	 * @param dateString
+	 *            标准形式的时间字符串
+	 * 
+	 * @return 日期对象
+	 * 
+	 */
+	public static Date parseDateTime(String dateString) {
+		// return parse(s, "yyyy-MM-dd HH:mm:ss");
+
+		try {
+			return NORM_DATETIME_FORMAT.parse(dateString);
+		} catch (ParseException e) {
+			logger.error("Parse " + dateString + " with format " + NORM_DATETIME_FORMAT.toPattern() + " error!", e);
+		}
+		return null;
+	}
+
+	/**
+	 * 
+	 * 格式yyyy-MM-dd
+	 * 
+	 * @param dateString
+	 *            标准形式的日期字符串
+	 * 
+	 * @return 日期对象
+	 * 
+	 */
+	public static Date parseDate(String dateString) {
+		// return parse(s, "yyyy-MM-dd");
+
+		try {
+			return NORM_DATE_FORMAT.parse(dateString);
+		} catch (ParseException e) {
+			logger.error("Parse " + dateString + " with format " + NORM_DATE_FORMAT.toPattern() + " error!", e);
+		}
+		return null;
+	}
+	// ------------------------------------ Parse end
+	// ----------------------------------------------
+
+	/**
+	 * 
+	 * 获取指定日期偏移指定时间后的时间
+	 * 
+	 * @param date
+	 *            基准日期
+	 * 
+	 * @param calendarField
+	 *            偏移的粒度大小(小时、天、月等)使用Calendar中的常数
+	 * 
+	 * @param offsite
+	 *            偏移量,正数为向后偏移,负数为向前偏移
+	 * 
+	 * @return 偏移后的日期
+	 * 
+	 */
+	public static Date getOffsiteDate(Date date, int calendarField, int offsite) {
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(date);
+		cal.add(calendarField, offsite);
+		return cal.getTime();
+	}
+
+	/**
+	 * 
+	 * 判断两个日期相差的时长<br/>
+	 * 
+	 * 返回 minuend - subtrahend 的差
+	 * 
+	 * @param subtrahend
+	 *            减数日期
+	 * 
+	 * @param minuend
+	 *            被减数日期
+	 * 
+	 * @param diffField
+	 *            相差的选项:相差的天、小时
+	 * 
+	 * @return 日期差
+	 * 
+	 */
+	public static long dateDiff(Date subtrahend, Date minuend, long diffField) {
+		long diff = minuend.getTime() - subtrahend.getTime();
+		return diff / diffField;
+	}
+
+	/**
+	 * 转译a标签
+	 * @param content
+	 * @return
+	 */
+	private String labelFormat(String content){
+		if(StringUtils.isBlank(content)) {
+            return "";
+        }
+		return content.replaceAll("<a", "&lt;a").replaceAll("</a>", "&lt;/a&gt;");
+	}
+
+	/**
+	 * 日期比较(只比较日期部分)
+	 * date1 > date2 返回true
+	 * @param date1
+	 * @param date2
+	 * @return
+	 * @throws ParseException
+	 */
+	public static boolean  dateCompare(Date date1,Date date2){
+		if(date1 == null) {
+            return false;
+        }
+		if(date2 == null) {
+            return true;
+        }
+		if(date1.getTime() > date2.getTime()) {
+            return true;
+        }
+		return false;
+	}
+}

+ 137 - 0
src/main/java/com/sooka/common/utils/EncryptUtil.java

@@ -0,0 +1,137 @@
+package com.sooka.common.utils;
+
+import javax.crypto.*;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.UnsupportedEncodingException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+public class EncryptUtil {
+
+
+	/**/
+	public static String encryptByHex(String str1, String salt) {
+		String salts = CheckSumUtil.getMD5(salt);
+		return parseByte2HexStr(encrypt(str1, salts));
+
+	}
+
+
+
+	/**/
+	public static String decryptToString(String st1, String salt) {
+		String salts =  CheckSumUtil.getMD5(salt);
+		byte[] decryptFrom = parseHexStr2Byte(st1);
+		byte[] decryptResult = decrypt(decryptFrom, salts);
+		return new String(decryptResult);
+
+	}
+
+
+	/**
+	 * 加密
+	 *
+	 *  需要加密的内容
+	 * @param str
+	 *  加密
+	 * @return
+	 */
+	public static byte[] encrypt(String str, String salt) {
+		try {
+			KeyGenerator kgen = KeyGenerator.getInstance("AES");
+			kgen.init(128, new SecureRandom(salt.getBytes()));
+			SecretKey secretKey = kgen.generateKey();
+			byte[] enCodeFormat = secretKey.getEncoded();
+			SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
+			Cipher cipher = Cipher.getInstance("AES");// 创建密码器
+			byte[] byteContent = str.getBytes("utf-8");
+			cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
+			byte[] result = cipher.doFinal(byteContent);
+			return result; // 加密
+		} catch (NoSuchAlgorithmException e) {
+			e.printStackTrace();
+		} catch (NoSuchPaddingException e) {
+			e.printStackTrace();
+		} catch (InvalidKeyException e) {
+			e.printStackTrace();
+		} catch (UnsupportedEncodingException e) {
+			e.printStackTrace();
+		} catch (IllegalBlockSizeException e) {
+			e.printStackTrace();
+		} catch (BadPaddingException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/**
+	 * 解密
+	 *
+	 *  待解密内容
+	 * @param str
+	 *  解密密钥
+	 * @return
+	 */
+	public static byte[] decrypt(byte[] str, String salt) {
+		try {
+			KeyGenerator kgen = KeyGenerator.getInstance("AES");
+			kgen.init(128, new SecureRandom(salt.getBytes()));
+			SecretKey secretKey = kgen.generateKey();
+			byte[] enCodeFormat = secretKey.getEncoded();
+			SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
+			Cipher cipher = Cipher.getInstance("AES");// 创建密码器
+			cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
+			byte[] result = cipher.doFinal(str);
+			return result; // 加密
+		} catch (NoSuchAlgorithmException e) {
+			e.printStackTrace();
+		} catch (NoSuchPaddingException e) {
+			e.printStackTrace();
+		} catch (InvalidKeyException e) {
+			e.printStackTrace();
+		} catch (IllegalBlockSizeException e) {
+			e.printStackTrace();
+		} catch (BadPaddingException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/**
+	 * 将二进制转换成16进制
+	 * 
+	 * @param buf
+	 * @return
+	 */
+	public static String parseByte2HexStr(byte buf[]) {
+		StringBuffer sb = new StringBuffer();
+		for (int i = 0; i < buf.length; i++) {
+			String hex = Integer.toHexString(buf[i] & 0xFF);
+			if (hex.length() == 1) {
+				hex = '0' + hex;
+			}
+			sb.append(hex.toUpperCase());
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * 将16进制转换为二进制
+	 * 
+	 * @param hexStr
+	 * @return
+	 */
+	public static byte[] parseHexStr2Byte(String hexStr) {
+		if (hexStr.length() < 1) {
+            return null;
+        }
+		byte[] result = new byte[hexStr.length() / 2];
+		for (int i = 0; i < hexStr.length() / 2; i++) {
+			int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
+			int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
+			result[i] = (byte) (high * 16 + low);
+		}
+		return result;
+	}
+}

+ 304 - 0
src/main/java/com/sooka/common/utils/ExcelUtil.java

@@ -0,0 +1,304 @@
+package com.sooka.common.utils;
+
+import com.google.common.collect.Lists;
+import com.sooka.mybatis.model.TCmsContent;
+import com.sooka.common.annotation.ExcelField;
+import com.sooka.common.exception.SystemException;
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.xssf.usermodel.XSSFCell;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.beans.PropertyDescriptor;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Description:
+ *
+ *
+ * @create 2017-07-27
+ **/
+public class ExcelUtil {
+
+    public static void exports(String sheetName,List<?> list) {
+
+        if(CmsUtil.isNullOrEmpty(list)) {
+            throw new SystemException("导出excel失败!");
+        }
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletResponse response = attributes.getResponse();
+        try {
+            ServletOutputStream out = response.getOutputStream();
+            HSSFWorkbook wb = new HSSFWorkbook();
+            HSSFSheet sheet=wb.createSheet(sheetName);
+            for (int i= 0;i<list.size();i++) {
+                Object obj = list.get(i);
+                Class clazz = obj.getClass();
+                if(i== 0) {
+                    HSSFRow row=sheet.createRow(i);
+                    Field[] fields = clazz.getDeclaredFields();
+                    int tmp = 0;
+                    for (Field field :fields) {
+                        HSSFCell cell = row.createCell(tmp);
+                        ExcelField excelFiled = field.getAnnotation(ExcelField.class);
+                        /*判断是否只支持导入*/
+                        if (excelFiled == null||excelFiled.isOnlyImport()) {
+                            continue;
+                        }
+                        cell.setCellValue(excelFiled.value());
+                        tmp++;
+                    }
+                }
+                HSSFRow row=sheet.createRow(i+1);
+                Field[] fields = clazz.getDeclaredFields();
+                int tmp = 0;
+                for (Field field :fields) {
+                    ExcelField excelFiled = field.getAnnotation(ExcelField.class);
+                    if (excelFiled == null||excelFiled.isOnlyImport()){continue;}
+                    HSSFCell cell = row.createCell(tmp);
+                    PropertyDescriptor pd = new PropertyDescriptor(field.getName(),clazz);
+                    Method getMethod = pd.getReadMethod();
+                    Object o = getMethod.invoke(obj);
+                    if(!StrUtil.isBlank(excelFiled.dateFormat())&& o instanceof Date) {
+                        cell.setCellValue(DateUtil.format((Date)o,excelFiled.dateFormat()));
+                    } else {
+                        cell.setCellValue(CmsUtil.isNullOrEmpty(o)?excelFiled.isNullDefaultValue():String.valueOf(o));
+                    }
+                    tmp++;
+                }
+            }
+            response.reset();
+            response.setHeader("Content-disposition", "attachment;filename="+ new String(sheetName.getBytes("utf-8"), "ISO8859-1")+".xls");
+            response.setContentType("application/msexcel");
+            wb.write(out);
+            out.flush();
+            out.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new SystemException("导出excel失败,["+e.getMessage()+"]");
+        }
+    }
+
+    public static void exports2007(String sheetName,List<?> list) {
+
+        if(CmsUtil.isNullOrEmpty(list)) {
+            throw new SystemException("导出excel失败!");
+        }
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletResponse response = attributes.getResponse();
+        try {
+            ServletOutputStream out = response.getOutputStream();
+            XSSFWorkbook wb = new XSSFWorkbook();
+            XSSFSheet sheet=wb.createSheet(sheetName);
+            for (int i= 0;i<list.size();i++) {
+                Object obj = list.get(i);
+                Class clazz = obj.getClass();
+                if(i== 0) {
+                    XSSFRow row=sheet.createRow(i);
+                    Field[] fields = clazz.getDeclaredFields();
+                    int tmp = 0;
+                    for (Field field :fields) {
+                        XSSFCell cell = row.createCell(tmp);
+                        ExcelField excelFiled = field.getAnnotation(ExcelField.class);
+                        if (excelFiled == null||excelFiled.isOnlyImport()) {
+                            continue;
+                        }
+                        cell.setCellValue(excelFiled.value());
+                        tmp++;
+                    }
+                }
+                XSSFRow row=sheet.createRow(i+1);
+                Field[] fields = clazz.getDeclaredFields();
+                int tmp = 0;
+                for (Field field :fields) {
+                    ExcelField excelFiled = field.getAnnotation(ExcelField.class);
+                    if (excelFiled == null||excelFiled.isOnlyImport()){continue;}
+                    XSSFCell cell = row.createCell(tmp);
+                    PropertyDescriptor pd = new PropertyDescriptor(field.getName(),clazz);
+                    Method getMethod = pd.getReadMethod();
+                    Object o = getMethod.invoke(obj);
+                    if(!StrUtil.isBlank(excelFiled.dateFormat())&& o instanceof Date) {
+                        cell.setCellValue(DateUtil.format((Date)o,excelFiled.dateFormat()));
+                    } else {
+                        cell.setCellValue(CmsUtil.isNullOrEmpty(o)?excelFiled.isNullDefaultValue():String.valueOf(o));
+                    }
+                    tmp++;
+                }
+            }
+            response.reset();
+            response.setHeader("Content-disposition", "attachment;filename="+ new String(sheetName.getBytes("utf-8"), "ISO8859-1")+".xlsx");
+            response.setContentType("application/msexcel");
+            wb.write(out);
+            out.flush();
+            out.close();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("导出excel失败,["+e.getMessage()+"]");
+        }
+    }
+
+
+    public static <T> List<T> imports(FileInputStream is,Class<T> clazz){
+        List<T> result = Lists.newArrayList();
+        try {
+            HSSFWorkbook workbook = new HSSFWorkbook(is);
+            Sheet sheet = workbook.getSheetAt(0);
+            /*获取第0行标题*/
+            Row row0 = sheet.getRow(0);
+            /*遍历每一列*/
+            for (int r = 1; r < sheet.getPhysicalNumberOfRows(); r++) {
+                T obj = clazz.newInstance();
+                Field[] fields = obj.getClass().getDeclaredFields();
+                Row row = sheet.getRow(r);
+                for (int c = 0; c < row.getPhysicalNumberOfCells(); c++) {
+                    for(Field field :fields) {
+                        ExcelField excelFiled = field.getAnnotation(ExcelField.class);
+                        String title = getCellValue(row0.getCell(c).getCellType(), row0.getCell(c));
+                        if(excelFiled==null&&!title.equals(excelFiled.value())) {
+                            continue;
+                        }
+                        String cellValue = getCellValue(row.getCell(c).getCellType(), row.getCell(c));
+                        PropertyDescriptor pd = new PropertyDescriptor(field.getName(),obj.getClass());
+                        if("错误".equals(cellValue)||field.getType()==String.class) {
+                            pd.getWriteMethod().invoke(obj, cellValue);
+                            continue;
+                        }
+                        if(field.getType()==Integer.class){
+                            pd.getWriteMethod().invoke(obj, Integer.parseInt(cellValue));
+                            continue;
+                        }
+                        if(field.getType()==Long.class){
+                            pd.getWriteMethod().invoke(obj, Long.parseLong(cellValue));
+                            continue;
+                        }
+                        if(field.getType()==Float.class){
+                            pd.getWriteMethod().invoke(obj, Float.parseFloat(cellValue));
+                            continue;
+                        }
+                        if(field.getType()==Double.class){
+                            pd.getWriteMethod().invoke(obj, Double.parseDouble(cellValue));
+                            continue;
+                        }
+                        if(field.getType()==Date.class) {
+                            pd.getWriteMethod().invoke(obj, DateUtil.parseDate(cellValue));
+                        }
+
+                    }
+                }
+                result.add(obj);
+            }
+        }catch (Exception e) {
+            throw new RuntimeException("导如excel失败,["+e.getMessage()+"]");
+        }
+        return result;
+    }
+
+    public static <T>List<T> imports2007(FileInputStream is,Class<T> clazz){
+        List<T> result = Lists.newArrayList();
+        try {
+            XSSFWorkbook workbook = new XSSFWorkbook(is);
+            Sheet sheet = workbook.getSheetAt(0);
+            /*获取第0行标题*/
+            Row row0 = sheet.getRow(0);
+            /*遍历每一列*/
+            for (int r = 1; r < sheet.getPhysicalNumberOfRows(); r++) {
+                T obj = clazz.newInstance();
+                Field[] fields = obj.getClass().getDeclaredFields();
+                Row row = sheet.getRow(r);
+                for (int c = 0; c < row.getPhysicalNumberOfCells(); c++) {
+                    for(Field field :fields) {
+                        ExcelField excelFiled = field.getAnnotation(ExcelField.class);
+                        String title = getCellValue(row0.getCell(c).getCellType(), row0.getCell(c));
+                        if(excelFiled==null||!title.equals(excelFiled.value())) {
+                            continue;
+                        }
+                        String cellValue = getCellValue(row.getCell(c).getCellType(), row.getCell(c));
+                        PropertyDescriptor pd = new PropertyDescriptor(field.getName(),obj.getClass());
+                        if("错误".equals(cellValue)||field.getType()==String.class) {
+                            pd.getWriteMethod().invoke(obj, cellValue);
+                            continue;
+                        }
+                        if(field.getType()==Integer.class){
+                            pd.getWriteMethod().invoke(obj, Integer.parseInt(cellValue));
+                            continue;
+                        }
+                        if(field.getType()==Long.class){
+                            pd.getWriteMethod().invoke(obj, Long.parseLong(cellValue));
+                            continue;
+                        }
+                        if(field.getType()==Float.class){
+                            pd.getWriteMethod().invoke(obj, Float.parseFloat(cellValue));
+                            continue;
+                        }
+                        if(field.getType()==Double.class){
+                            pd.getWriteMethod().invoke(obj, Double.parseDouble(cellValue));
+                            continue;
+                        }
+                        if(field.getType()==Date.class) {
+                            pd.getWriteMethod().invoke(obj, DateUtil.parseDate(cellValue));
+                        }
+
+                    }
+                }
+                result.add(obj);
+            }
+        }catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("导如excel失败,["+e.getMessage()+"]");
+        }
+        return result;
+    }
+
+    public static String getCellValue(int cellType,Cell cell){
+        switch(cellType) {
+            case Cell.CELL_TYPE_STRING: /*文本*/
+                return cell.getStringCellValue();
+            case Cell.CELL_TYPE_NUMERIC: /*数字、日期*/
+                if(org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) {
+                    return DateUtil.formatDate(cell.getDateCellValue()); /*日期型*/
+                }
+                else {
+                    return String.valueOf(cell.getNumericCellValue()); /*数字*/
+                }
+            case Cell.CELL_TYPE_BOOLEAN: /*布尔型*/
+                return  String.valueOf(cell.getBooleanCellValue());
+            case Cell.CELL_TYPE_BLANK: /*空白*/
+                return cell.getStringCellValue();
+            case Cell.CELL_TYPE_ERROR: /*错误*/
+                return "错误";
+            case Cell.CELL_TYPE_FORMULA: /*公式*/
+                return "错误";
+            default:
+                return "错误";
+        }
+    }
+
+    public static void main(String [] args){
+        File file = new File("E:\\123.xlsx");
+        try {
+            FileInputStream inputStream=  new FileInputStream(file);
+            List<TCmsContent> list= imports2007(inputStream, TCmsContent.class);
+            System.out.println(list.get(0).getTitle());
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 139 - 0
src/main/java/com/sooka/common/utils/HtmlKit.java

@@ -0,0 +1,139 @@
+package com.sooka.common.utils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.safety.Whitelist;
+
+public class HtmlKit {
+
+
+
+    // 只有纯文本可以通过
+	public static String getText(String html) {
+		if (html == null) {
+            return null;
+        }
+		return Jsoup.clean(html, Whitelist.none());
+	}
+	
+	// 以下标签可以通过
+	// b, em, i, strong, u. 纯文本 
+	public static String getSimpleHtml(String html) {
+		if (html == null) {
+            return null;
+        }
+		return Jsoup.clean(html, Whitelist.simpleText());
+	}
+	
+	// 以下标签可以通过
+	//a, b, blockquote, br, cite, code, dd, dl, dt, em, i, li, ol, p, pre, q, small, strike, strong, sub, sup, u, ul
+	public static String getBasicHtml(String html) {
+		if (html == null) {
+            return null;
+        }
+		return Jsoup.clean(html, Whitelist.basic());
+	}
+	
+	//在basic基础上  增加图片通过
+	public static String getBasicHtmlAndImage(String html) {
+		if (html == null) {
+            return null;
+        }
+		return Jsoup.clean(html, Whitelist.basicWithImages());
+	}
+	// 只允许图片  src="" width="" height="" title="" align="" alt=""
+	public static String onlyImg(String html){
+		Whitelist wl = Whitelist.none();
+		wl.addTags("img").addAttributes("img", "src", "width", "height", "title", "align", "alt");
+		return Jsoup.clean(html, wl);
+	}
+	// 以下标签可以通过	
+	//a, b, blockquote, br, caption, cite, code, col, colgroup, dd, dl, dt, em, h1, h2, h3, h4, h5, h6, i, img, li, ol, p, pre, q, small, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, u, ul
+	public static String getFullHtml(String html) {
+		if (html == null) {
+            return null;
+        }
+		return Jsoup.clean(html, Whitelist.relaxed());
+	}
+	
+	//只允许指定的html标签
+	public static String clearTags(String html, String ...tags) {
+		Whitelist wl = new Whitelist();
+		return Jsoup.clean(html, wl.addTags(tags));
+	}
+	
+	// 对关键字加上颜色
+	public static String markKeywods (String keywords, String target) {
+		if (!StringUtils.isEmpty(keywords)) {
+			String[] arr = keywords.split(" ");
+			for (String s : arr) {
+				if (!StringUtils.isEmpty(s)) {
+					String temp = "<span class=\"highlight\">" + s + "</span>";
+					if(temp!=null) {
+                        target = target.replaceAll(s, temp);
+                    }
+				}
+			}
+		}
+		return target;
+	}
+
+	// 获取文章中的img url
+	public static String getImgSrc(String html) {
+		if (html == null) {
+            return null;
+        }
+	    Document doc = Jsoup.parseBodyFragment(html);
+	    Element image = doc.select("img").first();
+	    return image == null ? null : image.attr("src");
+	}
+
+	public static String getSafeStringXSS(String s){
+		if (s == null || "".equals(s)) {
+			return s;
+		}
+		StringBuilder sb = new StringBuilder(s.length() + 16);
+		for (int i = 0; i < s.length(); i++) {
+			char c = s.charAt(i);
+			switch (c) {
+				case '<':
+					sb.append("&lt;");
+					break;
+				case '>':
+					sb.append("&gt;");
+					break;
+				case '\'':
+					sb.append("&prime;");// &acute;");
+					break;
+				case '′':
+					sb.append("&prime;");// &acute;");
+					break;
+				case '\"':
+					sb.append("&quot;");
+					break;
+				case '"':
+					sb.append("&quot;");
+					break;
+				case '&':
+					sb.append("&");
+					break;
+				case '#':
+					sb.append("#");
+					break;
+				case '\\':
+					sb.append('¥');
+					break;
+				case '=':
+					sb.append("&#61;");
+					break;
+				default:
+					sb.append(c);
+					break;
+			}
+		}
+		return sb.toString();
+	}
+
+}

+ 106 - 0
src/main/java/com/sooka/common/utils/Http.java

@@ -0,0 +1,106 @@
+package com.sooka.common.utils;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Map;
+
+/**
+ * Created by yanhongliang on 16/6/14.
+ */
+public class Http {
+
+    public interface SignParams {
+        String signParams(String params);
+    }
+
+    static public void setOnSignParams(SignParams signParams) {
+        onSignParams = signParams;
+    }
+    static private SignParams onSignParams;
+
+    static public String stringFromParams(Map<String, Object> post) {
+
+        StringBuilder buffer = new StringBuilder();
+
+        if (post == null) return null;
+
+        ArrayList<String> keys = new ArrayList<>(post.size());
+        keys.addAll(post.keySet());
+        Collections.sort(keys);
+
+//        ArrayList<Map.Entry<String, Object>> params = new ArrayList<>(post.size());
+//
+//        for (Map.Entry<String, Object> entry: post.entrySet()) {
+//            params.add(entry);
+//        }
+//
+//        Collections.sort(params, new Comparator<Map.Entry<String, Object>>() {
+//            @Override
+//            public int compare(Map.Entry<String, Object> lhs, Map.Entry<String, Object> rhs) {
+//
+//                System.out.println("-----lhs-----:=>"+lhs.getKey().hashCode());
+//                System.out.println("-----rhs-----:=>"+rhs.getKey().hashCode());
+//
+//                return lhs.getKey().hashCode() - rhs.getKey().hashCode();
+//            }
+//        });
+
+        for (String key : keys) {
+            Object value = post.get(key);
+            if (buffer.length() > 0) buffer.append("&");
+            buffer.append(key);
+            buffer.append("=");
+            try {
+                buffer.append(URLEncoder.encode(String.valueOf(value), "UTF-8"));
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace();
+            }
+        }
+
+        String paramsString = new String(buffer);
+
+        if (onSignParams != null) {
+            paramsString = onSignParams.signParams(paramsString);
+        }
+
+        return paramsString;
+    }
+
+    public static String getMd5(String string) {
+
+        byte[] hash;
+
+        try {
+
+            hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
+
+        } catch (NoSuchAlgorithmException e) {
+
+            throw new RuntimeException("Huh, MD5 should be supported?", e);
+
+        } catch (UnsupportedEncodingException e) {
+
+            throw new RuntimeException("Huh, UTF-8 should be supported?", e);
+
+        }
+
+
+        StringBuilder hex = new StringBuilder(hash.length * 2);
+
+        for (byte b : hash) {
+
+            if ((b & 0xFF) < 0x10) hex.append("0");
+
+            hex.append(Integer.toHexString(b & 0xFF));
+
+        }
+
+        return hex.toString();
+
+    }
+}

+ 157 - 0
src/main/java/com/sooka/common/utils/HttpRequest.java

@@ -0,0 +1,157 @@
+package com.sooka.common.utils;
+
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Map;
+
+/**
+ * Http 访问
+ */
+public abstract class HttpRequest {
+
+
+    public interface IProgress {
+        void downloadProgress(int percent, long localSize, long totalSize);
+    }
+
+    public void getAsync(final Map<String, Object> params, final String toUrl) {
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                get(params, toUrl);
+            }
+        }).start();
+    }
+
+    public void get(Map<String, Object> params, String toUrl) {
+        sendRequest(toUrl, Http.stringFromParams(params), false);
+    }
+
+    public void postAsync(final Map<String, Object> params, final String toUrl) {
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                post(params, toUrl);
+            }
+        }).start();
+    }
+
+    public void post(Map<String, Object> params, String toUrl) {
+        sendRequest(toUrl, Http.stringFromParams(params), true);
+    }
+
+    private void sendRequest(String url, String params, boolean post) {
+        if (url.equals("")||url == null) return;
+//        Log.i("---------", ""+TextUtils.isEmpty(url));
+
+
+        Response response = new Response(0);
+        HttpURLConnection connection = null;
+        InputStreamReader in = null;
+        try {
+            if (!post) {
+                url = url + "?" + params;
+            }
+            URL uriAPI = new URL(url);
+            connection = (HttpURLConnection) uriAPI.openConnection();
+            // 设置连接主机超时时间
+//            connection.setConnectTimeout(10 * 1000);
+            //设置从主机读取数据超时
+//            connection.setReadTimeout(10 * 1000);
+            // 设置是否使用缓存  默认是true
+            connection.setUseCaches(true);
+
+            if (post) {
+
+                connection.setDoInput(true);
+                connection.setDoOutput(true);
+                connection.setRequestMethod("POST");
+                connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+                connection.setRequestProperty("Charset", "UTF-8");
+
+                connection.setRequestProperty("Content-Length", "" + params.length());
+                System.out.println(url + "?" + params);
+
+                // 写入post参数
+                DataOutputStream dop = new DataOutputStream(connection.getOutputStream());
+                dop.writeBytes(params);
+                dop.flush();
+                dop.close();
+            }
+
+            long timestamp = System.currentTimeMillis();
+            response.state = connection.getResponseCode();
+            response.timestamp = connection.getHeaderFieldDate("Date", 0);
+            if (response.timestamp != 0) {
+                response.timestamp += System.currentTimeMillis() - timestamp;
+            }
+
+            if (response.state == 200) {
+                in = new InputStreamReader(connection.getInputStream());
+
+                BufferedReader bufferedReader = new BufferedReader(in);
+                StringBuilder strBuilder = new StringBuilder();
+                String line;
+                while ((line = bufferedReader.readLine()) != null && !_cancel) {
+                    strBuilder.append(line);
+                }
+                response.content = strBuilder.toString();
+            }
+
+        } catch (Exception e) {
+            response.content = e.getLocalizedMessage();
+            error(e);
+        } finally {
+            if (connection != null) {
+                connection.disconnect();
+            }
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            response.cancel = _cancel;
+            _cancel = false;
+            complete(response);
+        }
+    }
+
+    private boolean _cancel = false;
+    public void cancel() {
+        _cancel = true;
+    }
+
+    public abstract void complete(Response response);
+
+    public void error(Exception e)
+    {
+        e.printStackTrace();
+    }
+
+    /**
+     * A dummy item representing a piece of content.
+     */
+    public static class Response {
+        public boolean cancel = false;
+        public int state;
+        public String content;
+        public long timestamp = 0;
+
+        public Response(int state) {
+            this.state = state;
+            this.content = "";
+        }
+
+        @Override
+        public String toString() {
+            return content;
+        }
+    }
+}

+ 175 - 0
src/main/java/com/sooka/common/utils/JsonUtil.java

@@ -0,0 +1,175 @@
+package com.sooka.common.utils;
+
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Maps;
+import com.sooka.module.api.vo.ApiResult;
+
+import java.util.List;
+import java.util.Map;
+
+public class JsonUtil {
+
+    private final static Integer DEFAULT_ERROR_CODE = 1;
+
+    private final static Integer DEFAULT_SUCCESS_CODE = 0;
+
+
+    /*后台框架请求成功JSON*/
+    public static String toSUCCESS(String message,String tabId,boolean closeCurrent){
+        JSONObject obj = new JSONObject();
+        obj.put("statusCode","200");
+        obj.put("message",message);
+        obj.put("tabid",tabId);
+        obj.put("closeCurrent",closeCurrent);
+        obj.put("forward","");
+        obj.put("forwardConfirm","");
+        return obj.toJSONString();
+    }
+
+    /*后台框架请求成功JSON*/
+    public static String toSUCCESS(String message,String tabId,String dialogid,boolean closeCurrent){
+        JSONObject obj = new JSONObject();
+        obj.put("statusCode","200");
+        obj.put("message",message);
+        obj.put("tabid",tabId);
+        obj.put("dialogid",dialogid);
+        obj.put("closeCurrent",closeCurrent);
+        obj.put("forward","");
+        obj.put("forwardConfirm","");
+        return obj.toJSONString();
+    }
+
+    /*后台框架请求成功JSON*/
+    public static String toSUCCESS(String message,String tabId,String dialogid,String divid,boolean closeCurrent){
+        JSONObject obj = new JSONObject();
+        obj.put("statusCode","200");
+        obj.put("message",message);
+        obj.put("tabid",tabId);
+        obj.put("dialogid",dialogid);
+        obj.put("closeCurrent",closeCurrent);
+        obj.put("divid",divid);
+        obj.put("forwardConfirm","");
+        return obj.toJSONString();
+    }
+
+    /*后台框架请求成功JSON*/
+    public static String toSUCCESS(String message,String tabId,String dialogid,String divid,String forward,boolean closeCurrent){
+        JSONObject obj = new JSONObject();
+        obj.put("statusCode","200");
+        obj.put("message",message);
+        obj.put("tabid",tabId);
+        obj.put("dialogid",dialogid);
+        obj.put("closeCurrent",closeCurrent);
+        obj.put("divid",divid);
+        obj.put("forward",forward);
+        obj.put("forwardConfirm","");
+        return obj.toJSONString();
+    }
+
+    /*后台框架请求成功JSON*/
+    public static String toSUCCESS(String message){
+        JSONObject obj = new JSONObject();
+        obj.put("statusCode","200");
+        obj.put("message",message);
+        obj.put("tabid","");
+        obj.put("closeCurrent",false);
+        obj.put("forward","");
+        obj.put("forwardConfirm","");
+        return obj.toJSONString();
+    }
+
+
+    /*后台框架文件上传成功JSON*/
+    public static String toUploadSUCCESS(String message,String fileName){
+        JSONObject obj = new JSONObject();
+        obj.put("statusCode","200");
+        obj.put("message",message);
+        obj.put("filename",fileName);
+        return obj.toJSONString();
+    }
+
+    /*后台框架文件上传错误JSON*/
+    public static String toUploadRROR(String message){
+        JSONObject obj = new JSONObject();
+        obj.put("statusCode","300");
+        obj.put("message",message);
+        return obj.toJSONString();
+    }
+
+    /*后台框架请求错误JSON*/
+    public static String toERROR(String message){
+        JSONObject obj = new JSONObject();
+        obj.put("statusCode","300");
+        obj.put("message",message);
+        obj.put("tabid","");
+        obj.put("closeCurrent",false);
+        obj.put("forward","");
+        obj.put("forwardConfirm","");
+        return obj.toJSONString();
+    }
+
+    /*后台框架回话超时JSON*/
+    public static String toTIMEOUT(){
+        JSONObject obj = new JSONObject();
+        obj.put("statusCode","301");
+        obj.put("message","会话超时");
+        obj.put("closeCurrent",false);
+        obj.put("forward","");
+        obj.put("forwardConfirm","");
+        return obj.toJSONString();
+    }
+
+    /*后台框架回话超时JSON*/
+    public static String toTIMEOUT(String info){
+        JSONObject obj = new JSONObject();
+        obj.put("statusCode","301");
+        obj.put("message",info);
+        obj.put("closeCurrent",false);
+        obj.put("forward","");
+        obj.put("forwardConfirm","");
+        return obj.toJSONString();
+    }
+
+
+    /*通用信息提示JSON*/
+    public static Map toMAP(boolean success, String msg){
+        Map obj = Maps.newHashMap();
+        obj.put("success",success);
+        obj.put("message",msg);
+        return obj;
+    }
+
+    /* API接口请求成功返回JSON */
+    public static String toSuccessResultJSON(String msg,List list){
+        ApiResult result = new ApiResult<List>();
+        result.setStatusCode(DEFAULT_SUCCESS_CODE);
+        result.setMsg(msg);
+        result.setData(list);
+        return JSON.toJSONString(result);
+    }
+
+    /* API接口请求成功返回JSON */
+    public static String toSuccessResultJSON(String msg,Object object){
+        ApiResult result = new ApiResult();
+        result.setStatusCode(DEFAULT_SUCCESS_CODE);
+        result.setMsg(msg);
+        if(!CmsUtil.isNullOrEmpty(object)) {
+            result.setData(object);
+        }
+        return JSON.toJSONString(result);
+    }
+    /* API接口请求错误返回JSON */
+    public static String toErrorResultJSON(String msg){
+        ApiResult result = new ApiResult();
+        result.setStatusCode(DEFAULT_ERROR_CODE);
+        result.setMsg(msg);
+        return JSON.toJSONString(result);
+    }
+
+    /*创建一个新的JSONObject*/
+    public static JSONObject newJSONObject(){
+        return new JSONObject();
+    }
+}

+ 35 - 0
src/main/java/com/sooka/common/utils/MD5.java

@@ -0,0 +1,35 @@
+package com.sooka.common.utils;
+
+import java.security.MessageDigest;
+
+public class MD5 {
+
+	public static String md5(String str) {
+		try {
+			MessageDigest md = MessageDigest.getInstance("MD5");
+			md.update(str.getBytes());
+			byte b[] = md.digest();
+
+			int i;
+
+			StringBuffer buf = new StringBuffer("");
+			for (int offset = 0; offset < b.length; offset++) {
+				i = b[offset];
+				if (i < 0)
+					i += 256;
+				if (i < 16)
+					buf.append("0");
+				buf.append(Integer.toHexString(i));
+			}
+			str = buf.toString();
+		} catch (Exception e) {
+			e.printStackTrace();
+
+		}
+		return str;
+	}
+	public static void main(String[] args) {
+		System.out.println(md5("31119@qq.com"+"123456"));
+		System.out.println(md5("mj1"));
+	}
+}

+ 36 - 0
src/main/java/com/sooka/common/utils/MMain.java

@@ -0,0 +1,36 @@
+package com.sooka.common.utils;
+
+/******************************
+ * @Description TODO
+ * @Author yanhongliang
+ * @Date 2019-11-26 16:41
+ ******************************/
+
+public class MMain {
+
+
+    public static void main(String[] args) {
+
+        int[] a = {15};
+
+        for (int i1 : a) {
+
+            int b = i1 / 5;
+
+            for (int j = 0; j < 5; j++) {
+                System.out.print("*");
+            }
+
+            for (int j = 0; j < (5 - 5); j++) {
+                System.out.print("-");
+            }
+
+            System.out.println("-");
+
+        }
+
+
+    }
+
+
+}

+ 72 - 0
src/main/java/com/sooka/common/utils/ObjectExcelView.java

@@ -0,0 +1,72 @@
+package com.sooka.common.utils;
+
+import org.apache.poi.hssf.usermodel.*;
+import org.springframework.web.servlet.view.document.AbstractExcelView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+* 导入到EXCEL
+* 类名称:ObjectExcelView.java
+* 类描述: 
+* @author FH
+* 作者单位: 
+* 联系方式:
+* @version 1.0
+ */
+public class ObjectExcelView extends AbstractExcelView {
+
+	@Override
+	protected void buildExcelDocument(Map<String, Object> model,
+			HSSFWorkbook workbook, HttpServletRequest request,
+			HttpServletResponse response) throws Exception {
+		// TODO Auto-generated method stub
+		Date date = new Date();
+		String filename = Tools.date2Str(date, "yyyyMMddHHmmss");
+		HSSFSheet sheet;
+		HSSFCell cell;
+		response.setContentType("application/octet-stream");
+		response.setHeader("Content-Disposition", "attachment;filename="+filename+".xls");
+		sheet = workbook.createSheet("sheet1");
+		
+		List<String> titles = (List<String>) model.get("titles");
+		int len = titles.size();
+		HSSFCellStyle headerStyle = workbook.createCellStyle(); //标题样式
+		headerStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
+		headerStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
+		HSSFFont headerFont = workbook.createFont();	//标题字体
+		headerFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
+		headerFont.setFontHeightInPoints((short)11);
+		headerStyle.setFont(headerFont);
+		short width = 20,height=25*20;
+		sheet.setDefaultColumnWidth(width);
+		for(int i=0; i<len; i++){ //设置标题
+			String title = titles.get(i);
+			cell = getCell(sheet, 0, i);
+			cell.setCellStyle(headerStyle);
+			setText(cell,title);
+		}
+		sheet.getRow(0).setHeight(height);
+		
+		HSSFCellStyle contentStyle = workbook.createCellStyle(); //内容样式
+		contentStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
+		List<PageData> varList = (List<PageData>) model.get("varList");
+		int varCount = varList.size();
+		for(int i=0; i<varCount; i++){
+			PageData vpd = varList.get(i);
+			for(int j=0;j<len;j++){
+				String varstr = vpd.getString("var"+(j+1)) != null ? vpd.getString("var"+(j+1)) : "";
+				cell = getCell(sheet, i+1, j);
+				cell.setCellStyle(contentStyle);
+				setText(cell,varstr);
+			}
+			
+		}
+		
+	}
+
+}

+ 122 - 0
src/main/java/com/sooka/common/utils/PageData.java

@@ -0,0 +1,122 @@
+package com.sooka.common.utils;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class PageData extends HashMap implements Map{
+	
+	private static final long serialVersionUID = 1L;
+	
+	Map map = null;
+	HttpServletRequest request;
+	
+	public PageData(HttpServletRequest request){
+		this.request = request;
+		Map properties = request.getParameterMap();
+		Map returnMap = new HashMap(); 
+		Iterator entries = properties.entrySet().iterator(); 
+		Entry entry;
+		String name = "";  
+		String value = "";  
+		while (entries.hasNext()) {
+			entry = (Entry) entries.next();
+			name = (String) entry.getKey(); 
+			Object valueObj = entry.getValue(); 
+			if(null == valueObj){ 
+				value = ""; 
+			}else if(valueObj instanceof String[]){ 
+				String[] values = (String[])valueObj;
+				for(int i=0;i<values.length;i++){ 
+					 value = values[i] + ",";
+				}
+				value = value.substring(0, value.length()-1); 
+			}else{
+				value = valueObj.toString(); 
+			}
+			returnMap.put(name, value); 
+		}
+		map = returnMap;
+	}
+	
+	public PageData() {
+		map = new HashMap();
+	}
+	
+	@Override
+	public Object get(Object key) {
+		Object obj = null;
+		if(map.get(key) instanceof Object[]) {
+			Object[] arr = (Object[])map.get(key);
+			obj = request == null ? arr:(request.getParameter((String)key) == null ? arr:arr[0]);
+		} else {
+			obj = map.get(key);
+		}
+		return obj;
+	}
+	
+	public String getString(Object key) {
+		return (String)get(key);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public Object put(Object key, Object value) {
+		return map.put(key, value);
+	}
+	
+	@Override
+	public Object remove(Object key) {
+		return map.remove(key);
+	}
+	@Override
+	public void clear() {
+		map.clear();
+	}
+	@Override
+	public boolean containsKey(Object key) {
+		// TODO Auto-generated method stub
+		return map.containsKey(key);
+	}
+	@Override
+	public boolean containsValue(Object value) {
+		// TODO Auto-generated method stub
+		return map.containsValue(value);
+	}
+	@Override
+	public Set entrySet() {
+		// TODO Auto-generated method stub
+		return map.entrySet();
+	}
+	@Override
+	public boolean isEmpty() {
+		// TODO Auto-generated method stub
+		return map.isEmpty();
+	}
+	@Override
+	public Set keySet() {
+		// TODO Auto-generated method stub
+		return map.keySet();
+	}
+	@Override
+	@SuppressWarnings("unchecked")
+	public void putAll(Map t) {
+		// TODO Auto-generated method stub
+		map.putAll(t);
+	}
+	@Override
+	public int size() {
+		// TODO Auto-generated method stub
+		return map.size();
+	}
+	@Override
+	public Collection values() {
+		// TODO Auto-generated method stub
+		return map.values();
+	}
+	
+}

+ 99 - 0
src/main/java/com/sooka/common/utils/PathUtil.java

@@ -0,0 +1,99 @@
+package com.sooka.common.utils;
+
+import java.io.File;
+
+/**
+ * new File("..\path\abc.txt") 中的三个方法获取路径的方法
+ * 1: getPath() 获取相对路径,例如   ..\path\abc.txt
+ * 2: getAbslutlyPath() 获取绝对路径,但可能包含 ".." 或 "." 字符,例如  D:\otherPath\..\path\abc.txt
+ * 3: getCanonicalPath() 获取绝对路径,但不包含 ".." 或 "." 字符,例如  D:\path\abc.txt
+ */
+public class PathUtil {
+	
+	private static String webRootPath;
+	private static String rootClassPath;
+	
+
+	public static String getPath(Class clazz) {
+		String path = clazz.getResource("").getPath();
+		return new File(path).getAbsolutePath();
+	}
+	
+	public static String getPath(Object object) {
+		String path = object.getClass().getResource("").getPath();
+		return new File(path).getAbsolutePath();
+	}
+	
+	// 注意:命令行返回的是命令行所在的当前路径
+	public static String getRootClassPath() {
+		if (rootClassPath == null) {
+			try {
+				String path = PathUtil.class.getClassLoader().getResource("").toURI().getPath();
+				rootClassPath = new File(path).getAbsolutePath();
+			}
+			catch (Exception e) {
+				String path = PathUtil.class.getClassLoader().getResource("").getPath();
+				rootClassPath = new File(path).getAbsolutePath();
+			}
+		}
+		return rootClassPath;
+	}
+	
+	public static void setRootClassPath(String rootClassPath) {
+		PathUtil.rootClassPath = rootClassPath;
+	}
+	
+	public static String getPackagePath(Object object) {
+		Package p = object.getClass().getPackage();
+		return p != null ? p.getName().replaceAll("\\.", "/") : "";
+	}
+	
+	public static File getFileFromJar(String file) {
+		throw new RuntimeException("Not finish. Do not use this method.");
+	}
+	
+	public static String getWebRootPath() {
+		if (webRootPath == null) {
+			webRootPath = detectWebRootPath();
+		}
+		return webRootPath;
+	}
+	
+	public static void setWebRootPath(String webRootPath) {
+		if (webRootPath == null) {
+			return ;
+		}
+		
+		if (webRootPath.endsWith(File.separator)) {
+			webRootPath = webRootPath.substring(0, webRootPath.length() - 1);
+		}
+		PathUtil.webRootPath = webRootPath;
+	}
+	
+	// 注意:命令行返回的是命令行所在路径的上层的上层路径
+	private static String detectWebRootPath() {
+		try {
+			String path = PathUtil.class.getResource("/").toURI().getPath();
+			return new File(path).getParentFile().getParentFile().getCanonicalPath();
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+	
+	public static boolean isAbsolutelyPath(String path) {
+		return path.startsWith("/") || path.indexOf(":") == 1;
+	}
+	
+	/*
+	private static String detectWebRootPath() {
+		try {
+			String path = PathKit.class.getResource("/").getFile();
+			return new File(path).getParentFile().getParentFile().getCanonicalPath();
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+	}
+	*/
+}
+
+

+ 118 - 0
src/main/java/com/sooka/common/utils/PinyinUtil.java

@@ -0,0 +1,118 @@
+package com.sooka.common.utils;
+
+import net.sourceforge.pinyin4j.PinyinHelper;
+import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
+import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
+import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
+import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
+import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
+import org.apache.commons.lang3.StringUtils;
+ 
+
+public class PinyinUtil{
+     
+    /**
+     * 转为大写字母, 如:中国人民银行 =====>ZHONGGUORENMINYINHAN
+     * @author lance
+     * 2016年1月16日 下午4:56:07
+     */
+    public static String convertUpper(String text){
+        return convert(text, HanyuPinyinCaseType.UPPERCASE, false);
+    }
+     
+    /**
+     * 转为小写字母, 如:中国人民银行 =====>zhongguorenminyinhang
+     * @author lance
+     * 2016年1月16日 下午4:56:07
+     */
+    public static String convertLower(String text){
+        return convert(text, HanyuPinyinCaseType.LOWERCASE, false);
+    }
+     
+    /**
+     * 首字母大写, 如:中国人民银行 =====>ZhongGuoRenMinYinHang
+     * @author lance
+     * 2016年1月16日 下午5:04:11
+     */
+    public static String converCapitalize(String text){
+        return convert(text, null, true);
+    }
+     
+    /**
+     * 所有中文的第一个字母大写, 如:中国人民银行 =====>ZGRMYH
+     * @author lance
+     * 2016年1月17日 下午10:16:19
+     */
+    public static String capitalizeLetter(String text){
+        String c = converCapitalize(text);
+        if(StringUtils.isBlank(c)) {
+            return "";
+        }
+         
+        return StringUtils.replacePattern(c, "[a-z]", "");
+    }
+     
+    /**
+     * 获取首字母, 如:中国人民银行 =====>Z
+     * @author lance
+     * 2016年1月17日 下午10:11:57
+     */
+    public static String firstLetter(String text){
+        String c = converCapitalize(text);
+        if(StringUtils.isBlank(c)) {
+            return "";
+        }
+         
+        return StringUtils.substring(c, 0, 1);
+    }
+     
+    /**
+     * 转为拼音
+     * @param text          待转化的中文字符
+     * @param caseType      转化类型, 即大写小写
+     * @param isCapitalize  是否首字母大写
+     * @author lance
+     * 2016年1月17日 下午10:28:05
+     */
+    public static String convert(String text, HanyuPinyinCaseType caseType, boolean isCapitalize) {
+        if(StringUtils.isBlank(text)){
+            return "";
+        }
+        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
+        if(caseType != null) {
+            format.setCaseType(caseType);
+            isCapitalize = false;
+        }
+         
+        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
+        format.setVCharType(HanyuPinyinVCharType.WITH_V);
+        char[] input = StringUtils.trimToEmpty(text).toCharArray();
+        StringBuilder builder = new StringBuilder();
+        try {
+            for (char c: input) {
+                if (Character.toString(c).matches("[\\u4E00-\\u9FA5]+")) {
+                    String[] temp = PinyinHelper.toHanyuPinyinStringArray(c, format);
+                    if(isCapitalize) {
+                        builder.append(StringUtils.capitalize(temp[0]));
+                    }else {
+                        builder.append(temp[0]);
+                    }
+                } else {
+                    if(isCapitalize) {
+                        builder.append(StringUtils.capitalize(Character.toString(c)));
+                    }else {
+                         builder.append(Character.toString(c));
+                    }
+                }
+            }
+        } catch (BadHanyuPinyinOutputFormatCombination ex) {
+            ex.printStackTrace();
+        }
+ 
+        return builder.toString();
+    }
+
+    public static  void main(String[] args){
+      System.out.print( convertLower("哈哈"));
+    }
+}

+ 78 - 0
src/main/java/com/sooka/common/utils/Pojo2MapUtil.java

@@ -0,0 +1,78 @@
+package com.sooka.common.utils;
+
+import com.google.common.collect.Maps;
+import com.sooka.mybatis.model.TCmsContent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * Description:pojo 转 map
+ *
+ *
+ * @create 2017-06-15
+ **/
+public class Pojo2MapUtil {
+
+    private static final Logger log = LoggerFactory.getLogger(Pojo2MapUtil.class);
+
+    public static Map<String, ?> toMap(Object o) throws Exception {
+        Map<String, Object> values = Maps.newHashMap();
+        BeanInfo info = Introspector.getBeanInfo(o.getClass());
+        log.debug(">>>>>>>>>> pojo to map [begin]");
+        for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
+            Method getter = pd.getReadMethod();
+            if (getter != null) {
+                log.debug(pd.getName() + "-->" + getter.invoke(o));
+                values.put(pd.getName(), getter.invoke(o));
+            }
+            else {
+                log.debug(">>>>>>>>>> null getter"+getter);
+            }
+        }
+        log.debug(">>>>>>>>>> pojo to map [end]");
+        return values;
+    }
+
+    public static <T> T toObj(Class<T> clazz, Map map)
+            throws IntrospectionException, IllegalAccessException,
+            InstantiationException, InvocationTargetException, ClassNotFoundException {
+        T obj = clazz.newInstance();
+        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
+        PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();
+        log.debug(">>>>>>>>>> map to  pojo [begin]");
+        for (int i = 0; i< propertyDescriptors.length; i++) {
+            PropertyDescriptor descriptor = propertyDescriptors[i];
+            String propertyName = descriptor.getName();
+
+            if (map.containsKey(propertyName)) {
+                Object value = map.get(propertyName);
+                Object[] args = new Object[1];
+                args[0] = value;
+                descriptor.getWriteMethod().invoke(obj, args);
+                log.debug(">>>>>>>>>> "+propertyName+ "==>" + map.get(propertyName));
+            }
+        }
+        log.debug(">>>>>>>>>> map to pojo [end]");
+        return obj;
+    }
+
+    public static void main(String[] args) throws Exception {
+        TCmsContent content = new TCmsContent();
+        content.setContentId(999999L);
+        content.setModelId(11111);
+        content.setUpdatedate(new Date());
+        Map m = toMap(content);
+        m.forEach((key,value)->
+          System.out.println(key+"-->>"+value)
+        );
+    }
+}

+ 38 - 0
src/main/java/com/sooka/common/utils/QiniuUtil.java

@@ -0,0 +1,38 @@
+package com.sooka.common.utils;
+
+import com.qiniu.common.Zone;
+import com.qiniu.http.Response;
+import com.qiniu.storage.Configuration;
+import com.qiniu.storage.UploadManager;
+import com.qiniu.util.Auth;
+import org.springframework.web.multipart.MultipartFile;
+
+public class QiniuUtil {
+
+    /**
+     * 七牛文件上传
+     * @param accessKey
+     * @param secretKey
+     * @param bucketname
+     * @param multipartFile
+     * @return
+     */
+    public static String upload(String accessKey, String secretKey, String bucketname, MultipartFile multipartFile){
+        Auth auth = Auth.create(accessKey, secretKey);
+        /* 七牛上传不能自动获取区域,只能手动设置 */
+        Zone z = Zone.zone0();
+        Configuration c = new Configuration(z);
+        UploadManager uploadManager = new UploadManager(c);
+        String result = null;
+        try {
+            Response res = uploadManager.put(multipartFile.getBytes(), StrUtil.getUUID()+"."+ StrUtil.getExtensionName(multipartFile.getOriginalFilename()), auth.uploadToken(bucketname));
+            result=res.bodyString();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+      return result;
+    }
+
+
+}

+ 50 - 0
src/main/java/com/sooka/common/utils/SmsUtil.java

@@ -0,0 +1,50 @@
+package com.sooka.common.utils;
+
+
+import com.alibaba.fastjson.JSONArray;
+import jodd.http.HttpRequest;
+import jodd.http.HttpResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SmsUtil {
+
+    private static final Logger log = LoggerFactory.getLogger(SmsUtil.class);
+
+    private static  final String url = "https://api.netease.im/sms/sendtemplate.action";
+    private static  final String appKey = "cc58c823717404e2bb009fb055f659cf";
+    private static  final String appSecret = "e4a1120b04c5";
+    private static  final String nonce =  "12345";
+
+    public static void sendTemplateMsg(String mobile,String templateId,String... params){
+
+        String curTime = String.valueOf((new Date()).getTime() / 1000L);
+        String checkSum = CheckSumUtil.getCheckSum(appSecret, nonce ,curTime);
+
+        JSONArray paramArray = new JSONArray();
+        for(String param : params){
+            paramArray.add(param);
+        }
+        Map<String,String> queryMap = new HashMap<>();
+        queryMap.put("templateid",templateId);
+        queryMap.put("mobiles","[\""+mobile+"\"]");
+        queryMap.put("params",paramArray.toJSONString());
+
+        HttpResponse response = HttpRequest
+                .post(url)
+                .header("charset","utf-8")
+                .header("contentType", "application/x-www-form-urlencoded")
+                .header("AppKey", appKey)
+                .header("Nonce", nonce)
+                .header("CurTime", curTime)
+                .header("CheckSum", checkSum)
+                .query(queryMap)
+                .send();
+        log.info(response.bodyText());
+    }
+
+}

+ 125 - 0
src/main/java/com/sooka/common/utils/StrUtil.java

@@ -0,0 +1,125 @@
+package com.sooka.common.utils;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+public class StrUtil {
+
+
+	/**
+	 * 判断字符串是否为空
+	 * @param str
+	 * @return
+	 */
+	public static boolean isBlank(String str) {
+
+		return str == null || str.length() <= 0;
+	}
+
+	/**
+	 * 替换中文逗号
+	 * @param content
+	 * @return
+	 */
+	public static String replace(String content) {
+		String word = content.replace(",", ",").trim();
+		return word;
+	}
+
+
+	/**
+	 * 获取文件扩展名
+	 * 
+	 * @param filename
+	 * @return
+	 */
+	public static String getExtensionName(String filename) {
+		if ((filename != null) && (filename.length() > 0)) {
+			int dot = filename.lastIndexOf('.');
+			if ((dot > -1) && (dot < (filename.length() - 1))) {
+				return filename.substring(dot + 1);
+			}
+		}
+		return filename;
+	}
+
+	/**
+	 *
+	 * 获取uuid
+	 *
+	 * @return
+	 */
+
+	public static String getUUID() {
+		UUID uuid = UUID.randomUUID();
+		return uuid.toString().replace("-", "");
+
+	}
+
+
+	/* 字符串数组排重 */
+	public static String[] excludeRepeatStr(String str){
+		if(StrUtil.isBlank(str)) {
+            return null;
+        }
+		String[] ss = str.replace(" ","").split(",");
+		Arrays.sort(ss);
+		Set<String> prodCodeSet = new HashSet<>();
+		prodCodeSet.addAll(Arrays.asList(ss));
+		ss = prodCodeSet.toArray(new String[]{});
+	  return ss;
+	}
+
+
+
+	public static  boolean isNotNumeric(String ...strs) {
+		for(String str:strs){
+			if(StringUtils.isNumeric(str)) {
+                return false;
+            }
+		}
+		return true;
+
+	}
+
+	public static  boolean isContain(String[] strs,String str) {
+	    if(CmsUtil.isNullOrEmpty(strs)) {
+            return false;
+        }
+	    for(String s:strs){
+	    	if(s.equals(str)) {
+                return  true;
+            }
+		}
+		return  false;
+
+	}
+
+	/*判断一个字符是否是中文*/
+	public static boolean isChinese(char c) {
+		return c >= 0x4E00 &&  c <= 0x9FA5;
+	}
+	/*判断一个字符串是否含有中文*/
+	public static boolean isChinese(String str) {
+		if (str == null) {
+            return false;
+        }
+		for (char c : str.toCharArray()) {
+			if (isChinese(c)) {
+                return true;
+            }
+		}
+		return false;
+	}
+
+	public static void  main(String args[]){
+//       System.out.println( excludeRepeatStr("1,2,1"));
+//		 System.out.println(isNotNumeric("0","46"));
+		String[] ss = {"1000","200"};
+		System.out.println(isContain(ss,"200"));
+	}
+}

+ 258 - 0
src/main/java/com/sooka/common/utils/Tools.java

@@ -0,0 +1,258 @@
+package com.sooka.common.utils;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Random;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Tools {
+	
+	/**
+	 * 随机生成六位数验证码 
+	 * @return
+	 */
+	public static int getRandomNum(){
+		 Random r = new Random();
+		//(Math.random()*(999999-100000)+100000)
+		 return r.nextInt(900000)+100000;
+	}
+	
+	/**
+	 * 检测字符串是否不为空(null,"","null")
+	 * @param s
+	 * @return 不为空则返回true,否则返回false
+	 */
+	public static boolean notEmpty(String s){
+		return s!=null && !"".equals(s) && !"null".equals(s);
+	}
+	
+	/**
+	 * 检测字符串是否为空(null,"","null")
+	 * @param s
+	 * @return 为空则返回true,不否则返回false
+	 */
+	public static boolean isEmpty(String s){
+		return s==null || "".equals(s) || "null".equals(s);
+	}
+	
+	/**
+	 * 字符串转换为字符串数组
+	 * @param str 字符串
+	 * @param splitRegex 分隔符
+	 * @return
+	 */
+	public static String[] str2StrArray(String str,String splitRegex){
+		if(isEmpty(str)){
+			return null;
+		}
+		return str.split(splitRegex);
+	}
+	
+	/**
+	 * 用默认的分隔符(,)将字符串转换为字符串数组
+	 * @param str	字符串
+	 * @return
+	 */
+	public static String[] str2StrArray(String str){
+		return str2StrArray(str,",\\s*");
+	}
+	
+	/**
+	 * 按照yyyy-MM-dd HH:mm:ss的格式,日期转字符串
+	 * @param date
+	 * @return yyyy-MM-dd HH:mm:ss
+	 */
+	public static String date2Str(Date date){
+		return date2Str(date,"yyyy-MM-dd HH:mm:ss");
+	}
+	
+	/**
+	 * 按照yyyy-MM-dd HH:mm:ss的格式,字符串转日期
+	 * @param date
+	 * @return
+	 */
+	public static Date str2Date(String date){
+		if(notEmpty(date)){
+			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+			try {
+				return sdf.parse(date);
+			} catch (ParseException e) {
+				e.printStackTrace();
+			}
+			return new Date();
+		}else{
+			return null;
+		}
+	}
+	
+	/**
+	 * 按照参数format的格式,日期转字符串
+	 * @param date
+	 * @param format
+	 * @return
+	 */
+	public static String date2Str(Date date,String format){
+		if(date!=null){
+			SimpleDateFormat sdf = new SimpleDateFormat(format);
+			return sdf.format(date);
+		}else{
+			return "";
+		}
+	}
+	
+	/**
+	 * 把时间根据时、分、秒转换为时间段
+	 * @param StrDate
+	 */
+	public static String getTimes(String StrDate){
+		String resultTimes = "";
+		
+		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+	    Date now;
+	    
+	    try {
+	    	now = new Date();
+	    	Date date=df.parse(StrDate);
+	    	long times = now.getTime()-date.getTime();
+	    	long day  =  times/(24*60*60*1000);
+	    	long hour = (times/(60*60*1000)-day*24);
+	    	long min  = ((times/(60*1000))-day*24*60-hour*60);
+	    	long sec  = (times/1000-day*24*60*60-hour*60*60-min*60);
+	        
+	    	StringBuffer sb = new StringBuffer();
+	    	//sb.append("发表于:");
+	    	if(hour>0 ){
+	    		sb.append(hour+"小时前");
+	    	} else if(min>0){
+	    		sb.append(min+"分钟前");
+	    	} else{
+	    		sb.append(sec+"秒前");
+	    	}
+	    		
+	    	resultTimes = sb.toString();
+	    } catch (ParseException e) {
+	    	e.printStackTrace();
+	    }
+	    
+	    return resultTimes;
+	}
+	
+	/**
+	 * 写txt里的单行内容
+	 * @param filePath  文件路径
+	 * @param content  写入的内容
+	 */
+	public static void writeFile(String fileP,String content){
+		String filePath = String.valueOf(Thread.currentThread().getContextClassLoader().getResource(""))+"../../";	//项目路径
+		filePath = (filePath.trim() + fileP.trim()).substring(6).trim();
+		if(filePath.indexOf(":") != 1){
+			filePath = File.separator + filePath;
+		}
+		try {
+	        OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(filePath),"utf-8");      
+	        BufferedWriter writer=new BufferedWriter(write);          
+	        writer.write(content);      
+	        writer.close(); 
+
+	        
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	/**
+	  * 验证邮箱
+	  * @param email
+	  * @return
+	  */
+	 public static boolean checkEmail(String email){
+	  boolean flag = false;
+	  try{
+	    String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
+	    Pattern regex = Pattern.compile(check);
+	    Matcher matcher = regex.matcher(email);
+	    flag = matcher.matches();
+	   }catch(Exception e){
+	    flag = false;
+	   }
+	  return flag;
+	 }
+	
+	 /**
+	  * 验证手机号码
+	  * @param mobiles
+	  * @return
+	  */
+	 public static boolean checkMobileNumber(String mobileNumber){
+	  boolean flag = false;
+	  try{
+	    Pattern regex = Pattern.compile("^(((13[0-9])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8})|(0\\d{2}-\\d{8})|(0\\d{3}-\\d{7})$");
+	    Matcher matcher = regex.matcher(mobileNumber);
+	    flag = matcher.matches();
+	   }catch(Exception e){
+	    flag = false;
+	   }
+	  return flag;
+	 }
+	 
+	/**
+	 * 检测KEY是否正确
+	 * @param paraname  传入参数
+	 * @param FKEY		接收的 KEY
+	 * @return 为空则返回true,不否则返回false
+	 */
+	public static boolean checkKey(String paraname, String FKEY){
+		paraname = (null == paraname)? "":paraname;
+		return MD5.md5(paraname+DateUtil.getDays()+",fh,").equals(FKEY);
+	}
+	 
+	/**
+	 * 读取txt里的单行内容
+	 * @param filePath  文件路径
+	 */
+	public static String readTxtFile(String fileP) {
+		try {
+			
+			String filePath = String.valueOf(Thread.currentThread().getContextClassLoader().getResource(""))+"../../";	//项目路径
+			filePath = filePath.replaceAll("file:/", "");
+			filePath = filePath.replaceAll("%20", " ");
+			filePath = filePath.trim() + fileP.trim();
+			if(filePath.indexOf(":") != 1){
+				filePath = File.separator + filePath;
+			}
+			String encoding = "utf-8";
+			File file = new File(filePath);
+			if (file.isFile() && file.exists()) { 		// 判断文件是否存在
+				InputStreamReader read = new InputStreamReader(
+				new FileInputStream(file), encoding);	// 考虑到编码格式
+				BufferedReader bufferedReader = new BufferedReader(read);
+				String lineTxt = null;
+				while ((lineTxt = bufferedReader.readLine()) != null) {
+					return lineTxt;
+				}
+				read.close();
+			}else{
+				System.out.println("找不到指定的文件,查看此路径是否正确:"+filePath);
+			}
+		} catch (Exception e) {
+			System.out.println("读取文件内容出错");
+		}
+		return "";
+	}
+	
+	
+	public static void main(String[] args) {
+		System.out.println(getRandomNum());
+	}
+	
+}

+ 22 - 0
src/main/java/com/sooka/common/utils/UserUtil.java

@@ -0,0 +1,22 @@
+package com.sooka.common.utils;
+
+import com.sooka.module.web.system.vo.UserVo;
+import com.sooka.common.constant.CmsConst;
+import org.apache.shiro.authz.UnauthenticatedException;
+
+/**
+ * Description:系统用户工具类
+ *
+ *
+ * @create 2017-05-31
+ **/
+public class UserUtil {
+
+    public static UserVo getSysUserVo() {
+        UserVo userVo =   ((UserVo) ControllerUtil.getHttpSession().getAttribute(CmsConst.SITE_USER_SESSION_KEY));
+        if(CmsUtil.isNullOrEmpty(userVo)) {
+            throw  new UnauthenticatedException();
+        }
+        return userVo;
+    }
+}

+ 151 - 0
src/main/java/com/sooka/component/beetl/BeetlConfiguration.java

@@ -0,0 +1,151 @@
+package com.sooka.component.beetl;
+
+
+import com.google.common.collect.Maps;
+import com.sooka.component.beetl.fun.*;
+import com.sooka.component.beetl.tag.ShiroTag;
+import org.beetl.core.Function;
+import org.beetl.core.GroupTemplate;
+import org.beetl.core.TagFactory;
+import org.beetl.core.resource.ClasspathResourceLoader;
+import org.beetl.ext.spring.BeetlGroupUtilConfiguration;
+import org.beetl.ext.spring.BeetlSpringViewResolver;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+public class BeetlConfiguration {
+
+
+    @Value("${system.site.name}")
+    private String siteName;
+
+    @Value("${system.dev.model}")
+    private String devModel;
+
+    @Value("${system.http.protocol}")
+    private String httpProtocol;
+
+    @Value("${system.http.host}")
+    private String host;
+
+    @Value("${system.site.prefix}")
+    private String sitePrefix;
+
+    @Value("${system.login.path}")
+    private String loginPath;
+
+    public Map<String,Object> sharedVars(){
+        Map<String,Object> sharedVars =  Maps.newHashMap();
+        sharedVars.put("siteName",siteName);
+        sharedVars.put("baseURL",httpProtocol+"://"+ host);
+        sharedVars.put("resPath",httpProtocol+"://"+ host+"/"+"static"+"/"+"www");
+        sharedVars.put("devModel",Boolean.valueOf(devModel));
+        sharedVars.put("adminLoginPath",loginPath);
+        sharedVars.put("sitePrefix",sitePrefix);
+        sharedVars.put("frontPath",httpProtocol+"://"+ host+"/"+sitePrefix);
+        return sharedVars;
+    }
+
+    public Map<String,Object> functionPackages(){
+        Map<String,Object> functionPackages = new HashMap<String,Object>();
+        functionPackages.put("shiro",new ShiroTag());
+        return functionPackages;
+    }
+
+    @Bean(name = "function")
+    public Map<String,Function> function(PermissionFunction permissionTag,
+                                         TreePermissionFunction permissionFunction,
+                                         TreeCategoryFunction categoryFunction,
+                                         SelectCategoryFunction selectCategoryFunction,
+                                         TreeContentCategoryFunction contentCategoryFunction,
+                                         SelectPermissionFunction selectPermissionOut,
+                                         ContentTreeCategoryFunction contentTreeCategoryFunction,
+                                         ContentSelectCategoryFunction contentSelectCategoryFunction,
+                                         TreeTopicCatagoryFunction treeTopicCatagoryFunction,
+                                         TreeOrganizationFunction treeOrganizationFunction,
+                                         SelectOrganizationFunction selectOrganizationFunction,
+                                         OrganizationFunction organizationFunction
+                                        ){
+        Map<String,Function> functionPackages = Maps.newHashMap();
+        /*打印时间*/
+        functionPackages.put("PrintTime",new PrintTimeFunction());
+        /*输出权限Checkbox*/
+        functionPackages.put("PermissionOut",permissionTag);
+        /*输出树形权限菜单*/
+        functionPackages.put("TreePermissionOut",permissionFunction);
+        /*输出树形分类菜单*/
+        functionPackages.put("TreeCategoryOut",categoryFunction);
+        /*内容添加页面输出树形分类菜单*/
+        functionPackages.put("TreeContentCategoryFunction",contentCategoryFunction);
+        /*输出权限HtmlSelect菜单*/
+        functionPackages.put("SelectPermissionOut",selectPermissionOut);
+        /*输出分类HtmlSelect菜单*/
+        functionPackages.put("SelectCategoryOut",selectCategoryFunction);
+        /*输出内容添加页面树形菜单*/
+        functionPackages.put("ContentCategoryOut",contentTreeCategoryFunction);
+        functionPackages.put("ContentSelectCategoryFunction",contentSelectCategoryFunction);
+        /*输出自定义模型字段类型名称*/
+        functionPackages.put("printModelFiledClass",new PrintModelFiledClassFunction());
+
+        functionPackages.put("TopicCatagoryOut",treeTopicCatagoryFunction);
+        functionPackages.put("TreeOrgOut",treeOrganizationFunction);
+        functionPackages.put("selectOrganizationOut",selectOrganizationFunction);
+        functionPackages.put("organizationOut",organizationFunction);
+
+
+        return functionPackages;
+    }
+
+    @Bean(initMethod = "init", name = "beetlConfig")
+    public BeetlGroupUtilConfiguration getbeetlConfig(@Qualifier("function")Map<String,Function> function,
+                                                      @Qualifier("tagFactory")Map<String,TagFactory> tagFactory) {
+
+        BeetlGroupUtilConfiguration beetlGroupUtilConfiguration = new BeetlGroupUtilConfiguration();
+        ResourcePatternResolver patternResolver = ResourcePatternUtils.getResourcePatternResolver(new DefaultResourceLoader());
+        try {
+            ClasspathResourceLoader classpathResourceLoader = new ClasspathResourceLoader(BeetlConfiguration.class.getClassLoader(), "templates/");
+            beetlGroupUtilConfiguration.setConfigFileResource(patternResolver.getResource("classpath:beetl.properties"));
+            beetlGroupUtilConfiguration.setResourceLoader(classpathResourceLoader);
+            beetlGroupUtilConfiguration.setFunctionPackages(functionPackages());
+            beetlGroupUtilConfiguration.setSharedVars(sharedVars());
+            beetlGroupUtilConfiguration.setFunctions(function);
+            beetlGroupUtilConfiguration.setTagFactorys(tagFactory);
+//            beetlGroupUtilConfiguration.setErrorHandler(new BeetlWebErrorHandler());
+            return beetlGroupUtilConfiguration;
+
+        } catch (Exception e) {
+
+            throw new RuntimeException(e);
+
+        }
+    }
+
+
+
+    @Bean(name = "beetlViewResolver")
+    public BeetlSpringViewResolver getBeetlSpringViewResolver(@Qualifier(value = "beetlConfig") BeetlGroupUtilConfiguration beetlGroupUtilConfiguration) {
+        BeetlSpringViewResolver beetlSpringViewResolver = new BeetlSpringViewResolver();
+        beetlSpringViewResolver.setContentType("text/html;charset=UTF-8");
+        beetlSpringViewResolver.setOrder(0);
+        beetlSpringViewResolver.setSuffix(".html");
+        beetlSpringViewResolver.setConfig(beetlGroupUtilConfiguration);
+        return beetlSpringViewResolver;
+    }
+
+    @Bean(name = "groupTemplate")
+    public GroupTemplate getGroupTemplate(
+            @Qualifier("beetlConfig") BeetlGroupUtilConfiguration beetlGroupUtilConfiguration) {
+        return beetlGroupUtilConfiguration.getGroupTemplate();
+
+    }
+
+}

+ 37 - 0
src/main/java/com/sooka/component/beetl/BeetlWebErrorHandler.java

@@ -0,0 +1,37 @@
+package com.sooka.component.beetl;
+
+import com.sooka.common.utils.CmsUtil;
+import org.beetl.core.ConsoleErrorHandler;
+import org.beetl.core.exception.BeetlException;
+import org.beetl.core.exception.ErrorInfo;
+
+import java.io.IOException;
+import java.io.Writer;
+
+public class BeetlWebErrorHandler extends ConsoleErrorHandler {
+
+
+	@Override
+	public void processExcption(BeetlException ex, Writer writer) {
+		ErrorInfo err = new ErrorInfo(ex);
+		StringBuffer content = new StringBuffer();
+		content.append("<!DOCTYPE html>");
+		content.append("<html>");
+		content.append("<head>");
+		content.append("<meta charset=\"UTF-8\">");
+		content.append("<title>模板解析错误</title>");
+		content.append("</head>");
+		content.append("<body>");
+		content.append("<p style=\"font-size:22px;padding-left:10px;\"><b>"+err.getType()+"</b></p>");
+		content.append("<p style=\"font-size:18px;padding-left:10px;\">描述 : " + (!CmsUtil.isNullOrEmpty(err.getMsg())?err.getMsg():"上面信息已经很详细 :)") + (CmsUtil.isNullOrEmpty(err.getCause())?"":"( "+err.getCause() +" )")+" </p>");
+        content.append("<p style=\"font-size:18px;padding-left:10px;\">位置 : " +err.getResourceCallStack()+" ~ 第"+ err.getErrorTokenLine() + "行</p>");
+		content.append("</body>");
+		content.append("</html>");
+		try {
+			writer.write(content.toString());
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+}

+ 68 - 0
src/main/java/com/sooka/component/beetl/format/DateFormat.java

@@ -0,0 +1,68 @@
+package com.sooka.component.beetl.format;
+
+import org.beetl.core.Format;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+public class DateFormat implements Format {
+
+    private ThreadLocal<Map<String, SimpleDateFormat>> threadlocal = new ThreadLocal();
+
+    public DateFormat() {
+    }
+
+    @Override
+    public Object format(Object data, String pattern) {
+        if (data == null) {
+            return null;
+        } else {
+            Date date;
+            if (Date.class.isAssignableFrom(data.getClass())) {
+                SimpleDateFormat date1;
+                if (pattern == null) {
+                    date1 = this.getDateFormat("default");
+                } else {
+                    date1 = this.getDateFormat(pattern);
+                }
+
+                return date1.format((Date) data);
+            } else if (data.getClass() == Long.class) {
+                date = new Date(((Long) data).longValue());
+                SimpleDateFormat sdf;
+                if (pattern == null) {
+                    sdf = this.getDateFormat("default");
+                } else {
+                    sdf = this.getDateFormat(pattern);
+                }
+
+                return sdf.format(date);
+            } else {
+                return data;
+            }
+        }
+    }
+
+    private SimpleDateFormat getDateFormat(String pattern) {
+        Object map;
+        if ((map = this.threadlocal.get()) == null) {
+            map = new HashMap(4, 0.65F);
+            this.threadlocal.set((Map<String, SimpleDateFormat>) map);
+        }
+
+        SimpleDateFormat format = (SimpleDateFormat) ((Map) map).get(pattern);
+        if (format == null) {
+            if ("default".equals(pattern)) {
+                format = new SimpleDateFormat();
+            } else {
+                format = new SimpleDateFormat(pattern);
+            }
+
+            ((Map) map).put(pattern, format);
+        }
+
+        return format;
+    }
+}

+ 45 - 0
src/main/java/com/sooka/component/beetl/format/XSSDefenseFormat.java

@@ -0,0 +1,45 @@
+package com.sooka.component.beetl.format;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.beetl.core.Format;
+import org.owasp.validator.html.*;
+
+public class XSSDefenseFormat implements Format {
+
+    @Override
+    public Object format(Object data, String pattern) {
+        if (null == data) {
+            return null;
+        } else {
+
+            try {
+                if(data instanceof String) {
+                    Policy policy = Policy.getInstance(getClass().getResourceAsStream("/antisamy.xml"));
+                    AntiSamy as = new AntiSamy(policy);
+
+                    String content = (String) data;
+                    if ("escape".equals(pattern)) {
+                        content = StringEscapeUtils.escapeHtml(content);
+                    }
+                    CleanResults cr = as.scan(content);
+                    content = cr.getCleanHTML();
+                    return content;
+                }
+                return data;
+
+            } catch (ScanException e) {
+                return "系统错误";
+            } catch (PolicyException e) {
+                return "系统错误";
+            }
+
+        }
+    }
+
+    public static void main(String[] args){
+        String js =  "中文<script>hi</script><h5></h5>";
+        System.out.println(js);
+        js = (String) new XSSDefenseFormat().format(js, "escape");
+        System.out.println(js);
+    }
+}

+ 65 - 0
src/main/java/com/sooka/component/beetl/fun/ContentSelectCategoryFunction.java

@@ -0,0 +1,65 @@
+package com.sooka.component.beetl.fun;
+
+import com.sooka.mybatis.model.TCmsCategory;
+import com.sooka.common.utils.StrUtil;
+import com.sooka.module.web.cms.service.CategoryService;
+import org.beetl.core.Context;
+import org.beetl.core.Function;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class ContentSelectCategoryFunction implements Function{
+
+    @Autowired
+    private CategoryService service;
+
+    @Override
+    public Object call(Object[] objects, Context context) {
+
+
+        Integer siteId = Integer.parseInt(objects[0].toString()); /*站点Id*/
+        Long currentId =Long.parseLong(objects[1].toString()); /*当前栏目Id*/
+        return recursion(currentId, 0L,"",siteId);
+    }
+
+
+
+    /*递归输出子节点*/
+    private String recursion(Long cid,Long  pid,String tag,Integer siteId){
+         /*临时拼凑看不懂就放弃*/
+        tag+=(StrUtil.isBlank(tag)?"&nbsp;&nbsp;":"&nbsp;&nbsp;&nbsp;&nbsp;");
+        StringBuffer sbf = new StringBuffer();
+        List<TCmsCategory> ctas  = service.findCategoryListByPid(pid,siteId);
+        if(ctas!=null&&ctas.size()>0){
+            String tagMaker = "";
+            for(TCmsCategory cat:ctas){
+                if (ctas.lastIndexOf(cat) == (ctas.size()-1)){
+                    tagMaker="└";
+                }else {
+                     tagMaker="├";
+                }
+
+                int childSize = service.findCategoryListByPid(cat.getCategoryId(),siteId).size();
+                if((cat.getAlone()||!StrUtil.isBlank(cat.getUrl()))&&childSize==0) {
+                    continue;
+                }
+                if(childSize>0) {
+                    sbf.append("<optgroup label=\""+tagMaker + cat.getCategoryName() + "\">");
+                    sbf.append(recursion(cid,cat.getCategoryId(),tag,siteId));
+                    sbf.append("</optgroup>");
+                }else {
+                    if (cid.longValue() == cat.getCategoryId().longValue()) {
+                        sbf.append("<option value=\"" + cat.getCategoryId() + "\" selected='selected' >" + tag + "&nbsp;"+tagMaker + cat.getCategoryName() + "</option>");
+                    }else {
+                        sbf.append("<option value=\"" + cat.getCategoryId() + "\" >" + tag + "&nbsp;"+tagMaker  + cat.getCategoryName() + "</option>");
+                    }
+                }
+            }
+            return  sbf.toString();
+        }
+        return "";
+    }
+}

+ 64 - 0
src/main/java/com/sooka/component/beetl/fun/ContentTreeCategoryFunction.java

@@ -0,0 +1,64 @@
+package com.sooka.component.beetl.fun;
+
+import com.sooka.mybatis.model.TCmsCategory;
+import com.sooka.common.utils.ControllerUtil;
+import com.sooka.common.utils.StrUtil;
+import com.sooka.module.web.cms.service.CategoryService;
+import org.beetl.core.Context;
+import org.beetl.core.Function;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Description:content页面输出分类栏目
+ *
+ *
+ * @create 2017-04-15
+ **/
+@Service
+public class ContentTreeCategoryFunction implements Function{
+
+    @Autowired
+    private CategoryService service;
+
+    @Value("${system.http.protocol}")
+    private String httpProtocol;
+
+    private String url = "/system/cms/category/input?id";
+
+    @Override
+    public Object call(Object[] objects, Context context) {
+
+        Long pid = Long.parseLong(objects[0].toString());
+        Integer siteId = Integer.parseInt(objects[1].toString());
+        if(objects[2]!=null&&!StrUtil.isBlank(objects[2].toString())) {
+            this.url=objects[2].toString();
+        }
+        return recursion(pid,siteId);
+    }
+
+    /* 递归函数 */
+    private String recursion(Long pid,Integer siteId){
+       StringBuffer sbf = new StringBuffer();
+       List<TCmsCategory> cats  = service.findCategoryListByPid(pid,siteId);
+       if(cats!=null&&cats.size()>0){
+           for(TCmsCategory cat:cats){
+               int childSize = service.findCategoryListByPid(cat.getCategoryId(),siteId).size();
+               if((cat.getAlone()||!StrUtil.isBlank(cat.getUrl()))&&childSize==0) {
+                   continue;
+               }
+               if(childSize>0) {
+                   sbf.append("  <li data-id=\"" + cat.getCategoryId() + "\" data-pid=\"" + pid + "\" >" + cat.getCategoryName() + " [" + cat.getCategoryId() + "] </li>");
+               }else {
+                   sbf.append("  <li data-id=\"" + cat.getCategoryId() + "\" data-pid=\"" + pid + "\" data-url=\"" + httpProtocol+"://"+ ControllerUtil.getDomain()+url + "=" + cat.getCategoryId() + "\" data-divid=\"#layout-content\">" + cat.getCategoryName() + " [" + cat.getCategoryId() + "] </li>");
+               }
+               sbf.append(recursion(cat.getCategoryId(),siteId));
+           }
+           return  sbf.toString();
+       }
+       return "";
+    }
+}

+ 74 - 0
src/main/java/com/sooka/component/beetl/fun/OrganizationFunction.java

@@ -0,0 +1,74 @@
+package com.sooka.component.beetl.fun;
+
+import com.sooka.module.web.system.service.OrganizationService;
+import com.sooka.mybatis.model.TSysOrg;
+import org.beetl.core.Context;
+import org.beetl.core.Function;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Description:权限tag
+ * 这个函数需要调用时遍历使用
+ *
+ * @create 2017-04-14
+ **/
+@Service
+public class OrganizationFunction implements Function {
+
+    @Autowired
+    private OrganizationService service;
+
+    private final String isChecked = " data-checked='true' ";
+
+    @Override
+    public Object call(Object[] objects, Context context) {
+
+        /*父节点Id*/
+        Integer pid = (Integer) objects[0];
+         /*角色Id*/
+        Integer userId = (Integer) objects[1];
+
+        List<TSysOrg> orgList = service.findByPid(pid);
+        TSysOrg tso=service.findById(pid);
+        if(orgList!=null&&orgList.size()>0) {
+            StringBuffer sbf = new StringBuffer();
+            sbf.append("<li data-id='"+tso.getId()+"' data-pid='"+tso.getPid()+"'"+isChecked(pid,userId)+">"+tso.getName()+"</li>");
+            for (TSysOrg o : orgList) {
+                sbf.append("<li data-id='"+o.getId()+"' data-pid='"+o.getPid()+"' "+isChecked(o.getId(),userId)+">"+o.getName()+"</li>");
+                sbf.append(subPermission(o.getId(),userId));
+            }
+            return sbf.toString();
+        }else{
+            return "<li data-id='"+tso.getId()+"' data-pid='"+tso.getPid()+"'"+isChecked(pid,userId)+">"+tso.getName()+"</li>";
+        }
+
+    }
+
+    /**
+     * 递归查询子节点
+     * @param pid
+     * @param userId
+     * @return
+     */
+    public String subPermission(Integer pid,Integer userId){
+        StringBuffer sbf = new StringBuffer();
+        List<TSysOrg> orgList = service.findByPid(pid);
+        for (TSysOrg o : orgList) {
+            sbf.append("<li data-id='"+o.getId()+"' data-pid='"+o.getPid()+"' "+isChecked(o.getId(),userId)+">"+o.getName()+"</li>");
+            sbf.append(subPermission(o.getId(),userId));
+        }
+
+        return sbf.toString();
+    }
+
+
+    public String isChecked(Integer orgId,Integer userId){
+        if(service.findCountByOrgIdAndUserId(orgId,userId)>0) {
+            return isChecked;
+        }
+        return "";
+    }
+}

+ 79 - 0
src/main/java/com/sooka/component/beetl/fun/PermissionFunction.java

@@ -0,0 +1,79 @@
+package com.sooka.component.beetl.fun;
+
+import com.sooka.module.web.system.service.RoleService;
+import com.sooka.mybatis.model.TSysPermission;
+import org.beetl.core.Context;
+import org.beetl.core.Function;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Description:权限tag
+ * 这个函数需要调用时遍历使用
+ *
+ * @create 2017-04-14
+ **/
+@Service
+public class PermissionFunction implements Function {
+
+    @Autowired
+    private RoleService service;
+
+    private final String isChecked = " data-checked='true' ";
+
+    @Override
+    public Object call(Object[] objects, Context context) {
+
+        /*父节点Id*/
+        Integer pid = (Integer) objects[0];
+         /*角色Id*/
+        Integer roleId = (Integer) objects[1];
+
+        List<TSysPermission> permissions = service.findPermissonByPid(pid);
+        TSysPermission tsp=service.findPermissonByid(pid);
+        if(permissions!=null&&permissions.size()>0) {
+            StringBuffer sbf = new StringBuffer();
+            sbf.append("<li data-id='"+tsp.getPermissionId()+"' data-pid='"+tsp.getPid()+"'"+isChecked(pid,roleId)+">"+tsp.getDescription()+"</li>");
+            for (TSysPermission p : permissions) {
+                sbf.append("<li data-id='"+p.getPermissionId()+"' data-pid='"+p.getPid()+"' "+isChecked(p.getPermissionId(),roleId)+">"+p.getDescription()+"</li>");
+                sbf.append(subPermission(p.getPermissionId(),roleId));
+            }
+            return sbf.toString();
+        }else{
+            return "<li data-id='"+tsp.getPermissionId()+"' data-pid='"+tsp.getPid()+"'"+isChecked(pid,roleId)+">"+tsp.getDescription()+"</li>";
+        }
+
+    }
+
+    /**
+     * 递归查询子节点
+     * @param pid
+     * @param roleId
+     * @return
+     */
+    public String subPermission(Integer pid,Integer roleId){
+        StringBuffer sbf = new StringBuffer();
+        List<TSysPermission> permissions = service.findPermissonByPid(pid);
+        for (TSysPermission p : permissions) {
+            sbf.append("<li data-id='"+p.getPermissionId()+"' data-pid='"+p.getPid()+"' "+isChecked(p.getPermissionId(),roleId)+">"+p.getDescription()+"</li>");
+            sbf.append(subPermission(p.getPermissionId(),roleId));
+        }
+
+        return sbf.toString();
+    }
+
+    /**
+     * 判断是否用于权限
+     * @param permissionId
+     * @param roleId
+     * @return
+     */
+    public String isChecked(Integer permissionId,Integer roleId){
+        if(service.findPermissionCountByRoleId(roleId,permissionId)>0) {
+            return isChecked;
+        }
+        return "";
+    }
+}

+ 35 - 0
src/main/java/com/sooka/component/beetl/fun/PrintModelFiledClassFunction.java

@@ -0,0 +1,35 @@
+package com.sooka.component.beetl.fun;
+
+import com.sooka.common.db.kit.DbTableKit;
+import org.beetl.core.Context;
+import org.beetl.core.Function;
+
+/**
+ * Description:输出字段类型名称
+ *
+ *
+ * @create 2017-05-12
+ **/
+public class PrintModelFiledClassFunction implements Function {
+
+    @Override
+    public Object call(Object[] objects, Context context) {
+        if (objects.length != 1){
+            throw new RuntimeException("length of params must be 1 !");
+        }
+        if (objects[0].toString().length()!=0) {
+            String var = (String) objects[0];
+            for (String val : DbTableKit.MODEL_FILED_CLASS) {
+                String[] tmp = val.split("#");
+                System.out.println(tmp);
+                if (tmp[0].equals(var)) {
+                    return  tmp[1];
+                }
+                continue;
+            }
+        }
+        return null;
+    }
+
+
+}

+ 46 - 0
src/main/java/com/sooka/component/beetl/fun/PrintTimeFunction.java

@@ -0,0 +1,46 @@
+package com.sooka.component.beetl.fun;
+import org.beetl.core.Context;
+import org.beetl.core.Function;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+
+public class PrintTimeFunction implements Function {
+
+    private final static SimpleDateFormat TIME_STAMP_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    private final static SimpleDateFormat MY_DATE_FORMAT = new SimpleDateFormat("yyyy年MM月dd日");
+
+    @Override
+    public String call(Object[] params, Context context) {
+        if (params.length != 1){
+            throw new RuntimeException("length of params must be 1 !");
+        }
+        if (params[0].toString().length()==0){
+            return null;
+        }
+    
+        return getNiceDate((Date)params[0]);
+    }
+
+    public static String getNiceDate( Date date) {
+        if (null == date) {
+            return "";
+        }
+        String result = null;
+        long currentTime = System.currentTimeMillis() - date.getTime();
+        int time = (int)(currentTime / 1000);
+        if(time < 60) {
+            result = "刚刚";
+        } else if(time >= 60 && time < 3600) {
+            result = time/60 + "分钟前";
+        } else if(time >= 3600 && time < 86400) {
+            result = time/3600 + "小时前";
+        } else if(time >= 86400 && time < 864000) {
+            result = time/86400 + "天前";
+        } else{
+            result = MY_DATE_FORMAT.format(date);
+        }
+        return result;
+    }
+}

+ 68 - 0
src/main/java/com/sooka/component/beetl/fun/SelectCategoryFunction.java

@@ -0,0 +1,68 @@
+package com.sooka.component.beetl.fun;
+
+import com.sooka.mybatis.model.TCmsCategory;
+import com.sooka.common.utils.StrUtil;
+import com.sooka.module.web.cms.service.CategoryService;
+import org.beetl.core.Context;
+import org.beetl.core.Function;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class SelectCategoryFunction implements Function{
+
+    @Autowired
+    private CategoryService service;
+
+    private final String head = "<option value=\"0\" >顶级节点</option>";
+
+    private final String isSelected = "selected=\"selected\"";
+
+    @Override
+    public Object call(Object[] objects, Context context) {
+
+        Long pid = Long.parseLong(objects[0].toString());
+        Long currentId =Long.parseLong(objects[1].toString());
+        Integer siteId =Integer.parseInt(objects[2].toString());
+        if(pid!=null) {
+            return head+recursion(currentId,pid, 0L,"",siteId);
+        }
+        return head+recursion(currentId, 0L, 0L,"",siteId);
+    }
+
+
+
+    /*递归输出子节点*/
+    private String recursion(Long cid,Long pid,Long sPid,String tag,Integer siteId){
+         /*临时拼凑看不懂就放弃*/
+        tag+=(StrUtil.isBlank(tag)?"&nbsp;&nbsp;":"&nbsp;&nbsp;&nbsp;&nbsp;");
+        StringBuffer sbf = new StringBuffer();
+        List<TCmsCategory> ctas  = service.findCategoryListByPid(sPid,siteId);
+        if(ctas!=null&&ctas.size()>0){
+            for(TCmsCategory cat:ctas){
+
+                   /*如果是自己就不输出了*/
+                   if(cid.intValue()!=cat.getCategoryId().intValue()&&cid.intValue()!=cat.getParentId().intValue()||cid.intValue()==0) {
+                       if (ctas.lastIndexOf(cat) == (ctas.size()-1)) {
+                           sbf.append("<option value=\"" + cat.getCategoryId() + "\" " + isSelected(cat.getCategoryId(), pid) + ">" + tag + "└" + cat.getCategoryName() + "</option>");
+                       }else{
+                           sbf.append("<option value=\"" + cat.getCategoryId() + "\" " + isSelected(cat.getCategoryId(), pid) + ">" + tag + "├" + cat.getCategoryName() + "</option>");
+                       }
+                   }
+                   sbf.append(recursion(cid,pid,cat.getCategoryId(),tag,siteId));
+            }
+            return  sbf.toString();
+        }
+        return "";
+    }
+
+    private String isSelected(Long id,Long perId){
+        if(id.longValue()==perId.longValue()) {
+            return isSelected;
+        }
+        return "";
+    }
+
+}

+ 72 - 0
src/main/java/com/sooka/component/beetl/fun/SelectOrganizationFunction.java

@@ -0,0 +1,72 @@
+package com.sooka.component.beetl.fun;
+
+import com.sooka.module.web.system.service.OrganizationService;
+import com.sooka.common.utils.StrUtil;
+import com.sooka.mybatis.model.TSysOrg;
+import org.beetl.core.Context;
+import org.beetl.core.Function;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Description:select
+ *
+ *
+ * @create 2017-04-15
+ **/
+@Service
+public class SelectOrganizationFunction implements Function{
+
+    @Autowired
+    private OrganizationService service;
+
+    private final String head = "<option value=\"0\" >顶级节点</option>";
+
+    private final String isSelected = "selected=\"selected\"";
+
+    @Override
+    public Object call(Object[] objects, Context context) {
+
+        Integer pid = (Integer)objects[0];
+        Integer currentId = (Integer)objects[1];
+        if(pid!=null) {
+            return head+recursion(currentId,pid,0,"");
+        }
+        return head+recursion(currentId,0,0,"");
+    }
+
+
+
+    /*递归输出子节点*/
+    private String recursion(Integer cid,Integer pid,Integer spid,String tag){
+
+        tag+=(StrUtil.isBlank(tag)?"&nbsp;&nbsp;":"&nbsp;&nbsp;&nbsp;&nbsp;");
+        StringBuffer sbf = new StringBuffer();
+        List<TSysOrg> orgList  = service.findByPid(spid);
+        if(orgList!=null&&orgList.size()>0){
+            int flag_ = 0;
+            for(TSysOrg org:orgList){
+                   /**如果是自己就不输出了**/
+                if(cid.intValue()!=org.getId().intValue()&&cid.intValue()!=org.getPid().intValue()||cid.intValue()==0) {
+                    flag_ = org.getId().intValue();
+                    sbf.append("<option value=\"" + org.getId() + "\" " + isSelected(org.getId().intValue(), pid) + ">" + tag + "|—" + org.getName() + "</option>");
+                }
+                if(flag_!=0) {
+                    sbf.append(recursion(cid,pid,org.getId(),tag));
+                }
+            }
+            return  sbf.toString();
+        }
+        return "";
+    }
+
+    private String isSelected(Integer id,Integer perId){
+        if(id.intValue()==perId.intValue()) {
+            return isSelected;
+        }
+        return "";
+    }
+
+}

+ 72 - 0
src/main/java/com/sooka/component/beetl/fun/SelectPermissionFunction.java

@@ -0,0 +1,72 @@
+package com.sooka.component.beetl.fun;
+
+import com.sooka.module.web.system.service.RoleService;
+import com.sooka.mybatis.model.TSysPermission;
+import com.sooka.common.utils.StrUtil;
+import org.beetl.core.Context;
+import org.beetl.core.Function;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Description:select
+ *
+ *
+ * @create 2017-04-15
+ **/
+@Service
+public class SelectPermissionFunction implements Function{
+
+    @Autowired
+    private RoleService service;
+
+    private final String head = "<option value=\"0\" >顶级节点</option>";
+
+    private final String isSelected = "selected=\"selected\"";
+
+    @Override
+    public Object call(Object[] objects, Context context) {
+
+        Integer pid = (Integer)objects[0];
+        Integer currentId = (Integer)objects[1];
+        if(pid!=null) {
+            return head+recursion(currentId,pid,0,"");
+        }
+        return head+recursion(currentId,0,0,"");
+    }
+
+
+
+    /*递归输出子节点*/
+    private String recursion(int cid,int pid,int spid,String tag){
+
+        tag+=(StrUtil.isBlank(tag)?"&nbsp;&nbsp;":"&nbsp;&nbsp;&nbsp;&nbsp;");
+        StringBuffer sbf = new StringBuffer();
+        List<TSysPermission> permissions  = service.findPermissonByPid(spid);
+        if(permissions!=null&&permissions.size()>0){
+            int flag_ = 0;
+            for(TSysPermission per:permissions){
+                   /**如果是自己就不输出了**/
+                if(cid!=per.getPermissionId()&&cid!=per.getPid()||cid==0) {
+                    flag_ = per.getPermissionId();
+                    sbf.append("<option value=\"" + per.getPermissionId() + "\" " + isSelected(per.getPermissionId(), pid) + ">" + tag + "|—" + per.getDescription() + "</option>");
+                }
+                if(flag_!=0) {
+                    sbf.append(recursion(cid,pid,per.getPermissionId(),tag));
+                }
+            }
+            return  sbf.toString();
+        }
+        return "";
+    }
+
+    private String isSelected(Integer id,Integer perId){
+        if(id.intValue()==perId.intValue()) {
+            return isSelected;
+        }
+        return "";
+    }
+
+}

+ 50 - 0
src/main/java/com/sooka/component/beetl/fun/TreeCategoryFunction.java

@@ -0,0 +1,50 @@
+package com.sooka.component.beetl.fun;
+
+import com.sooka.mybatis.model.TCmsCategory;
+import com.sooka.common.utils.ControllerUtil;
+import com.sooka.module.web.cms.service.CategoryService;
+import org.beetl.core.Context;
+import org.beetl.core.Function;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Description:输出子权限节点函数
+ *
+ *
+ * @create 2017-04-15
+ **/
+@Service
+public class TreeCategoryFunction implements Function{
+
+    @Autowired
+    private CategoryService service;
+
+    @Value("${system.http.protocol}")
+    private String httpProtocol;
+
+    @Override
+    public Object call(Object[] objects, Context context) {
+
+        Long pid = Long.parseLong(objects[0].toString());
+        Integer siteId = Integer.parseInt(objects[1].toString());
+        return recursion(pid,siteId);
+    }
+
+    /* 递归函数 */
+    private String recursion(Long pid,Integer siteId){
+       StringBuffer sbf = new StringBuffer();
+       List<TCmsCategory> cats  = service.findCategoryListByPid(pid,siteId);
+       if(cats!=null&&cats.size()>0){
+           for(TCmsCategory cat:cats){
+               sbf.append("  <li data-id=\""+cat.getCategoryId()+"\" data-pid=\""+pid+"\" data-url=\""+httpProtocol+"://"+ ControllerUtil.getDomain()+"/system/cms/category/input?id="+cat.getCategoryId()+"\" data-divid=\"#layout-11\">"+cat.getCategoryName()+" ["+cat.getCategoryId()+"] </li>");
+               sbf.append(recursion(cat.getCategoryId(),siteId));
+           }
+           return  sbf.toString();
+       }
+       return "";
+    }
+}

+ 49 - 0
src/main/java/com/sooka/component/beetl/fun/TreeContentCategoryFunction.java

@@ -0,0 +1,49 @@
+package com.sooka.component.beetl.fun;
+
+import com.sooka.mybatis.model.TCmsCategory;
+import com.sooka.common.utils.ControllerUtil;
+import com.sooka.module.web.cms.service.CategoryService;
+import org.beetl.core.Context;
+import org.beetl.core.Function;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Description:输出子权限节点函数
+ *
+ *
+ * @create 2017-04-15
+ **/
+@Service
+public class TreeContentCategoryFunction implements Function{
+
+    @Autowired
+    private CategoryService service;
+
+    @Value("${system.http.protocol}")
+    private String httpProtocol;
+
+    @Override
+    public Object call(Object[] objects, Context context) {
+
+        Long pid = Long.parseLong(objects[0].toString());
+        return recursion(pid);
+    }
+
+    /* 递归函数 */
+    private String recursion(Long pid){
+       StringBuffer sbf = new StringBuffer();
+       List<TCmsCategory> cats  = service.findCategoryListByPid(pid);
+       if(cats!=null&&cats.size()>0){
+           for(TCmsCategory cat:cats){
+               sbf.append("  <li data-id=\""+cat.getCategoryId()+"\" data-pid=\""+pid+"\" data-url=\""+httpProtocol+"://"+ ControllerUtil.getDomain()+"/system/cms/content/input?id="+cat.getCategoryId()+"\" data-divid=\"#layout-11\">"+cat.getCategoryName()+"</li>");
+               sbf.append(recursion(cat.getCategoryId()));
+           }
+           return  sbf.toString();
+       }
+       return "";
+    }
+}

+ 51 - 0
src/main/java/com/sooka/component/beetl/fun/TreeOrganizationFunction.java

@@ -0,0 +1,51 @@
+package com.sooka.component.beetl.fun;
+
+import com.sooka.module.web.system.service.OrganizationService;
+import com.sooka.common.utils.ControllerUtil;
+import com.sooka.mybatis.model.TSysOrg;
+import org.beetl.core.Context;
+import org.beetl.core.Function;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Description:输出子权限节点函数
+ *
+ *
+ * @create 2017-04-15
+ **/
+@Service
+public class TreeOrganizationFunction implements Function{
+
+    @Autowired
+    private OrganizationService service;
+
+    @Value("${system.http.protocol}")
+    private String httpProtocol;
+
+    @Override
+    public Object call(Object[] objects, Context context) {
+
+        Integer pid = Integer.parseInt((String) objects[0]);
+        String url = (String) objects[1];
+        String layout = (String) objects[2];
+        return recursion(pid,url,layout);
+    }
+
+    /* 递归函数 */
+    private String recursion(Integer pid,String url,String layout){
+       StringBuffer sbf = new StringBuffer();
+       List<TSysOrg> orgList  = service.findByPid(pid);
+       if(orgList!=null&&orgList.size()>0){
+           for(TSysOrg org:orgList){
+               sbf.append("  <li data-id=\""+org.getId()+"\" data-pid=\""+pid+"\" data-url=\""+httpProtocol+"://"+ ControllerUtil.getDomain()+"/"+url+org.getId()+"\"  data-divid=\""+layout+"\">"+org.getName()+"</li>");
+               sbf.append(recursion(org.getId(),url,layout));
+           }
+           return  sbf.toString();
+       }
+       return "";
+    }
+}

+ 49 - 0
src/main/java/com/sooka/component/beetl/fun/TreePermissionFunction.java

@@ -0,0 +1,49 @@
+package com.sooka.component.beetl.fun;
+
+import com.sooka.module.web.system.service.RoleService;
+import com.sooka.mybatis.model.TSysPermission;
+import com.sooka.common.utils.ControllerUtil;
+import org.beetl.core.Context;
+import org.beetl.core.Function;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Description:输出子权限节点函数
+ *
+ *
+ * @create 2017-04-15
+ **/
+@Service
+public class TreePermissionFunction implements Function{
+
+    @Autowired
+    private RoleService service;
+
+    @Value("${system.http.protocol}")
+    private String httpProtocol;
+
+    @Override
+    public Object call(Object[] objects, Context context) {
+
+        Integer pid = (Integer) objects[0];
+        return recursion(pid);
+    }
+
+    /* 递归函数 */
+    private String recursion(int pid){
+       StringBuffer sbf = new StringBuffer();
+       List<TSysPermission> permissions  = service.findPermissonByPid(pid);
+       if(permissions!=null&&permissions.size()>0){
+           for(TSysPermission per:permissions){
+               sbf.append("  <li data-id=\""+per.getPermissionId()+"\" data-pid=\""+pid+"\" data-url=\""+httpProtocol+"://"+ ControllerUtil.getDomain()+"/system/permission/input/"+per.getPermissionId()+"\" data-divid=\"#layout-1\">"+per.getDescription()+"</li>");
+               sbf.append(recursion(per.getPermissionId()));
+           }
+           return  sbf.toString();
+       }
+       return "";
+    }
+}

+ 65 - 0
src/main/java/com/sooka/component/beetl/fun/TreeTopicCatagoryFunction.java

@@ -0,0 +1,65 @@
+package com.sooka.component.beetl.fun;
+
+import com.sooka.mybatis.model.TCmsCategory;
+import com.sooka.common.utils.StrUtil;
+import com.sooka.module.web.cms.service.CategoryService;
+import org.beetl.core.Context;
+import org.beetl.core.Function;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Description:权限tag
+ * 这个函数需要调用时遍历使用
+ *
+ * @create 2017-04-14
+ **/
+@Service
+public class TreeTopicCatagoryFunction implements Function {
+
+    @Autowired
+    private CategoryService service;
+
+    private final String isChecked = " data-checked='true' ";
+
+    @Override
+    public Object call(Object[] objects, Context context) {
+
+        String siteId = objects[0].toString();
+        String pid = (String) objects[1];
+        String categoryIds = (String) objects[2];
+        return recursion(Long.parseLong(pid),Integer.parseInt(siteId),categoryIds);
+
+    }
+
+    /* 递归函数 */
+    private String recursion(Long pid,Integer siteId,String categoryIds){
+        StringBuffer sbf = new StringBuffer();
+        List<TCmsCategory> cats  = service.findCategoryListByPid(pid,siteId);
+        if(cats!=null&&cats.size()>0){
+            for(TCmsCategory cat:cats){
+                sbf.append("<li data-id=\""+cat.getCategoryId()+"\" data-pid=\""+pid+"\" "+isChecked(cat.getCategoryId(),categoryIds)+" >"+cat.getCategoryName()+" </li>");
+                sbf.append(recursion(cat.getCategoryId(),siteId,categoryIds));
+            }
+            return  sbf.toString();
+        }
+        return "";
+    }
+
+
+    public String isChecked(Long c1,String categoryIds){
+        if(!StrUtil.isBlank(categoryIds)) {
+            String[] array = categoryIds.split(",");
+            for (String catId : array) {
+                Long c2 = Long.parseLong(catId);
+                if (c1.longValue() == c2.longValue()) {
+                    return isChecked;
+                }
+                continue;
+            }
+        }
+        return "";
+    }
+}

+ 63 - 0
src/main/java/com/sooka/component/beetl/html/BeetlHtmlUtil.java

@@ -0,0 +1,63 @@
+package com.sooka.component.beetl.html;
+
+
+import com.sooka.component.beetl.thread.HtmlThread;
+import com.sooka.common.utils.PathUtil;
+import com.sooka.common.utils.StrUtil;
+import org.beetl.core.GroupTemplate;
+import org.beetl.core.Template;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.io.StringWriter;
+import java.util.Map;
+
+
+@Component
+public class BeetlHtmlUtil {
+
+
+	@Autowired
+	private GroupTemplate groupTemplate;
+
+	@Value("${system.http.protocol}")
+	private String httpProtocol;
+
+	@Value("${system.http.host}")
+	private String httpHost;
+
+	@Value("${system.site.subfix}")
+	private String siteSubfix;
+
+	@Value("${system.site.prefix}")
+	private String sitePrefix;
+
+
+	private final String STATIC_SUFFIX = ".html";
+
+
+	public void create(HttpServletRequest request,Integer siteId, String action, Map<String, Object> attr, String theme, String tpl) {
+		String view = "www"+File.separator + theme + File.separator + tpl+STATIC_SUFFIX;
+		Template template = groupTemplate.getTemplate(view);
+		StringWriter writer = new StringWriter();
+		template.binding("request", request);
+		template.binding("ctxPath", request.getContextPath());
+		template.binding("baseURL", httpProtocol + "://" + httpHost);
+		template.binding(attr);
+		template.renderTo(writer);
+		HtmlObject obj = new HtmlObject();
+		obj.setContent(format(writer.toString()));
+		String fileUrl = PathUtil.getWebRootPath() +File.separator+ "html" + File.separator+ siteId + File.separator + (StrUtil.isBlank(action)?"index":action) + ".html";
+		new File(fileUrl).delete();
+		obj.setFileUrl(fileUrl);
+		HtmlThread.addHtml(obj);
+	}
+     
+	private String format(String page){
+		return page.replace("/"+sitePrefix+"/","/html/").replace(siteSubfix, STATIC_SUFFIX);
+	}
+
+}

+ 24 - 0
src/main/java/com/sooka/component/beetl/html/HtmlObject.java

@@ -0,0 +1,24 @@
+package com.sooka.component.beetl.html;
+
+public class HtmlObject {
+
+	private String fileUrl;
+	private String content;
+
+	public String getFileUrl() {
+		return fileUrl;
+	}
+
+	public void setFileUrl(String fileUrl) {
+		this.fileUrl = fileUrl;
+	}
+
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+
+}

+ 210 - 0
src/main/java/com/sooka/component/beetl/tag/ShiroTag.java

@@ -0,0 +1,210 @@
+package com.sooka.component.beetl.tag;
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.util.Map;
+ 
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
+
+public class ShiroTag {
+    /**
+     * The guest tag
+     * 
+     * @return
+     */
+    public boolean isGuest() {
+        return getSubject() == null || getSubject().getPrincipal() == null;
+    }
+ 
+    /**
+     * The user tag
+     * 
+     * @return
+     */
+    public boolean isUser() {
+        return getSubject() != null && getSubject().getPrincipal() != null;
+    }
+ 
+    /**
+     * The authenticated tag
+     * 
+     * @return
+     */
+    public boolean isAuthenticated() {
+        return getSubject() != null && getSubject().isAuthenticated();
+    }
+ 
+    public boolean isNotAuthenticated() {
+        return !isAuthenticated();
+    }
+ 
+    /**
+     * The principal tag
+     * 
+     * @param map
+     * @return
+     */
+    public String principal(Map<?, ?> map) {
+        String strValue = null;
+        if (getSubject() != null) {
+ 
+            // Get the principal to print out
+            Object principal;
+            String type = map != null ? (String) map.get("type") : null;
+            if (type == null) {
+                principal = getSubject().getPrincipal();
+            } else {
+                principal = getPrincipalFromClassName(type);
+            }
+            String property = map != null ? (String) map.get("property") : null;
+            // Get the string value of the principal
+            if (principal != null) {
+                if (property == null) {
+                    strValue = principal.toString();
+                } else {
+                    strValue = getPrincipalProperty(principal, property);
+                }
+            }
+ 
+        }
+ 
+        if (strValue != null) {
+            return strValue;
+        } else {
+            return null;
+        }
+    }
+ 
+    /**
+     * The hasRole tag
+     * 
+     * @param roleName
+     * @return
+     */
+    public boolean hasRole(String roleName) {
+        return getSubject() != null && getSubject().hasRole(roleName);
+    }
+ 
+    /**
+     * The lacksRole tag
+     * 
+     * @param roleName
+     * @return
+     */
+    public boolean lacksRole(String roleName) {
+        boolean hasRole = getSubject() != null
+                && getSubject().hasRole(roleName);
+        return !hasRole;
+    }
+ 
+    /**
+     * The hasAnyRole tag
+     * 
+     * @param roleNames
+     * @return
+     */
+    public boolean hasAnyRole(String roleNames) {
+        boolean hasAnyRole = false;
+ 
+        Subject subject = getSubject();
+ 
+        if (subject != null) {
+ 
+            // Iterate through roles and check to see if the user has one of the
+            // roles
+            for (String role : roleNames.split(",")) {
+ 
+                if (subject.hasRole(role.trim())) {
+                    hasAnyRole = true;
+                    break;
+                }
+ 
+            }
+ 
+        }
+ 
+        return hasAnyRole;
+    }
+ 
+    /**
+     * The hasPermission tag
+     * 
+     * @param p
+     * @return
+     */
+    public boolean hasPermission(String p) {
+        return getSubject() != null && getSubject().isPermitted(p);
+    }
+ 
+    /**
+     * The lacksPermission tag
+     * 
+     * @param p
+     * @return
+     */
+    public boolean lacksPermission(String p) {
+        return !hasPermission(p);
+    }
+ 
+    private Object getPrincipalFromClassName(String type) {
+        Object principal = null;
+ 
+        try {
+            Class<?> cls = Class.forName(type);
+            principal = getSubject().getPrincipals().oneByType(cls);
+        } catch (ClassNotFoundException e) {
+ 
+        }
+        return principal;
+    }
+ 
+    private String getPrincipalProperty(Object principal, String property) {
+        String strValue = null;
+ 
+        try {
+            BeanInfo bi = Introspector.getBeanInfo(principal.getClass());
+ 
+            // Loop through the properties to get the string value of the
+            // specified property
+            boolean foundProperty = false;
+            for (PropertyDescriptor pd : bi.getPropertyDescriptors()) {
+                if (pd.getName().equals(property)) {
+                    Object value = pd.getReadMethod().invoke(principal,
+                            (Object[]) null);
+                    strValue = String.valueOf(value);
+                    foundProperty = true;
+                    break;
+                }
+            }
+ 
+            if (!foundProperty) {
+                final String message = "Property [" + property
+                        + "] not found in principal of type ["
+                        + principal.getClass().getName() + "]";
+ 
+                throw new RuntimeException(message);
+            }
+ 
+        } catch (Exception e) {
+            final String message = "Error reading property [" + property
+                    + "] from principal of type ["
+                    + principal.getClass().getName() + "]";
+ 
+            throw new RuntimeException(message, e);
+        }
+ 
+        return strValue;
+    }
+ 
+    protected Subject getSubject() {
+        return SecurityUtils.getSubject();
+    }
+ 
+//    public static void main(String[] args) {
+//        GroupTemplate gt = new GroupTemplate();
+//        gt.registerFunctionPackage("shiro", new ShiroTag());
+//
+//    }
+ 
+}

+ 223 - 0
src/main/java/com/sooka/component/beetl/tag/TagRegisterFactory.java

@@ -0,0 +1,223 @@
+package com.sooka.component.beetl.tag;
+
+import com.google.common.collect.Maps;
+import org.beetl.core.TagFactory;
+import org.beetl.ext.spring.SpringBeanTagFactory;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * Description:aa
+ *
+ *
+ * @create 2017-06-03
+ **/
+@Component
+public class TagRegisterFactory {
+
+
+    /* 内容列表标签 */
+    @Bean(name = "contentListTagFactory")
+    public SpringBeanTagFactory ContentListTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("contentListTag");
+        return  springBeanTagFactory;
+    }
+
+    /* 内容分页标签 */
+    @Bean(name = "contentPageTagFactory")
+    public SpringBeanTagFactory ContentPageTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("contentPageTag");
+        return  springBeanTagFactory;
+    }
+
+    /* 分页标签 */
+    @Bean(name = "paginationTagFactory")
+    public SpringBeanTagFactory PaginationTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("paginationTag");
+        return  springBeanTagFactory;
+    }
+    /* dbt成员分页标签 */
+    @Bean(name = "dbtuserPageTagFactory")
+    public SpringBeanTagFactory dbtuserPageTagFactory(){
+    	SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+    	springBeanTagFactory.setName("dbtUserListPageTag");
+    	return  springBeanTagFactory;
+    }
+
+    @Bean(name = "contentTagFactory")
+    public SpringBeanTagFactory contentTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("contentTag");
+        return  springBeanTagFactory;
+    }
+
+    @Bean(name = "categoryListTagFactory")
+    public SpringBeanTagFactory categoryListTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("categoryListTag");
+        return  springBeanTagFactory;
+    }
+
+    @Bean(name = "categoryTagFactory")
+    public SpringBeanTagFactory categoryTagFactory() {
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("categoryTag");
+        return springBeanTagFactory;
+    }
+
+
+
+    @Bean(name = "printSitePositionTagFactory")
+    public SpringBeanTagFactory  printSitePositionTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("printSitePositionTag");
+        return  springBeanTagFactory;
+    }
+
+    @Bean(name = "searchModelFiledValueTagFactory")
+    public SpringBeanTagFactory searchModelFiledValueTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("searchModelFiledValueTag");
+        return  springBeanTagFactory;
+    }
+
+    @Bean(name = "lucenePageTagFactory")
+    public SpringBeanTagFactory lucenePageTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("lucenePageTag");
+        return  springBeanTagFactory;
+    }
+
+
+    /* 分页标签 */
+    @Bean(name = "lucenePaginationTagFactory")
+    public SpringBeanTagFactory lucenePaginationTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("lucenePaginationTag");
+        return  springBeanTagFactory;
+    }
+
+    /* 分页标签 */
+    @Bean(name = "indexSilderTagFactory")
+    public SpringBeanTagFactory indexSilderTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("indexSilderTag");
+        return  springBeanTagFactory;
+    }
+
+
+    @Bean(name = "topicListTagFactory")
+    public SpringBeanTagFactory topicListTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("topicListTag");
+        return  springBeanTagFactory;
+    }
+
+    @Bean(name = "topicContentTagFactory")
+    public SpringBeanTagFactory topicContentTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("topicContentTag");
+        return  springBeanTagFactory;
+    }
+
+
+    /* 友情链接标签 */
+    @Bean(name = "friendLinkListTagFactory")
+    public SpringBeanTagFactory friendLinkListTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("friendLinkListTag");
+        return  springBeanTagFactory;
+    }
+
+    /* 视频标签 */
+    @Bean(name = "videoTagFactory")
+    public SpringBeanTagFactory videoTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("videoTag");
+        return  springBeanTagFactory;
+    }
+
+    /* 投票标签 */
+    @Bean(name = "voteTagFactory")
+    public SpringBeanTagFactory voteTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("voteTag");
+        return  springBeanTagFactory;
+    }
+    /* 文字直播标签 */
+    @Bean(name = "liveListTagFactory")
+    public SpringBeanTagFactory liveTagFactory(){
+        SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+        springBeanTagFactory.setName("liveListTag");
+        return  springBeanTagFactory;
+    }
+    /* 代表团标签 */
+    @Bean(name = "dbtListTagFactory")
+    public SpringBeanTagFactory dbtTagFactory(){
+    	SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+    	springBeanTagFactory.setName("dbtListTag");
+    	return  springBeanTagFactory;
+    }
+    /* 代表团成员标签 */
+    @Bean(name = "dbtUserListTagFactory")
+    public SpringBeanTagFactory dbtUserTagFactory(){
+    	SpringBeanTagFactory springBeanTagFactory = new SpringBeanTagFactory();
+    	springBeanTagFactory.setName("dbtUserListTag");
+    	return  springBeanTagFactory;
+    }
+    /* TagFactory */
+    @Bean(name = "tagFactory")
+    public Map<String,TagFactory> Tag(@Qualifier("contentListTagFactory") SpringBeanTagFactory contentListTag,
+                                      @Qualifier("contentPageTagFactory") SpringBeanTagFactory contentPageTag,
+                                      @Qualifier("paginationTagFactory") SpringBeanTagFactory paginationTag,
+                                      @Qualifier("contentTagFactory") SpringBeanTagFactory contentTag,
+                                      @Qualifier("categoryListTagFactory") SpringBeanTagFactory categoryListTag,
+                                      @Qualifier("categoryTagFactory") SpringBeanTagFactory categoryTag,
+                                      @Qualifier("searchModelFiledValueTagFactory") SpringBeanTagFactory SearchModelFiledValueTag,
+                                      @Qualifier("printSitePositionTagFactory") SpringBeanTagFactory printSitePositionTagFactory,
+                                      @Qualifier("lucenePageTagFactory") SpringBeanTagFactory lucenePageTagFactory,
+                                      @Qualifier("lucenePaginationTagFactory") SpringBeanTagFactory lucenePaginationTagFactory,
+                                      @Qualifier("indexSilderTagFactory") SpringBeanTagFactory indexSilderTagFactory,
+                                      @Qualifier("topicListTagFactory") SpringBeanTagFactory topicListTagFactory,
+                                      @Qualifier("topicContentTagFactory") SpringBeanTagFactory topicContentTagFactory,
+                                      @Qualifier("friendLinkListTagFactory") SpringBeanTagFactory friendLinkListTagFactory,
+                                      @Qualifier("videoTagFactory") SpringBeanTagFactory videoTagFactory,
+                                      @Qualifier("voteTagFactory") SpringBeanTagFactory voteTagFactory,
+                                      @Qualifier("liveListTagFactory") SpringBeanTagFactory liveListTag,
+                                      @Qualifier("dbtListTagFactory") SpringBeanTagFactory dbtListTag,
+                                      @Qualifier("dbtUserListTagFactory") SpringBeanTagFactory dbtUserListTag,
+                                      @Qualifier("dbtuserPageTagFactory") SpringBeanTagFactory dbtUserListPageTag
+
+
+    ){
+        Map<String,TagFactory> tag = Maps.newHashMap();
+        tag.put("cms_content_list",contentListTag);
+        tag.put("cms_content_page",contentPageTag);
+        tag.put("cms_pagination",paginationTag);
+        tag.put("cms_content",contentTag);
+        tag.put("cms_category_list",categoryListTag);
+        tag.put("cms_category",categoryTag);
+        tag.put("cms_modelfiled_find",SearchModelFiledValueTag);
+        tag.put("cms_site_pos",printSitePositionTagFactory);
+        tag.put("cms_lucene_page",lucenePageTagFactory);
+        tag.put("cms_lucene_pagination",lucenePaginationTagFactory);
+        tag.put("cms_index_silder",indexSilderTagFactory);
+        tag.put("cms_topic_list",topicListTagFactory);
+        tag.put("cms_topic_content",topicContentTagFactory);
+        tag.put("cms_friendlink",friendLinkListTagFactory);
+        tag.put("cms_index_video",videoTagFactory);
+        tag.put("cms_index_vote",voteTagFactory());
+        tag.put("cms_live_list",liveListTag);
+        tag.put("cms_dbt_list",dbtListTag);
+        tag.put("cms_dbtUser_list",dbtUserListTag);
+        tag.put("cms_dbtUserPage_list",dbtUserListPageTag);
+        return  tag;
+    }
+
+}

+ 88 - 0
src/main/java/com/sooka/component/beetl/tag/cms/CategoryListTag.java

@@ -0,0 +1,88 @@
+package com.sooka.component.beetl.tag.cms;
+
+import com.sooka.module.web.cms.service.SiteService;
+import com.sooka.mybatis.model.TCmsCategory;
+import com.sooka.mybatis.model.TCmsSite;
+import com.sooka.common.exception.CmsException;
+import com.sooka.common.utils.CmsUtil;
+import com.sooka.common.utils.Pojo2MapUtil;
+import com.sooka.common.utils.StrUtil;
+import com.sooka.module.web.cms.service.CategoryService;
+import org.beetl.core.GeneralVarTagBinding;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Description:内容列表标签
+ *
+ *
+ * @create 2017-05-26
+ **/
+@Service
+@Scope("prototype")
+public class CategoryListTag extends GeneralVarTagBinding {
+
+	@Autowired
+	private CategoryService categoryService;
+
+	@Autowired
+	private SiteService siteService;
+
+	@Value("${system.http.protocol}")
+	private String httpProtocol;
+
+	@Value("${system.http.host}")
+	private String httpHost;
+
+	@Value("${system.site.prefix}")
+	private String sitePrefix;
+
+	@Value("${system.site.subfix}")
+	private String siteSubfix;
+
+
+	@Override
+	public void render() {
+		Integer siteId=  (this.getAttributeValue("siteId") instanceof String)?Integer.parseInt((String) this.getAttributeValue("siteId")):(Integer)this.getAttributeValue("siteId");
+		Long categoryId=  (this.getAttributeValue("categoryId") instanceof String)?Long.parseLong((String) this.getAttributeValue("categoryId")):(Long) this.getAttributeValue("categoryId");
+		Integer isNav = Integer.parseInt((String) this.getAttributeValue("isNav"));
+		try {
+			this.wrapRender(siteId,categoryId,(isNav.intValue()==1?true:false));
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new CmsException(e.getMessage());
+		}
+
+	}
+	private void wrapRender(Integer siteId,Long categoryId,boolean isNav) throws Exception {
+		TCmsSite site = siteService.findById(siteId);
+		if(CmsUtil.isNullOrEmpty(site)) {
+            throw new CmsException("站点不存在[siteId:"+siteId+"]");
+        }
+		List<TCmsCategory> cats = categoryService.findCategoryListByPidAndIsNav(categoryId,siteId,isNav);
+        int i = 1;
+		if(CmsUtil.isNullOrEmpty(cats)) {
+        	TCmsCategory category = categoryService.findById(categoryId);
+        	if(CmsUtil.isNullOrEmpty(category)) {
+                throw new CmsException("没有查询到数据![siteId:" + siteId + ",categoryId:" + categoryId + "]");
+            }
+			cats = categoryService.findCategoryListByPidAndIsNav(category.getParentId(),siteId,isNav);
+		}
+        for (TCmsCategory category : cats){
+        	if(StrUtil.isBlank(category.getUrl())) {
+				category.setUrl(httpProtocol + "://" + (StrUtil.isBlank(site.getDomain())?httpHost:site.getDomain()) + "/"+sitePrefix+"/" + category.getSiteId() + "/" + category.getCategoryId()+siteSubfix);
+			}
+			Map result = Pojo2MapUtil.toMap(category);
+			result.put("index",i);
+			this.binds(result);
+			this.doBodyRender();
+			i++;
+		}
+	}
+
+}

+ 78 - 0
src/main/java/com/sooka/component/beetl/tag/cms/CategoryTag.java

@@ -0,0 +1,78 @@
+package com.sooka.component.beetl.tag.cms;
+
+import com.google.common.collect.Maps;
+import com.sooka.module.web.cms.service.SiteService;
+import com.sooka.mybatis.model.TCmsCategory;
+import com.sooka.mybatis.model.TCmsSite;
+import com.sooka.common.exception.CmsException;
+import com.sooka.common.utils.CmsUtil;
+import com.sooka.common.utils.StrUtil;
+import com.sooka.module.web.cms.service.CategoryService;
+import org.beetl.core.GeneralVarTagBinding;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * Description:内容列表标签
+ *
+ *
+ * @create 2017-05-26
+ **/
+@Service
+@Scope("prototype")
+public class CategoryTag extends GeneralVarTagBinding {
+
+	@Autowired
+	private CategoryService categoryService;
+
+	@Autowired
+	private SiteService siteService;
+
+	@Value("${system.http.protocol}")
+	private String httpProtocol;
+
+	@Value("${system.http.host}")
+	private String httpHost;
+
+	@Value("${system.site.prefix}")
+	private String sitePrefix;
+
+	@Value("${system.site.subfix}")
+	private String siteSubfix;
+
+	@Override
+	public void render() {
+		Map result = Maps.newHashMap();
+		Long categoryId=  (this.getAttributeValue("categoryId") instanceof String)?Long.parseLong((String) this.getAttributeValue("categoryId")):(Long) this.getAttributeValue("categoryId");
+		String categoryAlias = (String) this.getAttributeValue("categoryAlias");
+		Integer isParent=  (this.getAttributeValue("isParent") instanceof String)?Integer.parseInt((String) this.getAttributeValue("isParent")):(Integer) this.getAttributeValue("categoryId");
+		TCmsCategory category;
+		if(!(("").equals(categoryAlias)||null==categoryAlias)){
+			 category = categoryService.findByAlias(categoryAlias);
+		}else {
+			 category = categoryService.findById(categoryId);
+		}
+		TCmsSite site = siteService.findById(category.getSiteId());
+		if(CmsUtil.isNullOrEmpty(category)) {
+            throw new CmsException("栏目["+categoryId+"]不存在!");
+        }
+		if(isParent==1&&category.getParentId()!=0) {
+            category = categoryService.findById(category.getParentId());
+        }
+		result.put("categoryId",category.getCategoryId());
+		result.put("categoryName",category.getCategoryName());
+		result.put("categoryAlias",category.getAlias());
+		result.put("categoryContent",category.getContent());
+		result.put("categoryIcon",category.getCategoryIcon());
+		result.put("enName",category.getEnName());
+		result.put("url", !StrUtil.isBlank(category.getUrl())?category.getUrl():httpProtocol + "://" + (StrUtil.isBlank(site.getDomain())?httpHost:site.getDomain()) + "/"+sitePrefix+"/" + category.getSiteId() + "/" + category.getCategoryId()+siteSubfix);
+		result.put("more", !StrUtil.isBlank(category.getUrl())?category.getUrl():httpProtocol + "://" + (StrUtil.isBlank(site.getDomain())?httpHost:site.getDomain()) + "/"+sitePrefix+"/" + category.getSiteId() + "/" + category.getCategoryId()+"/index_1"+siteSubfix);
+		this.binds(result);
+		this.doBodyRender();
+	}
+
+}

+ 119 - 0
src/main/java/com/sooka/component/beetl/tag/cms/ContentListTag.java

@@ -0,0 +1,119 @@
+package com.sooka.component.beetl.tag.cms;
+
+import com.github.pagehelper.PageInfo;
+import com.sooka.module.web.cms.service.SiteService;
+import com.sooka.mybatis.model.TCmsSite;
+import com.sooka.common.exception.CmsException;
+import com.sooka.common.exception.SystemException;
+import com.sooka.common.utils.CmsUtil;
+import com.sooka.common.utils.StrUtil;
+import com.sooka.module.web.cms.service.ContentService;
+import org.beetl.core.GeneralVarTagBinding;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Service;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Description:内容列表标签
+ *
+ *
+ * @create 2017-05-26
+ **/
+@Service
+@Scope("prototype")
+public class ContentListTag extends GeneralVarTagBinding {
+
+    @Autowired
+    private ContentService contentService;
+
+    @Autowired
+    private SiteService siteService;
+
+    @Value("${system.http.protocol}")
+    private String httpProtocol;
+
+    @Value("${system.site.subfix}")
+    private String siteSubfix;
+
+    @Value("${system.http.host}")
+    private String httpHost;
+
+    @Value("${system.site.prefix}")
+    private String sitePrefix;
+
+
+    /**
+     * 文章列表标签
+     *
+     * siteId:站点id
+     * categoryId:分类编号
+     * hasChild:是否包含子栏目内容
+     * isHot:热门
+     * titleLen:标题长度
+     * target:是否新窗口打开
+     * orderBy:排序
+     * size:调用条数
+     * recommend:是否推荐 :0为不推荐,1为推荐
+     *
+     */
+    @Override
+    public void render() {
+        if (CmsUtil.isNullOrEmpty(this.args[1])) {
+            throw  new SystemException("标签参数不能为空!");
+        }
+        Integer titleLen =  Integer.parseInt((String) this.getAttributeValue("titleLen"));
+        Integer siteId=  (this.getAttributeValue("siteId") instanceof String)?Integer.parseInt((String) this.getAttributeValue("siteId")):(Integer)this.getAttributeValue("siteId");
+        Long categoryId=  (this.getAttributeValue("categoryId") instanceof String)?Long.parseLong((String) this.getAttributeValue("categoryId")):(Long) this.getAttributeValue("categoryId");
+        Integer hasChild=  Integer.parseInt((String) this.getAttributeValue("hasChild"));
+        Integer isPic =  Integer.parseInt(CmsUtil.isNullOrEmpty(this.getAttributeValue("isPic"))?"3":(String)this.getAttributeValue("isPic"));
+        Integer isRecommend =  Integer.parseInt(CmsUtil.isNullOrEmpty(this.getAttributeValue("isRecommend"))?"0":(String) this.getAttributeValue("isRecommend"));
+        Integer orderBy =  Integer.parseInt((String) this.getAttributeValue("orderBy"));
+        Integer pageNumber =  Integer.parseInt((CmsUtil.isNullOrEmpty(this.getAttributeValue("pageNumber"))?"1":(String) this.getAttributeValue("pageNumber")));
+        Integer pageSize =  Integer.parseInt((String) this.getAttributeValue("size"));
+        Integer isHot =  Integer.parseInt((String) this.getAttributeValue("isHot"));
+        PageInfo<Map> pageInfo = contentService.findContentListBySiteIdAndCategoryId(siteId, categoryId, orderBy, pageNumber,pageSize, hasChild, isHot, isPic,isRecommend);
+        if(CmsUtil.isNullOrEmpty(pageInfo.getList())) {
+            return;
+        }
+        this.wrapRender(pageInfo.getList(),titleLen,siteId);
+
+    }
+
+    private void wrapRender(List<Map>  contentList, int titleLen, int siteId) {
+        int i = 1;
+        for (Map content : contentList) {
+            String title = content.get("title").toString();
+            int length = title.length();
+            if (length > titleLen) {
+                content.put("title",title.substring(0, titleLen) + "...");
+            }
+            if (StrUtil.isBlank(content.get("url").toString())) {
+                TCmsSite site = siteService.findById(siteId);
+                if(CmsUtil.isNullOrEmpty(site)) {
+                    throw new CmsException("站点不存在[siteId:"+siteId+"]");
+                }
+                String url = httpProtocol + "://" + (StrUtil.isBlank(site.getDomain())?httpHost:site.getDomain()) + "/"+sitePrefix+"/"+site.getSiteId()+"/";
+                url+=content.get("categoryId")+"/"+content.get("contentId");
+                content.put("url",url+siteSubfix);
+            }
+            //contentlist中显示new标签 如发布日期是当前系统时间则显示new标签
+            Date indate =  (Date)content.get("inputdate");
+            int days = (int) ((new Date().getTime() - indate.getTime()) / (1000*3600*24));
+            if(days<2){
+                content.put("temp","<i></i>");
+            }
+            content.put("index",i);
+            this.binds(content);
+            this.doBodyRender();
+            i++;
+        }
+
+    }
+
+}

+ 93 - 0
src/main/java/com/sooka/component/beetl/tag/cms/ContentPageTag.java

@@ -0,0 +1,93 @@
+package com.sooka.component.beetl.tag.cms;
+
+import com.github.pagehelper.PageInfo;
+import com.sooka.module.web.cms.service.SiteService;
+import com.sooka.mybatis.model.TCmsSite;
+import com.sooka.common.exception.CmsException;
+import com.sooka.common.utils.CmsUtil;
+import com.sooka.common.utils.StrUtil;
+import org.beetl.core.GeneralVarTagBinding;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Description:内容列表标签
+ *
+ *
+ * @create 2017-05-26
+ **/
+@Service
+@Scope("prototype")
+public class ContentPageTag extends GeneralVarTagBinding {
+
+
+    @Autowired
+    private SiteService siteService;
+
+    @Value("${system.http.protocol}")
+    private String httpProtocol;
+
+    @Value("${system.http.host}")
+    private String httpHost;
+
+    @Value("${system.site.subfix}")
+    private String siteSubfix;
+
+    @Value("${system.site.prefix}")
+    private String sitePrefix;
+    /**
+     *
+     * 内容分页标签
+     *
+     */
+    @Override
+    public void render() {
+        if (CmsUtil.isNullOrEmpty(this.args[1])) {
+            throw  new CmsException("[内容分页标签]标签参数不能为空!");
+        }
+        Integer siteId=  (this.getAttributeValue("siteId") instanceof String)?Integer.parseInt((String) this.getAttributeValue("siteId")):(Integer)this.getAttributeValue("siteId");
+        if (CmsUtil.isNullOrEmpty(siteId)) {
+            throw  new CmsException("[内容分页标签]站点id不能为空");
+        }
+        PageInfo<Map> pageInfo = (PageInfo) this.getAttributeValue("page");
+        if (CmsUtil.isNullOrEmpty(pageInfo)) {
+            throw  new CmsException("[内容分页标签]此标签只能栏目页和栏目列表页使用");
+        }
+        String titleLen = (String) this.getAttributeValue("titleLen");
+        if (CmsUtil.isNullOrEmpty(pageInfo)) {
+            throw  new CmsException("[内容分页标签]站点id不能为空");
+        }
+
+        this.wrapRender(pageInfo.getList(),Integer.parseInt(titleLen),siteId);
+    }
+
+    private void wrapRender(List<Map>  contents, int titleLen, int siteId){
+        int i = 1;
+        for (Map content : contents) {
+            String title = content.get("title").toString();
+            int length = title.length();
+            if (length > titleLen) {
+                content.put("title",title.substring(0, titleLen) + "...");
+            }
+            if (StrUtil.isBlank(content.get("url").toString())) {
+                TCmsSite site = siteService.findById(siteId);
+                if(CmsUtil.isNullOrEmpty(site)) {
+                    throw new CmsException("站点不存在[siteId:"+siteId+"]");
+                }
+                String url = httpProtocol + "://" + (StrUtil.isBlank(site.getDomain())?httpHost:site.getDomain()) + "/"+sitePrefix+"/"+site.getSiteId()+"/";
+                url+=content.get("categoryId")+"/"+content.get("contentId");
+                content.put("url",url+siteSubfix);
+            }
+            content.put("index",i);
+            this.binds(content);
+            this.doBodyRender();
+            i++;
+        }
+    }
+
+}

+ 87 - 0
src/main/java/com/sooka/component/beetl/tag/cms/ContentTag.java

@@ -0,0 +1,87 @@
+package com.sooka.component.beetl.tag.cms;
+
+import com.google.common.collect.Maps;
+import com.sooka.module.web.cms.service.SiteService;
+import com.sooka.mybatis.mapper.TCmsContentMapper;
+import com.sooka.mybatis.model.TCmsContent;
+import com.sooka.mybatis.model.TCmsSite;
+import com.sooka.common.utils.CmsUtil;
+import com.sooka.common.utils.StrUtil;
+import org.beetl.core.GeneralVarTagBinding;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * Description:CONTENT TAG
+ *
+ *
+ * @create 2017-06-06
+ **/
+@Service
+@Scope("prototype")
+public class ContentTag extends GeneralVarTagBinding {
+
+    @Autowired
+    private TCmsContentMapper contentMapper;
+
+    @Autowired
+    private SiteService siteService;
+
+    @Value("${system.http.protocol}")
+    private String httpProtocol;
+
+    @Value("${system.http.host}")
+    private String httpHost;
+
+    @Value("${system.site.subfix}")
+    private String siteSubfix;
+
+    @Value("${system.site.prefix}")
+    private String sitePrefix;
+
+    @Override
+    public void render() {
+        Long categoryId=  (this.getAttributeValue("categoryId") instanceof String)?Long.parseLong((String) this.getAttributeValue("categoryId")):(Long) this.getAttributeValue("categoryId");
+        Long contentId=  (this.getAttributeValue("contentId") instanceof String)? Long.parseLong((String) this.getAttributeValue("contentId")):( Long)this.getAttributeValue("contentId");
+        Integer titleLen =  Integer.parseInt((String) this.getAttributeValue("titleLen"));
+        wrapRender(categoryId,contentId,titleLen);
+
+    }
+
+    private void wrapRender(Long categoryId, Long contentId, Integer titleLen) {
+        Map  result = Maps.newHashMap();
+        String prevContent="没有了",nextContent="没有了";
+        TCmsContent prev = contentMapper.selectPrevContentByContentIdAndCategoryId(contentId,categoryId);
+        TCmsContent next = contentMapper.selectNextContentByContentIdAndCategoryId(contentId,categoryId);
+
+        if(!CmsUtil.isNullOrEmpty(prev)) {
+            TCmsSite site = siteService.findById(prev.getSiteId());
+            int length = prev.getTitle().length();
+            if (length > titleLen) {
+                prev.setTitle(prev.getTitle().substring(0, titleLen));
+            }
+
+            prevContent = "<a href=\""+httpProtocol+"://"+(StrUtil.isBlank(site.getDomain())?httpHost:site.getDomain())+"/"+sitePrefix+"/"+prev.getSiteId()+"/"+prev.getCategoryId()+"/"+prev.getContentId();
+            prevContent+=siteSubfix+"\">"+prev.getTitle()+ "...</a>";
+        }
+        if(!CmsUtil.isNullOrEmpty(next)) {
+            TCmsSite site = siteService.findById(next.getSiteId());
+            int length = next.getTitle().length();
+            if (length > titleLen) {
+                next.setTitle(next.getTitle().substring(0, titleLen));
+            }
+            nextContent = "<a href=\""+httpProtocol+"://"+(StrUtil.isBlank(site.getDomain())?httpHost:site.getDomain())+"/"+sitePrefix+"/"+next.getSiteId()+"/"+next.getCategoryId()+"/"+next.getContentId();
+            nextContent+=siteSubfix+"\">"+next.getTitle()+ "...</a>";
+        }
+        result.put("prev",prevContent);
+        result.put("next",nextContent);
+        this.binds(result);
+        this.doBodyRender();
+
+
+    }
+}

+ 67 - 0
src/main/java/com/sooka/component/beetl/tag/cms/DbtListTag.java

@@ -0,0 +1,67 @@
+package com.sooka.component.beetl.tag.cms;
+
+import java.util.List;
+import java.util.Map;
+
+import org.beetl.core.GeneralVarTagBinding;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Service;
+
+import com.github.pagehelper.PageInfo;
+import com.sooka.common.utils.CmsUtil;
+import com.sooka.common.utils.StrUtil;
+import com.sooka.module.web.cms.service.DbtService;
+import com.sooka.module.web.cms.service.SiteService;
+
+/**
+ * Description:代表团列表标签
+ *
+ *
+ * @create 2019-07-01
+ **/
+@Service
+@Scope("prototype")
+public class DbtListTag extends GeneralVarTagBinding{
+
+
+    @Autowired
+    private SiteService siteService;
+
+    @Value("${system.http.protocol}")
+    private String httpProtocol;
+
+    @Value("${system.site.subfix}")
+    private String siteSubfix;
+
+    @Value("${system.http.host}")
+    private String httpHost;
+
+    @Value("${system.site.prefix}")
+    private String sitePrefix;
+    
+    @Autowired
+    private DbtService dbtService;
+    
+    @Override
+    public void render() {
+      
+        PageInfo<Map> pageInfo = dbtService.selectByTCmsContentDbtAll();
+        if(CmsUtil.isNullOrEmpty(pageInfo.getList())) {
+            return;
+        }
+        this.wrapRender(pageInfo.getList());
+
+    }
+    
+    private void wrapRender(List<Map> dbtList) {
+        int i = 1;
+        for (Map dbt : dbtList) {
+            this.binds(dbt);
+            this.doBodyRender();
+            i++;
+        }
+
+    }
+}

+ 0 - 0
src/main/java/com/sooka/component/beetl/tag/cms/DbtUserListPageTag.java


Some files were not shown because too many files changed in this diff