瀏覽代碼

app代码提交

liujiankang 7 年之前
父節點
當前提交
8eff3f567a
共有 100 個文件被更改,包括 10305 次插入0 次删除
  1. 26 0
      iamberry-app-international/.classpath
  2. 42 0
      iamberry-app-international/.project
  3. 13 0
      iamberry-app-international/.settings/.jsdtscope
  4. 3 0
      iamberry-app-international/.settings/org.eclipse.core.resources.prefs
  5. 13 0
      iamberry-app-international/.settings/org.eclipse.jdt.core.prefs
  6. 4 0
      iamberry-app-international/.settings/org.eclipse.m2e.core.prefs
  7. 22 0
      iamberry-app-international/.settings/org.eclipse.wst.common.component
  8. 7 0
      iamberry-app-international/.settings/org.eclipse.wst.common.project.facet.core.xml
  9. 1 0
      iamberry-app-international/.settings/org.eclipse.wst.jsdt.ui.superType.container
  10. 1 0
      iamberry-app-international/.settings/org.eclipse.wst.jsdt.ui.superType.name
  11. 2 0
      iamberry-app-international/.settings/org.eclipse.wst.validation.prefs
  12. 1 0
      iamberry-app-international/.svn/entries
  13. 1 0
      iamberry-app-international/.svn/format
  14. 293 0
      iamberry-app-international/.svn/pristine/00/00dd6395ecb5e57bffec86910b6eb705956a38f8.svn-base
  15. 532 0
      iamberry-app-international/.svn/pristine/0c/0ccd285d125bcc90af70c3f129fc99f1eaf17730.svn-base
  16. 539 0
      iamberry-app-international/.svn/pristine/0c/0cd66c3deb003dda343cc5ca361352a77faf81f0.svn-base
  17. 98 0
      iamberry-app-international/.svn/pristine/0c/0cf71f3a620c6cd571a85d5f1ba5eef080abf47a.svn-base
  18. 389 0
      iamberry-app-international/.svn/pristine/18/18136ec92a3b2dfb203eaf3d0b7a793fa62ff361.svn-base
  19. 70 0
      iamberry-app-international/.svn/pristine/22/22173ddf2fa2499295397049407bb587f0551ddb.svn-base
  20. 16 0
      iamberry-app-international/.svn/pristine/25/25df57d6e11c0d8870a45aae8fb3a42c2bcdf849.svn-base
  21. 2 0
      iamberry-app-international/.svn/pristine/31/319d159ee4424788e6e8b2eded3e240b7fdf53e0.svn-base
  22. 34 0
      iamberry-app-international/.svn/pristine/35/35ad3ecde3e1bbeebeed9371a7be62c1d55c260b.svn-base
  23. 26 0
      iamberry-app-international/.svn/pristine/37/3730fa2b75dd756b12c7caf1e9f9683d8a6f4d60.svn-base
  24. 93 0
      iamberry-app-international/.svn/pristine/38/387fc6906a7ce0447af2e1262a05b65eca3df2ed.svn-base
  25. 27 0
      iamberry-app-international/.svn/pristine/39/3901fa8f1c4a005a146b96574b6b8092e8c7285d.svn-base
  26. 532 0
      iamberry-app-international/.svn/pristine/39/397d38eece729e1d37f9b9d2a1cd0eade570694f.svn-base
  27. 64 0
      iamberry-app-international/.svn/pristine/3c/3c4f44bf9339d557eb54019e823a342acbf69425.svn-base
  28. 1 0
      iamberry-app-international/.svn/pristine/41/41dfc0a6c92707948578891c51d98c6443be63cc.svn-base
  29. 5 0
      iamberry-app-international/.svn/pristine/42/42a840f2d518a115d4e1c6b2c116af2abdde661a.svn-base
  30. 31 0
      iamberry-app-international/.svn/pristine/50/5033d95392fa59b225fe23ba46d7d989f7ba4e06.svn-base
  31. 136 0
      iamberry-app-international/.svn/pristine/51/5177fd2c3ad5dd453c00b2c19ec6d7f0d3bdf086.svn-base
  32. 10 0
      iamberry-app-international/.svn/pristine/52/52acda021ca7bc541f8f8541dabe808ed05bbacc.svn-base
  33. 539 0
      iamberry-app-international/.svn/pristine/53/53bd5fe7a483ab1fe50a4826ddb607c1664a1a6d.svn-base
  34. 1 0
      iamberry-app-international/.svn/pristine/5f/5fa5e36180fac8708ac7a25f5380bdb519b8de05.svn-base
  35. 13 0
      iamberry-app-international/.svn/pristine/68/68ca41ed890bd786cc693f5f9b3dd33bf2dbe899.svn-base
  36. 7 0
      iamberry-app-international/.svn/pristine/69/699dd1b472ad34f5c04d726361332c26f57000d1.svn-base
  37. 260 0
      iamberry-app-international/.svn/pristine/70/70c2440d479ec32dbfd186726a5d80399cd1ec7f.svn-base
  38. 37 0
      iamberry-app-international/.svn/pristine/73/7322e445e86a8d348cda9f6affcb614074a0633a.svn-base
  39. 131 0
      iamberry-app-international/.svn/pristine/78/784922537c371568589b21ce066069b0048c97e5.svn-base
  40. 297 0
      iamberry-app-international/.svn/pristine/7a/7abbe70eff09a278f8efbf40d834b54cba105dd5.svn-base
  41. 22 0
      iamberry-app-international/.svn/pristine/83/83ab51b62a8cb82a5ca748ea2c2e180ad5d299c7.svn-base
  42. 8 0
      iamberry-app-international/.svn/pristine/84/84d744f1cbbc113016f2802a37bfb20380fbfc72.svn-base
  43. 1 0
      iamberry-app-international/.svn/pristine/87/87ab9531e1222351568346cf9057a0cae36112b8.svn-base
  44. 377 0
      iamberry-app-international/.svn/pristine/93/93955fa03a184dd76e7a2ee36bf862aae9cd0059.svn-base
  45. 303 0
      iamberry-app-international/.svn/pristine/95/95df5945e3fadcd750159ef1304b32ea5dee1c79.svn-base
  46. 4 0
      iamberry-app-international/.svn/pristine/a1/a112be21c325d37ebc17baafd40c0386b5d09df1.svn-base
  47. 79 0
      iamberry-app-international/.svn/pristine/a1/a152df36efa7f1f06e6e1e722f067909dc39a875.svn-base
  48. 42 0
      iamberry-app-international/.svn/pristine/a2/a2b094b2906a5f2271b328aaeb7a5285dfdf15a3.svn-base
  49. 24 0
      iamberry-app-international/.svn/pristine/a7/a754255887f6026a6c102ed3f4e2e2e96f55fac9.svn-base
  50. 40 0
      iamberry-app-international/.svn/pristine/aa/aa037c8be163494b85ba4fbd4b4b62d2db35a0e3.svn-base
  51. 303 0
      iamberry-app-international/.svn/pristine/aa/aa5c4f6f4a6d4e500cde870788aa77bffd8eb76c.svn-base
  52. 88 0
      iamberry-app-international/.svn/pristine/ab/ab039ffeeccfdceaa75e33ca53e2a92c2944371d.svn-base
  53. 133 0
      iamberry-app-international/.svn/pristine/b3/b3d4e4b9b583161a83cb5a6676083f8e8d948ffb.svn-base
  54. 1 0
      iamberry-app-international/.svn/pristine/b6/b6fd1c80f7f0ae3d8b009c634195870d0a4aaf12.svn-base
  55. 50 0
      iamberry-app-international/.svn/pristine/bc/bc7801b95dffb1c2efb3a126c57cffc2b1ac0693.svn-base
  56. 68 0
      iamberry-app-international/.svn/pristine/be/beef0a37b6d6122ac284b52781417f76121f68ab.svn-base
  57. 285 0
      iamberry-app-international/.svn/pristine/c1/c130ba42dbe8c8288f6cde791ad20602c19ff34e.svn-base
  58. 3 0
      iamberry-app-international/.svn/pristine/c2/c28ac1ab4014d61a4153c5aefc5da6e4d4737aa2.svn-base
  59. 26 0
      iamberry-app-international/.svn/pristine/cb/cb388b5487acff1f27682d272159552dbbdf23b1.svn-base
  60. 116 0
      iamberry-app-international/.svn/pristine/cd/cd2443d9c124ca0324b51c71ed005f1ea1835a59.svn-base
  61. 301 0
      iamberry-app-international/.svn/pristine/d3/d3959ceba203d91592413915a90b7753a3bac87e.svn-base
  62. 2 0
      iamberry-app-international/.svn/pristine/d4/d484a833555f187f2c607a59d136f423ef3a0af4.svn-base
  63. 26 0
      iamberry-app-international/.svn/pristine/e1/e1bb9cf6c5bfa96aecaf5b404755ba3dfba0b7e8.svn-base
  64. 16 0
      iamberry-app-international/.svn/pristine/e4/e43a492614f0727399ffdb3e905804afe9d5e976.svn-base
  65. 225 0
      iamberry-app-international/.svn/pristine/e7/e7142d3a63215aae63ce15d5fc9edc2c700574bd.svn-base
  66. 279 0
      iamberry-app-international/.svn/pristine/e9/e976cfdd82b4e49c7ef7470f148d4c19d0c0b878.svn-base
  67. 42 0
      iamberry-app-international/.svn/pristine/e9/e9b6c776a48fe323db4cdf51277f3c9a767aa1be.svn-base
  68. 135 0
      iamberry-app-international/.svn/pristine/ee/ee58651af845cebfbbc1b4074a47603375032868.svn-base
  69. 25 0
      iamberry-app-international/.svn/pristine/fb/fb18f58e6853e18e5b708b31d03f7d25872b4325.svn-base
  70. 23 0
      iamberry-app-international/.svn/pristine/fd/fd923f0c62097e8d78d4b67f23323131bae06cf4.svn-base
  71. 二進制
      iamberry-app-international/.svn/wc.db
  72. 98 0
      iamberry-app-international/pom.xml
  73. 26 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/controller/ApkDownload.java
  74. 79 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/controller/BaseController.java
  75. 50 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/controller/GlobalController.java
  76. 135 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/controller/MachineController.java
  77. 260 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/controller/MessageController.java
  78. 303 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/controller/MilkController.java
  79. 539 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/controller/UserController.java
  80. 37 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/model/FileModel.java
  81. 22 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/model/FormatModel.java
  82. 136 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/util/Jdpush.java
  83. 70 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/util/TokenUtil.java
  84. 389 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/util/Utility.java
  85. 24 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/util/kafka/AESBase64Util.java
  86. 31 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/util/kafka/JsonDeserializer.java
  87. 133 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/util/kafka/KafkaConsumer.java
  88. 27 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/util/kafka/SaslConfiguration.java
  89. 225 0
      iamberry-app-international/src/main/java/com/iamberry/app/international/util/languageUtil.java
  90. 68 0
      iamberry-app-international/src/main/resources/iamberry-app-api-datasource.xml
  91. 64 0
      iamberry-app-international/src/main/resources/iamberry-app-api-ioc.xml
  92. 116 0
      iamberry-app-international/src/main/resources/iamberry-app-api-mvc.xml
  93. 17 0
      iamberry-app-international/src/main/resources/iamberry-app-service-config.properties
  94. 34 0
      iamberry-app-international/src/main/resources/iamberry-app-service-mybatis.xml
  95. 10 0
      iamberry-app-international/src/main/resources/jdbc.properties
  96. 42 0
      iamberry-app-international/src/main/resources/log4j.properties
  97. 1 0
      iamberry-app-international/src/main/resources/messages_EN.properties
  98. 2 0
      iamberry-app-international/src/main/resources/messages_HK.properties
  99. 1 0
      iamberry-app-international/src/main/resources/messages_ZH.properties
  100. 0 0
      iamberry-app-international/src/main/resources/schema.schemaxml

+ 26 - 0
iamberry-app-international/.classpath

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+		<attributes>
+			<attribute name="owner.project.facets" value="java"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

+ 42 - 0
iamberry-app-international/.project

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>iamberry-app-international</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.validation.validationbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<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>

+ 13 - 0
iamberry-app-international/.settings/.jsdtscope

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main/webapp"/>
+	<classpathentry kind="src" path="target/m2e-wtp/web-resources"/>
+	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
+		<attributes>
+			<attribute name="hide" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
+	<classpathentry kind="output" path=""/>
+</classpath>

+ 3 - 0
iamberry-app-international/.settings/org.eclipse.core.resources.prefs

@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+encoding//src/main/resources=UTF-8
+encoding/<project>=UTF-8

+ 13 - 0
iamberry-app-international/.settings/org.eclipse.jdt.core.prefs

@@ -0,0 +1,13 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.8

+ 4 - 0
iamberry-app-international/.settings/org.eclipse.m2e.core.prefs

@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1

+ 22 - 0
iamberry-app-international/.settings/org.eclipse.wst.common.component

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+    <wb-module deploy-name="iamberry-app-international">
+        <wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
+        <wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
+        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
+        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
+        <dependent-module archiveName="iamberry-app-international-service-1.0.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/iamberry-app-international-service/iamberry-app-international-service">
+            <dependency-type>uses</dependency-type>
+        </dependent-module>
+        <dependent-module archiveName="iamberry-common-tool-1.0.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/iamberry-common-tool/iamberry-common-tool">
+            <dependency-type>uses</dependency-type>
+        </dependent-module>
+        <dependent-module archiveName="iamberry-app-interface-1.0.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/iamberry-app-interface/iamberry-app-interface">
+            <dependency-type>uses</dependency-type>
+        </dependent-module>
+        <dependent-module archiveName="iamberry-common-core-1.0.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/iamberry-common-core/iamberry-common-core">
+            <dependency-type>uses</dependency-type>
+        </dependent-module>
+        <property name="context-root" value="iamberry-app-international"/>
+        <property name="java-output-path" value="/iamberry-app-international/target/classes"/>
+    </wb-module>
+</project-modules>

+ 7 - 0
iamberry-app-international/.settings/org.eclipse.wst.common.project.facet.core.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+  <fixed facet="wst.jsdt.web"/>
+  <installed facet="jst.web" version="2.3"/>
+  <installed facet="wst.jsdt.web" version="1.0"/>
+  <installed facet="java" version="1.8"/>
+</faceted-project>

+ 1 - 0
iamberry-app-international/.settings/org.eclipse.wst.jsdt.ui.superType.container

@@ -0,0 +1 @@
+org.eclipse.wst.jsdt.launching.baseBrowserLibrary

+ 1 - 0
iamberry-app-international/.settings/org.eclipse.wst.jsdt.ui.superType.name

@@ -0,0 +1 @@
+Window

+ 2 - 0
iamberry-app-international/.settings/org.eclipse.wst.validation.prefs

@@ -0,0 +1,2 @@
+disabled=06target
+eclipse.preferences.version=1

+ 1 - 0
iamberry-app-international/.svn/entries

@@ -0,0 +1 @@
+12

+ 1 - 0
iamberry-app-international/.svn/format

@@ -0,0 +1 @@
+12

+ 293 - 0
iamberry-app-international/.svn/pristine/00/00dd6395ecb5e57bffec86910b6eb705956a38f8.svn-base

@@ -0,0 +1,293 @@
+package com.iamberry.app.international.controller;
+
+import static com.iamberry.app.config.Response.BARCODE_NOT_FOUND;
+import static com.iamberry.app.config.Response.INVALID_TOKEN;
+import static com.iamberry.app.config.Response.SUCCESS;
+import static com.iamberry.app.config.Response.INSERT_DUPLICATE;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.dao.DataAccessException;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.iamberry.app.config.APIStatus;
+import com.iamberry.app.config.Response;
+import com.iamberry.app.config.ResponseHeader;
+import com.iamberry.app.core.dto.RecordDTO;
+import com.iamberry.app.core.entity.MilkImages;
+import com.iamberry.app.core.entity.MilkMakingRecord;
+import com.iamberry.app.core.entity.MilkPowderInfo;
+import com.iamberry.app.core.entity.User;
+import com.iamberry.wechat.file.FileUtils;
+import com.iamberry.wechat.file.UploadResultBean;
+
+/**
+ * UserController
+ *
+ * @author Moon Cheng
+ * @date 2016年1月18日 上午11:53:04
+ */
+@Controller
+@RequestMapping("/secure/milk")
+public class MilkController extends BaseController {
+
+	@InitBinder("makingRecord")
+	public void initBinderRecord(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("makingRecord.");
+	}
+
+	@InitBinder("milkPowderInfo")
+	public void initBinderMilkPowder(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("milkPowderInfo.");
+	}
+
+	/**
+	 * 添加冲奶信息 
+	 * @author Moon Cheng
+	 * @param token 唯一标识符 
+	 * @param makingRecord 冲奶信息实体类
+	 * @return 1000:请求成功;2100:无效token;
+	 */
+	@RequestMapping(value = "/set_milk_making_record", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMilkMakingRecord(@RequestParam("token") String token, MilkMakingRecord makingRecord) {
+		makingRecord = milkService.setMilkMakingRecord(makingRecord, token);
+		if (makingRecord == null) {
+			return INVALID_TOKEN;
+		}
+		return SUCCESS.setData(makingRecord, 1);
+	}
+
+	/**
+	 *  通过日期,日期类型,统计某时间的,冲奶总量
+	 * @param token   唯一标识符
+	 * @param dateStatus 标识符 : day week year 
+	 * @param chosenDate 结束时间
+	 * @param machineMac 机器mac地址
+	 * @return
+	 */
+	@RequestMapping(value = "/search_user_records_by_time", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchUserRecordsByTime(@RequestParam(value = "token") String token,
+			@RequestParam("date_status") String dateStatus, @RequestParam("chosen_date") String chosenDate,
+			@RequestParam("devid") String machineMac) {
+
+		User userInfo = userService.validateUserToken(token);
+		if (userInfo == null) {
+			return INVALID_TOKEN;
+		}
+		Map<String, List<RecordDTO>> makingRecords = milkService.searchUserRecordsByTime(userInfo.getId(), dateStatus,
+				chosenDate, machineMac);
+		return SUCCESS.setData(makingRecords, makingRecords.size());
+	}
+
+	/**
+	 * 通过冲奶记录id获取冲奶记录详情
+	 * @author Moon Cheng
+	 * @param recordId 冲奶记录,id
+	 * @return 
+	 *//*
+	@RequestMapping(value = "/search_user_record_by_id", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchUserRecordById(@RequestParam(value = "record_id") Long recordId) {
+		MilkMakingRecord makingRecord = milkService.searchUserRecordById(recordId);
+		return SUCCESS.setData(makingRecord, 1);
+	}*/
+
+	/**
+	 * 根据用户id获取用户,冲奶总容量
+	 * @author Moon Cheng
+	 * @param userId  用户id 
+	 * @return
+	 */
+	@RequestMapping(value = "/get_user_total_milk_volume", method = RequestMethod.POST)
+	@ResponseBody
+	private Response getTotalMilkVolumeMadeByUser(@RequestParam(value = "user_id") Long userId) {
+		return SUCCESS.setData(milkService.getTotalMilkVolumeMadeByUser(userId), 0);
+	}
+
+	/**
+	 * 手动添加,奶粉信息!
+	 * @author Moon Cheng
+	 * @param token  唯一标识符
+	 * @param milkPowderInfo  奶粉信息
+	 * @return
+	 */
+	@RequestMapping(value = "/set_milk_powder_info", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMilkPowderInfo(@RequestParam(value = "token") String token, MilkPowderInfo milkPowderInfo) {
+		if(milkPowderInfo.getBar_code() == null){
+			return INVALID_TOKEN;
+		}
+		MilkPowderInfo	milkInfo = milkService.selectMilkPowderByBar(milkPowderInfo.getBar_code());
+		if(milkInfo != null){
+			return INSERT_DUPLICATE;
+		}
+		
+		// 勺量,每勺多少克     量勺 克数范围2-18
+		String amountStr = request.getParameter("a_mount");
+		if (amountStr == null) {
+			// 兼容低版本
+			milkPowderInfo = milkService.setMilkPowderInfo(milkPowderInfo, token);
+			if (milkPowderInfo == null) {
+				return INVALID_TOKEN;
+			}
+			return SUCCESS.setData(milkPowderInfo, 1);
+		}
+		
+		float amount = Float.parseFloat(amountStr);
+		// 勺数,多少少		量勺勺数范围 1-10
+		int spoonNum = Integer.parseInt(request.getParameter("spoon_num"));
+		// ML,1勺多少奶量  水量范围30-300
+		float spoonML = Float.parseFloat(request.getParameter("spoon_ml"));
+		
+		// 毫升/勺	
+		float s = spoonML / spoonNum;
+		
+		// 混合比 计算公式:勺量   * 勺数  / 毫升 / 100 = 混合比
+		float ratio = amount * spoonNum / spoonML * 100;
+		milkPowderInfo.setPowder_ratio(ratio);
+		milkPowderInfo.setWeight_per_spoon(amount);
+		milkPowderInfo.setMilk_volume_per_spoon(s);
+		
+		// 密度
+		/*
+		 *     A<13.2                6
+			   13.21<A<15.3          7
+			   15.31<A<17.4          8 
+			   17.41<A<19.5          9
+			   19.51<A<22.0         10 
+			   22.1 <A              10
+		 */
+		int m = 6;
+		if (ratio < 13.2) {
+			m = 6;
+		} else if (ratio > 13.21 && ratio < 15.3) {
+			m = 7;
+		} else if (ratio > 15.31 && ratio < 17.4) {
+			m = 8;
+		} else if (ratio > 17.41 && ratio < 19.5) {
+			m = 9;
+		} else {
+			m = 10;
+		}
+		milkPowderInfo.setDensity((float)m);
+		
+		// 保存操作
+		try {
+			milkPowderInfo = milkService.setMilkPowderInfo(milkPowderInfo, token);
+		} catch (DataAccessException  e) {
+			return INSERT_DUPLICATE;
+		}
+		
+		if (milkPowderInfo == null) {
+			return INVALID_TOKEN;
+		}
+		
+		// 保存图片
+		String imageFront = request.getParameter("imageFront");
+		String imageBar = request.getParameter("imageBar");
+		String imageFeed = request.getParameter("imageFeed");
+		MilkImages images = new MilkImages();
+		images.setImage_Front(imageFront);
+		images.setImage_Bar(imageBar);
+		images.setImage_Feed(imageFeed);
+		images.setImage_Milk_ID(milkPowderInfo.getId());
+		milkService.setMilkImages(images);
+		return SUCCESS.setData(milkPowderInfo, 1);
+	}
+
+	/**
+	 * 通过,条形码获取奶粉信息
+	 * @author Moon Cheng
+	 * @param barcode 条形码code
+	 * @return
+	 */
+	@RequestMapping(value = "/search_milk_powder_info_by_barcode", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkPowderInfoByBarCode(@RequestParam(value = "barcode") String barcode) {
+		MilkPowderInfo milkPowderInfo = milkService.searchMilkPowderInfoByBarCode(barcode);
+		if (milkPowderInfo == null) {
+			return BARCODE_NOT_FOUND;
+		}
+		return SUCCESS.setData(milkPowderInfo, 1);
+	}
+
+	/**
+	 * 铜鼓品牌名获取奶粉信息
+	 * @author Moon Cheng, Yin
+	 * @param brand 品牌名
+	 * @return
+	 */
+	@RequestMapping(value = "/search_milk_powder_infos_by_brand", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkPowderInfosByBrand(@RequestParam(value = "brand") String brand) {
+		Map<String, List<String>> milkPowderInfos = milkService.searchMilkPowderInfosByBrand(brand);
+		return SUCCESS.setData(milkPowderInfos, milkPowderInfos.size());
+	}
+
+	/**
+	 * 获取奶粉品牌
+	 * @author Yin 
+	 * @return  过滤掉品牌名中有.的 例如 a.b 这里或只查询到a
+	 */
+	@RequestMapping(value = "/search_milk_powder_brand", method = RequestMethod.GET)
+	@ResponseBody
+	private Response searchMilkPowderBrand() {
+		List<String> milkPowderInfos = milkService.searchMilkPowderBrand();
+		return SUCCESS.setData(milkPowderInfos, milkPowderInfos.size());
+	}
+
+	/**
+	 * 通过奶粉品牌、段数、系列、查询奶粉信息
+	 * @param brand 品牌
+	 * @param series 系列
+	 * @param level 段数
+	 * @return
+	 */
+/*	@RequestMapping(value = "/search_milk_info_by_brand_series_level", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkInfoByBrandSeriesLevel(@RequestParam("brand") String brand,
+			@RequestParam("series") String series, @RequestParam("level") String level) {
+		return SUCCESS.setData(milkService.searchMilkInfoByBrandSeriesLevel(brand, series, level), 1);
+	}*/
+
+	/**
+	 * 上传奶粉信息的域名,及保存的路径,需要tomcat单独域名映射/或者是nginx
+	 */
+	private static String SAVE_MILK_IMAGE_DOMAIN = "http://milk.iamberry.com/";
+	private static String SAVE_MILK_IMAGE_PATH = "/common/";
+	/**
+	 * @param model
+	 * @param request
+	 * @return
+	 */
+	@ResponseBody
+	@RequestMapping(value = "/upload_image", method = RequestMethod.POST)
+	public Response uploadFileImage(@RequestParam("file")MultipartFile[] files, HttpServletRequest request) {
+		Map<String, String> filemap= new HashMap<String, String>();
+		
+		for (int i = 0; i < files.length; i++) {
+			MultipartFile file = files[i];
+			// 保存文件
+			UploadResultBean bean = FileUtils.saveFile(request.getServletContext(), file, SAVE_MILK_IMAGE_PATH, false);
+			if (bean == null) {
+				// 文件有误
+				return new Response(new ResponseHeader(4204, "文件有误!", -1));
+			}
+			filemap.put("file"+i,SAVE_MILK_IMAGE_DOMAIN + bean.getSaveFileName());
+		}
+		return SUCCESS.setData(filemap, filemap.size());
+	}
+}

+ 532 - 0
iamberry-app-international/.svn/pristine/0c/0ccd285d125bcc90af70c3f129fc99f1eaf17730.svn-base

@@ -0,0 +1,532 @@
+package com.iamberry.app.international.controller;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.FileUtils;
+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.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import sun.misc.BASE64Decoder;
+
+import com.iamberry.app.config.Constants;
+import com.iamberry.app.config.Response;
+import com.iamberry.app.config.ResponseHeader;
+import com.iamberry.app.core.dto.RemoteIpInfoDTO;
+import com.iamberry.app.core.dto.UserDTO;
+import com.iamberry.app.core.entity.User;
+import com.iamberry.app.international.util.TokenUtil;
+import com.iamberry.app.international.util.Utility;
+import com.iamberry.app.tool.util.AES;
+import com.iamberry.wechat.file.FileType;
+
+/**
+ * UserController
+ *
+ * @author Moon Cheng
+ * @date 2016年1月18日 上午11:53:04
+ */
+@Controller
+@RequestMapping("/secure/user")
+public class UserController extends BaseController {
+
+	@Autowired
+	HttpServletResponse response;
+	
+	private Logger logger = LoggerFactory.getLogger(UserController.class);
+	
+	// 保存用户头像的路径
+	private String saveRootPath = "/common/user_head/";
+	private String domain = "http://hk.iamberry.com";
+
+	@InitBinder("user")
+	public void initBinderUser(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("user.");
+	}
+
+	/**
+	 * 用户手机注册,成功返回json格式的用户信息
+	 * @author Moon Cheng
+	 * @param phone 手机号码
+	 * @param verificationCode 手机收到的短信验证码
+	 * @param password 密码
+	 * @param areacode  地区参数 +86 +866港澳台........
+	 * @return 2101:验证码错误;2102:验证码超时;1000:请求成功;2000:注册失败;
+	 */
+	@RequestMapping(value = "/register", method = RequestMethod.POST)
+	@ResponseBody
+	private Response register(@RequestParam("phone") String phone,
+			@RequestParam("verification_code") String verificationCode,
+			@RequestParam("password") String password,
+			@RequestParam("areacode") String areacode
+			) {
+		User user = new User();
+		int status = checkVerifyCode(phone, verificationCode, 1); //验证手机验证码是否正确
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else
+			if (status == 1) { //验证成功
+			String ip = Utility.getIp(request);
+			user = userService.register(areacode+","+phone, password, ip); 
+			if (user == null) {//注册失败
+				return Response.FAILURE;
+			}
+		}
+		//注册成功,返回用户信息
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * 第三方【微信】用户手机绑定,
+	 * @author Moon Cheng
+	 * @param phone 手机号
+	 * @param openId 微信的open——id
+	 * @return 1000:请求成功;2000:注册失败;
+	 */
+	@RequestMapping(value = "/third_part_binding_phone", method = RequestMethod.POST)
+	@ResponseBody
+	private Response thirdPartBindingPhone(@RequestParam("phone") String phone,
+			@RequestParam("open_id") String openId,@RequestParam("code") String code,
+			@RequestParam("areacode") String areacode 
+			) {
+		User user = new User();
+		int status = checkVerifyCode(phone, code, 1); //验证手机验证码是否正确
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} 
+		user = userService.thirdPartBindingPhone(areacode+","+phone, openId);
+		if (user == null) {
+			return Response.USER_NOT_EXIST;
+		}
+		
+		logger.info(user.getId() + "," + (user.getId().intValue() == 2011));
+		
+		if (user.getPassword() != null && user.getPassword().equals("EXTIES")) {
+			ResponseHeader header = new ResponseHeader(2011, "用户已经存在!", 1);
+			UserDTO dto = userService.tuyaConnect(user);
+			return new Response(header, dto);
+		}
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * login
+	 * 手机号登录,
+	 * @param phone 手机号
+	 * @param password 密码
+	 * @return 2012:身份验证失败;2013:账户冻结;1000:请求成功;
+	 */
+	@RequestMapping(value = "/login", method = RequestMethod.POST)
+	@ResponseBody
+	private Response login(@RequestParam(value = "phone", required = true) String phone,
+			@RequestParam(value = "password", required = true) String password) {
+		Object user = userService.login(phone, password);
+		int status = 0;
+		if (user instanceof Integer) {
+			status = (Integer) user;
+			switch (status) { 
+			case -1: //账号不存在
+				return Response.USER_NOT_EXIST;
+			case -2: //密码错误
+				return Response.AUTHENTICATION_ERROR;
+			case -3: //用户状态不正常
+				return Response.USER_FROZEN_ERROR;
+			}
+		}
+		return Response.SUCCESS.setData((UserDTO) user, 1);
+	}
+
+	/**
+	 * thirdPartLogin
+	 * 第三方登录
+	 * @param openId 微信open_id 
+	 * @param extType 来源 qq或者微信
+	 * @param extName extname
+	 * @param extPicture 图片
+	 * @return 2012:身份验证失败;2013:账户冻结;1000:请求成功;
+	 */
+	@RequestMapping(value = "/third_part_login", method = RequestMethod.POST)
+	@ResponseBody
+	private Response thirdPartLogin(@RequestParam(value = "open_id") String openId,
+			@RequestParam(value = "ext_type") String extType, @RequestParam(value = "ext_name") String extName,
+			@RequestParam(value = "ext_picture") String extPicture
+			) {
+		String ip = Utility.getIp(request);
+		User user1 = userService.thirdPartLogin(openId, extType, extName, extPicture, ip);
+
+		if (Constants.USER_INACTIVE.equals(user1.getStatus_())) {
+			return Response.USER_FROZEN_ERROR;
+		}
+ // 这里不注册涂鸦,给涂鸦账号,密码
+		UserDTO userInfo = new UserDTO(user1.getId(), user1.getUsername(), user1.getPassword(), user1.getToken(), user1.getDisplay_name(),
+				user1.getDisplay_picture(), user1.getCreated_on(), user1.getExt_open_id(), user1.getExt_name(), user1.getExt_type(),
+				user1.getLocation(), user1.getBaby_nickname() == null? "寶寶" : user1.getBaby_nickname(), user1.getBaby_dob(), user1.getBaby_gender(), user1.getStatus_());
+		userInfo.setPassword(null);
+		userInfo.setCountry_code(user1.getCountry_code());
+		userInfo.setEncryptUsername(AES.encrypt(user1.getUsername()));
+		userInfo.setUserCode("iamberry123");
+		userInfo.setIs_perfect_user(user1.getIs_perfect_user() == null? 1 : user1.getIs_perfect_user());
+		
+		return Response.SUCCESS.setData(userInfo);
+	}
+
+	/**
+	 * getUserInfo
+	 * 获取用户基本信息
+	 * @param id 用户id
+	 * @token  用户token 登录的时候设置的唯一的token
+	 * @return Response 2100:无效token;2020:无效用户;1000:请求成功;
+	 */
+	@RequestMapping(value = "/get_user_info", method = RequestMethod.POST)
+	@ResponseBody
+	private Response getUserInfo(@RequestParam(value = "user_id", required = true) Long id,
+			@RequestParam("token") String token) {
+		User userInfo = userService.validateUserToken(token);
+		if (userInfo == null) {//token不存在,表示登录的时候没有..
+			return Response.INVALID_TOKEN;
+		}
+		User user = userService.findById(id);
+		if (user == null) { //未找到
+			return Response.INVALID_PARMS;
+		}
+		return Response.SUCCESS.setData(user, 1);
+	}
+
+	/**
+	 * updateProfile
+	 * 更新用户基本信息
+	 * @param user 用户信息
+	 * @param token token
+	 * @return Response 2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/update_profile", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateProfile(User user, @RequestParam("token") String token) {
+		User user1 = userService.updateUserInfo(user, token);
+		if (user1 == null) {
+			return Response.INVALID_TOKEN;
+		}
+//		userInfo.setEncryptUsername(AES.encrypt(user.getUsername()));
+//		userInfo.setUserCode("iamberry123");
+		
+		UserDTO userInfo = new UserDTO(user1.getId(), user1.getUsername(), user1.getPassword(), user1.getToken(), user1.getDisplay_name(),
+				user1.getDisplay_picture(), user1.getCreated_on(), user1.getExt_open_id(), user1.getExt_name(), user1.getExt_type(),
+				user1.getLocation(), user1.getBaby_nickname(), user1.getBaby_dob(), user1.getBaby_gender(), user1.getStatus_());
+		userInfo.setPassword(null);
+		userInfo.setCountry_code(user1.getCountry_code());
+		userInfo.setEncryptUsername(AES.encrypt(user1.getUsername()));
+		userInfo.setUserCode("iamberry123");
+		return Response.SUCCESS.setData(userInfo, 1);
+	}
+
+	private BASE64Decoder decoder = new BASE64Decoder();  
+	
+	/**
+	 * updateDisplayPicture
+	 * 更改用户头像
+	 * @param user 用户信息
+	 * @param token 唯一标识符
+	 * @return Response
+	 * @throws IOException 
+	 */
+	@RequestMapping(value = "/update_display_picture", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateDisplayPicture(@RequestParam("picture_base64") String pictureBase64,
+			@RequestParam("token") String token, HttpServletRequest request) throws IOException {
+		// 判断文件类型
+		byte [] b = new byte[28];
+		pictureBase64.getBytes(0, 27, b, 0);
+		String temp = new String(b);
+		try {
+			b = decoder.decodeBuffer(temp);
+		} catch (IOException e) {
+			logger.error("updateDisplayPicture:" + e.getMessage());
+			return Response.FAILURE;
+		}
+		String type = null;					// 文件类型
+		String fileHead = byte2hex(b);		// 文件头
+		fileHead = fileHead.toUpperCase();
+		type = getType(fileHead);
+		if (type == null) {
+			return Response.FAILURE;
+		}
+		// 获取保存地址
+		String savePath = request.getServletContext().getRealPath(saveRootPath);
+		StringBuilder tempDir = new StringBuilder(savePath);
+		Long ran = new Date().getTime();
+		tempDir.append(File.separator);
+		tempDir.append(ran);
+		tempDir.append(File.separator);
+		// 判断保存路径是否存在,如果不存在,那么创建
+		File file=new File(savePath);
+		if (!file.exists()) {
+			logger.info("updateDisplayPicture-exists");
+			file.mkdirs();
+		}
+		// 获取保存文件名称
+		StringBuilder saveName = new StringBuilder(TokenUtil.getToken());
+		saveName.append(".").append(type);
+		tempDir.append(saveName);
+		// 保存磁盘
+		String userHeadURL = null;
+		if (!generateImage(pictureBase64, tempDir.toString())) {
+			logger.error("updateDisplayPicture-generateImage saveFile Error");
+			return Response.FAILURE;
+		} else {
+			userHeadURL = domain + request.getContextPath() + saveRootPath + ran + "/" + saveName.toString();
+		}
+		// 保存
+		String path = userService.updateDisplayPicture(userHeadURL, token);
+		return Response.SUCCESS.setData(path, 1);
+	}
+	
+	private String getType(String fileHead) {
+		FileType [] fileTypes = FileType.values();
+		for (FileType fileType : fileTypes) {
+			if (fileHead.startsWith(fileType.getValue())) {
+				return fileType.getSuffix();
+			}
+		}
+		return null;
+	}
+	
+	private boolean generateImage(String imgStr, String imgFilePath) throws IOException {  
+		// Base64解码  
+		byte[] bytes = decoder.decodeBuffer(imgStr);
+		for (int i = 0; i < bytes.length; ++i) {  
+			if (bytes[i] < 0) {
+				// 调整异常数据  
+				bytes[i] += 256;  
+			}  
+		}  
+		// 生成图片 
+		File file = new File(imgFilePath);
+		FileUtils.writeByteArrayToFile(file, bytes);
+		return true;  
+	}
+
+	private String byte2hex(byte[] b) {
+       // 转成16进制字符串
+       String hs = "";
+       String tmp = "";
+       for (int n = 0; n < b.length; n++) {
+           //整数转成十六进制表示
+           tmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
+           if (tmp.length() == 1) {
+               hs = hs + "0" + tmp;
+           } else {
+               hs = hs + tmp;
+           }
+       }
+       tmp = null;
+       return hs;
+   }
+
+	/**
+	 * 此方法可以不再使用
+	 */
+	@RequestMapping(value = "/avator/{id}/{rand}", method = RequestMethod.GET)
+	@ResponseBody
+	@Deprecated
+	private void getDisplayPicture() {
+		String url = request.getRequestURI();
+		url = url.substring(0, url.lastIndexOf('/'));
+		String userID = url.substring(url.lastIndexOf('/') + 1);
+		String avator = userService.selectUserAvator(Long.valueOf(userID));
+		response.setContentType("image/jpg");
+		try {
+			OutputStream os = response.getOutputStream();
+			BASE64Decoder decoder = new BASE64Decoder();
+			byte[] decoderBytes = decoder.decodeBuffer(avator);
+			os.write(decoderBytes);
+			os.flush();
+			os.close();
+		} catch (Exception e) {
+			// TODO: handle exception
+		}
+	}
+
+	/**
+	 * changePassword
+	 * 修改手机密码
+	 * @param oldPassword 新密码
+	 * @param newPassword 旧密码
+	 * @param token token
+	 * @return Response 2101:验证码错误;2102:验证码超时;2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/change_password", method = RequestMethod.POST)
+	@ResponseBody
+	private Response changePassword(@RequestParam("old_password") String oldPassword,
+			@RequestParam("new_password") String newPassword, @RequestParam("token") String token) {
+		int status = userService.changePassword(oldPassword, newPassword, token);
+		if (status == -1) { //token错误
+			return Response.INVALID_TOKEN;
+		} else if (status == 0) { //密码错误
+			return Response.ERROR_OLDPASSWORD;
+		} else { 
+			return Response.SUCCESS.setData(null);
+		}
+	}
+
+	/**
+	 * changePhone
+	 * 修改手机号码
+	 * @author Moon Cheng, Yin
+	 * @param newPhone 新手机号
+	 * @param token token
+	 * @param verificationCode 手机验证码
+	 * @return2101:验证码错误;2102:验证码超时;2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/change_phone", method = RequestMethod.POST)
+	@ResponseBody
+	private Response changePhone(@RequestParam("new_phone") String newPhone,
+			@RequestParam("verification_code") String verificationCode, @RequestParam("token") String token) {
+		int status = checkVerifyCode(newPhone, verificationCode, 2);
+		User user = null;
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else if (status == 1) { 
+			user = userService.changePhone(newPhone, token);
+			if (user == null) {
+				return Response.INVALID_TOKEN;
+			}
+		}
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * resetPassword
+	 * 重置手机密码
+	 * @param username 用户米
+	 * @param newPassword 新密码
+	 * @param verificationCode 验证码
+	 * @return2101:验证码错误;2102:验证码超时;2001:无效用户;2000:重置密码失败; 1000:请求成功;
+	 */
+	@RequestMapping(value = "/reset_password", method = RequestMethod.POST)
+	@ResponseBody
+	private Response resetPassword(@RequestParam(value = "username") String username,
+			@RequestParam("new_password") String newPassword,
+			@RequestParam("verification_code") String verificationCode) {
+		int status = checkVerifyCode(username, verificationCode, 3);
+		if (status == -1) {//验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else if (status == 1) { 
+			status = userService.resetPassWord(username, newPassword);
+			if (status == -3) {//账号不存在
+				return Response.USER_NOT_EXIST; 
+			} else if (status == 0) {
+				return Response.FAILURE;
+			}
+		}
+
+		return Response.SUCCESS.setData(null);
+	}
+
+	/**
+	 * 发送手机验证码
+	 * @param phone 手机号 
+	 * @param statusCode  1代表注册,2代表更换手机号,3代表忘记密码
+	 * @return
+	 */
+	@RequestMapping(value = "/send_code", method = RequestMethod.GET)
+	@ResponseBody
+	private Response sendCode(@RequestParam("phone") String phone, @RequestParam("status_code") int statusCode,@RequestParam("areacode") String areacode) {
+		String code = null;
+		Map<String, Integer> status = new HashMap<>();
+		User user = new User();
+		try {
+			/*switch (statusCode) {
+			case 1:// register
+				user = userService.selectUserByUsername(phone);
+				if (user != null) {
+					return Response.ERROR_REGISTER;
+				}
+				
+				break;
+			case 2:// change phone
+				user = userService.selectUserByUsername(phone);
+				if (user != null) {
+					return Response.ERROR_REGISTER;
+				}
+
+				break;
+			case 3:// reset password
+				user = userService.selectUserByUsername(phone);
+				if (user == null) {
+					return Response.USER_NOT_EXIST;
+				}
+
+				break;
+			default:
+				break;
+			}*/
+			codeService.sendCode(areacode+","+phone, statusCode);
+			status.put("code", 0);
+		} catch (Exception e) {
+			System.out.println(e);
+			return Response.SERVER_INTERNAL_ERROR;
+		}
+		if (0 == status.get(Constants.SMS_RETURNCODE)) {
+			return Response.SUCCESS.setData(code, 0);
+		} else {
+			return Response.FAILURE.setHeader(new ResponseHeader(status.get(Constants.SMS_RETURNCODE), "", 0));
+		}
+	}
+
+	/**
+	 * 获取封面图片
+	 * @return json
+	 */
+	@RequestMapping(value = "/start_page", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getStartPage() {
+		String pageUrl = userService.getStartPage();
+		return Response.SUCCESS.setData(pageUrl, 1);
+	}
+
+	/**
+	 * 获取地址url
+	 * @return
+	 */
+	@RequestMapping(value = "/get_location", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getLocation() {
+		String IP = Utility.getIp(request);
+		 //String IP = "183.14.17.153";
+		RemoteIpInfoDTO remoteIpInfoDTO = userService.getLocation(IP);
+		return Response.SUCCESS.setData(remoteIpInfoDTO, 1);
+	}
+	
+	/**
+	 * 获取app版本号
+	 * @return
+	 */
+	@RequestMapping(value = "/get_version", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getApkVersion() {
+		return Response.SUCCESS.setData(userService.getApkVersion());
+	}
+}

+ 539 - 0
iamberry-app-international/.svn/pristine/0c/0cd66c3deb003dda343cc5ca361352a77faf81f0.svn-base

@@ -0,0 +1,539 @@
+package com.iamberry.app.international.controller;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.FileUtils;
+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.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import sun.misc.BASE64Decoder;
+
+import com.iamberry.app.config.Constants;
+import com.iamberry.app.config.Response;
+import com.iamberry.app.config.ResponseHeader;
+import com.iamberry.app.core.dto.RemoteIpInfoDTO;
+import com.iamberry.app.core.dto.UserDTO;
+import com.iamberry.app.core.entity.User;
+import com.iamberry.app.international.util.TokenUtil;
+import com.iamberry.app.international.util.Utility;
+import com.iamberry.app.tool.util.AES;
+import com.iamberry.wechat.file.FileType;
+
+/**
+ * UserController
+ *
+ * @author Moon Cheng
+ * @date 2016年1月18日 上午11:53:04
+ */
+@Controller
+@RequestMapping("/secure/user")
+public class UserController extends BaseController {
+
+	@Autowired
+	HttpServletResponse response;
+	
+	private Logger logger = LoggerFactory.getLogger(UserController.class);
+	
+	// 保存用户头像的路径
+	private String saveRootPath = "/common/user_head/";
+	private String domain = "http://hk.iamberry.com";
+
+	@InitBinder("user")
+	public void initBinderUser(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("user.");
+	}
+
+	/**
+	 * 用户手机注册,成功返回json格式的用户信息
+	 * @author Moon Cheng
+	 * @param phone 手机号码
+	 * @param verificationCode 手机收到的短信验证码
+	 * @param password 密码
+	 * @param areacode  地区参数 +86 +866港澳台........
+	 * @return 2101:验证码错误;2102:验证码超时;1000:请求成功;2000:注册失败;
+	 */
+	@RequestMapping(value = "/register", method = RequestMethod.POST)
+	@ResponseBody
+	private Response register(@RequestParam("phone") String phone,
+			@RequestParam("verification_code") String verificationCode,
+			@RequestParam("password") String password,
+			@RequestParam("areacode") String areacode
+			) {
+		User user = new User();
+		int status = checkVerifyCode(phone, verificationCode, 1); //验证手机验证码是否正确
+		status = 1;
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else
+			if (status == 1) { //验证成功
+			User users = userService.selectUserByUsername(phone);
+				if(users == null){
+					String ip = Utility.getIp(request);
+					user = userService.register(areacode+","+phone, password, ip); 
+					if (user == null) {//注册失败
+						return Response.FAILURE;
+					}
+				}else{
+					return Response.ERROR_REGISTER;
+				}
+		}
+		System.out.println(phone+"-注册成功!请求涂鸦");
+		//注册成功,返回用户信息
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * 第三方【微信】用户手机绑定,
+	 * @author Moon Cheng
+	 * @param phone 手机号
+	 * @param openId 微信的open——id
+	 * @return 1000:请求成功;2000:注册失败;
+	 */
+	@RequestMapping(value = "/third_part_binding_phone", method = RequestMethod.POST)
+	@ResponseBody
+	private Response thirdPartBindingPhone(@RequestParam("phone") String phone,
+			@RequestParam("open_id") String openId,@RequestParam("code") String code,
+			@RequestParam("areacode") String areacode 
+			) {
+		User user = new User();
+		int status = checkVerifyCode(phone, code, 1); //验证手机验证码是否正确
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} 
+		user = userService.thirdPartBindingPhone(areacode+","+phone, openId);
+		if (user == null) {
+			return Response.USER_NOT_EXIST;
+		}
+		
+		logger.info(user.getId() + "," + (user.getId().intValue() == 2011));
+		
+		if (user.getPassword() != null && user.getPassword().equals("EXTIES")) {
+			ResponseHeader header = new ResponseHeader(2011, "用户已经存在!", 1);
+			UserDTO dto = userService.tuyaConnect(user);
+			return new Response(header, dto);
+		}
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * login
+	 * 手机号登录,
+	 * @param phone 手机号
+	 * @param password 密码
+	 * @return 2012:身份验证失败;2013:账户冻结;1000:请求成功;
+	 */
+	@RequestMapping(value = "/login", method = RequestMethod.POST)
+	@ResponseBody
+	private Response login(@RequestParam(value = "phone", required = true) String phone,
+			@RequestParam(value = "password", required = true) String password) {
+		Object user = userService.login(phone, password);
+		int status = 0;
+		if (user instanceof Integer) {
+			status = (Integer) user;
+			switch (status) { 
+			case -1: //账号不存在
+				return Response.USER_NOT_EXIST;
+			case -2: //密码错误
+				return Response.AUTHENTICATION_ERROR;
+			case -3: //用户状态不正常
+				return Response.USER_FROZEN_ERROR;
+			}
+		}
+		return Response.SUCCESS.setData((UserDTO) user, 1);
+	}
+
+	/**
+	 * thirdPartLogin
+	 * 第三方登录
+	 * @param openId 微信open_id 
+	 * @param extType 来源 qq或者微信
+	 * @param extName extname
+	 * @param extPicture 图片
+	 * @return 2012:身份验证失败;2013:账户冻结;1000:请求成功;
+	 */
+	@RequestMapping(value = "/third_part_login", method = RequestMethod.POST)
+	@ResponseBody
+	private Response thirdPartLogin(@RequestParam(value = "open_id") String openId,
+			@RequestParam(value = "ext_type") String extType, @RequestParam(value = "ext_name") String extName,
+			@RequestParam(value = "ext_picture") String extPicture
+			) {
+		String ip = Utility.getIp(request);
+		User user1 = userService.thirdPartLogin(openId, extType, extName, extPicture, ip);
+
+		if (Constants.USER_INACTIVE.equals(user1.getStatus_())) {
+			return Response.USER_FROZEN_ERROR;
+		}
+ // 这里不注册涂鸦,给涂鸦账号,密码
+		UserDTO userInfo = new UserDTO(user1.getId(), user1.getUsername(), user1.getPassword(), user1.getToken(), user1.getDisplay_name(),
+				user1.getDisplay_picture(), user1.getCreated_on(), user1.getExt_open_id(), user1.getExt_name(), user1.getExt_type(),
+				user1.getLocation(), user1.getBaby_nickname() == null? "寶寶" : user1.getBaby_nickname(), user1.getBaby_dob(), user1.getBaby_gender(), user1.getStatus_());
+		userInfo.setPassword(null);
+		userInfo.setCountry_code(user1.getCountry_code());
+		userInfo.setEncryptUsername(AES.encrypt(user1.getUsername()));
+		userInfo.setUserCode("iamberry123");
+		userInfo.setIs_perfect_user(user1.getIs_perfect_user() == null? 1 : user1.getIs_perfect_user());
+		
+		return Response.SUCCESS.setData(userInfo);
+	}
+
+	/**
+	 * getUserInfo
+	 * 获取用户基本信息
+	 * @param id 用户id
+	 * @token  用户token 登录的时候设置的唯一的token
+	 * @return Response 2100:无效token;2020:无效用户;1000:请求成功;
+	 */
+	@RequestMapping(value = "/get_user_info", method = RequestMethod.POST)
+	@ResponseBody
+	private Response getUserInfo(@RequestParam(value = "user_id", required = true) Long id,
+			@RequestParam("token") String token) {
+		User userInfo = userService.validateUserToken(token);
+		if (userInfo == null) {//token不存在,表示登录的时候没有..
+			return Response.INVALID_TOKEN;
+		}
+		User user = userService.findById(id);
+		if (user == null) { //未找到
+			return Response.INVALID_PARMS;
+		}
+		return Response.SUCCESS.setData(user, 1);
+	}
+
+	/**
+	 * updateProfile
+	 * 更新用户基本信息
+	 * @param user 用户信息
+	 * @param token token
+	 * @return Response 2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/update_profile", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateProfile(User user, @RequestParam("token") String token) {
+		User user1 = userService.updateUserInfo(user, token);
+		if (user1 == null) {
+			return Response.INVALID_TOKEN;
+		}
+//		userInfo.setEncryptUsername(AES.encrypt(user.getUsername()));
+//		userInfo.setUserCode("iamberry123");
+		
+		UserDTO userInfo = new UserDTO(user1.getId(), user1.getUsername(), user1.getPassword(), user1.getToken(), user1.getDisplay_name(),
+				user1.getDisplay_picture(), user1.getCreated_on(), user1.getExt_open_id(), user1.getExt_name(), user1.getExt_type(),
+				user1.getLocation(), user1.getBaby_nickname(), user1.getBaby_dob(), user1.getBaby_gender(), user1.getStatus_());
+		userInfo.setPassword(null);
+		userInfo.setCountry_code(user1.getCountry_code());
+		userInfo.setEncryptUsername(AES.encrypt(user1.getUsername()));
+		userInfo.setUserCode("iamberry123");
+		return Response.SUCCESS.setData(userInfo, 1);
+	}
+
+	private BASE64Decoder decoder = new BASE64Decoder();  
+	
+	/**
+	 * updateDisplayPicture
+	 * 更改用户头像
+	 * @param user 用户信息
+	 * @param token 唯一标识符
+	 * @return Response
+	 * @throws IOException 
+	 */
+	@RequestMapping(value = "/update_display_picture", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateDisplayPicture(@RequestParam("picture_base64") String pictureBase64,
+			@RequestParam("token") String token, HttpServletRequest request) throws IOException {
+		// 判断文件类型
+		byte [] b = new byte[28];
+		pictureBase64.getBytes(0, 27, b, 0);
+		String temp = new String(b);
+		try {
+			b = decoder.decodeBuffer(temp);
+		} catch (IOException e) {
+			logger.error("updateDisplayPicture:" + e.getMessage());
+			return Response.FAILURE;
+		}
+		String type = null;					// 文件类型
+		String fileHead = byte2hex(b);		// 文件头
+		fileHead = fileHead.toUpperCase();
+		type = getType(fileHead);
+		if (type == null) {
+			return Response.FAILURE;
+		}
+		// 获取保存地址
+		String savePath = request.getServletContext().getRealPath(saveRootPath);
+		StringBuilder tempDir = new StringBuilder(savePath);
+		Long ran = new Date().getTime();
+		tempDir.append(File.separator);
+		tempDir.append(ran);
+		tempDir.append(File.separator);
+		// 判断保存路径是否存在,如果不存在,那么创建
+		File file=new File(savePath);
+		if (!file.exists()) {
+			logger.info("updateDisplayPicture-exists");
+			file.mkdirs();
+		}
+		// 获取保存文件名称
+		StringBuilder saveName = new StringBuilder(TokenUtil.getToken());
+		saveName.append(".").append(type);
+		tempDir.append(saveName);
+		// 保存磁盘
+		String userHeadURL = null;
+		if (!generateImage(pictureBase64, tempDir.toString())) {
+			logger.error("updateDisplayPicture-generateImage saveFile Error");
+			return Response.FAILURE;
+		} else {
+			userHeadURL = domain + request.getContextPath() + saveRootPath + ran + "/" + saveName.toString();
+		}
+		// 保存
+		String path = userService.updateDisplayPicture(userHeadURL, token);
+		return Response.SUCCESS.setData(path, 1);
+	}
+	
+	private String getType(String fileHead) {
+		FileType [] fileTypes = FileType.values();
+		for (FileType fileType : fileTypes) {
+			if (fileHead.startsWith(fileType.getValue())) {
+				return fileType.getSuffix();
+			}
+		}
+		return null;
+	}
+	
+	private boolean generateImage(String imgStr, String imgFilePath) throws IOException {  
+		// Base64解码  
+		byte[] bytes = decoder.decodeBuffer(imgStr);
+		for (int i = 0; i < bytes.length; ++i) {  
+			if (bytes[i] < 0) {
+				// 调整异常数据  
+				bytes[i] += 256;  
+			}  
+		}  
+		// 生成图片 
+		File file = new File(imgFilePath);
+		FileUtils.writeByteArrayToFile(file, bytes);
+		return true;  
+	}
+
+	private String byte2hex(byte[] b) {
+       // 转成16进制字符串
+       String hs = "";
+       String tmp = "";
+       for (int n = 0; n < b.length; n++) {
+           //整数转成十六进制表示
+           tmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
+           if (tmp.length() == 1) {
+               hs = hs + "0" + tmp;
+           } else {
+               hs = hs + tmp;
+           }
+       }
+       tmp = null;
+       return hs;
+   }
+
+	/**
+	 * 此方法可以不再使用
+	 */
+	@RequestMapping(value = "/avator/{id}/{rand}", method = RequestMethod.GET)
+	@ResponseBody
+	@Deprecated
+	private void getDisplayPicture() {
+		String url = request.getRequestURI();
+		url = url.substring(0, url.lastIndexOf('/'));
+		String userID = url.substring(url.lastIndexOf('/') + 1);
+		String avator = userService.selectUserAvator(Long.valueOf(userID));
+		response.setContentType("image/jpg");
+		try {
+			OutputStream os = response.getOutputStream();
+			BASE64Decoder decoder = new BASE64Decoder();
+			byte[] decoderBytes = decoder.decodeBuffer(avator);
+			os.write(decoderBytes);
+			os.flush();
+			os.close();
+		} catch (Exception e) {
+			// TODO: handle exception
+		}
+	}
+
+	/**
+	 * changePassword
+	 * 修改手机密码
+	 * @param oldPassword 新密码
+	 * @param newPassword 旧密码
+	 * @param token token
+	 * @return Response 2101:验证码错误;2102:验证码超时;2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/change_password", method = RequestMethod.POST)
+	@ResponseBody
+	private Response changePassword(@RequestParam("old_password") String oldPassword,
+			@RequestParam("new_password") String newPassword, @RequestParam("token") String token) {
+		int status = userService.changePassword(oldPassword, newPassword, token);
+		if (status == -1) { //token错误
+			return Response.INVALID_TOKEN;
+		} else if (status == 0) { //密码错误
+			return Response.ERROR_OLDPASSWORD;
+		} else { 
+			return Response.SUCCESS.setData(null);
+		}
+	}
+
+	/**
+	 * changePhone
+	 * 修改手机号码
+	 * @author Moon Cheng, Yin
+	 * @param newPhone 新手机号
+	 * @param token token
+	 * @param verificationCode 手机验证码
+	 * @return2101:验证码错误;2102:验证码超时;2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/change_phone", method = RequestMethod.POST)
+	@ResponseBody
+	private Response changePhone(@RequestParam("new_phone") String newPhone,
+			@RequestParam("verification_code") String verificationCode, @RequestParam("token") String token) {
+		int status = checkVerifyCode(newPhone, verificationCode, 2);
+		User user = null;
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else if (status == 1) { 
+			user = userService.changePhone(newPhone, token);
+			if (user == null) {
+				return Response.INVALID_TOKEN;
+			}
+		}
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * resetPassword
+	 * 重置手机密码
+	 * @param username 用户米
+	 * @param newPassword 新密码
+	 * @param verificationCode 验证码
+	 * @return2101:验证码错误;2102:验证码超时;2001:无效用户;2000:重置密码失败; 1000:请求成功;
+	 */
+	@RequestMapping(value = "/reset_password", method = RequestMethod.POST)
+	@ResponseBody
+	private Response resetPassword(@RequestParam(value = "username") String username,
+			@RequestParam("new_password") String newPassword,
+			@RequestParam("verification_code") String verificationCode) {
+		int status = checkVerifyCode(username, verificationCode, 3);
+		if (status == -1) {//验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else if (status == 1) { 
+			status = userService.resetPassWord(username, newPassword);
+			if (status == -3) {//账号不存在
+				return Response.USER_NOT_EXIST; 
+			} else if (status == 0) {
+				return Response.FAILURE;
+			}
+		}
+
+		return Response.SUCCESS.setData(null);
+	}
+
+	/**
+	 * 发送手机验证码
+	 * @param phone 手机号 
+	 * @param statusCode  1代表注册,2代表更换手机号,3代表忘记密码
+	 * @return
+	 */
+	@RequestMapping(value = "/send_code", method = RequestMethod.GET)
+	@ResponseBody
+	private Response sendCode(@RequestParam("phone") String phone, @RequestParam("status_code") int statusCode,@RequestParam("areacode") String areacode) {
+		String code = null;
+		Map<String, Integer> status = new HashMap<>();
+		User user = new User();
+		try {
+			switch (statusCode) {
+			case 1:// register
+				user = userService.selectUserByUsername(phone);
+				if (user != null) {
+					return Response.ERROR_REGISTER;
+				}
+				
+				break;
+			case 2:// change phone
+				user = userService.selectUserByUsername(phone);
+				if (user != null) {
+					return Response.ERROR_REGISTER;
+				}
+
+				break;
+			case 3:// reset password
+				user = userService.selectUserByUsername(phone);
+				if (user == null) {
+					return Response.USER_NOT_EXIST;
+				}
+
+				break;
+			default:
+				break;
+			}
+			codeService.sendCode(areacode+","+phone, statusCode);
+			status.put("code", 0);
+		} catch (Exception e) {
+			System.out.println(e);
+			return Response.SERVER_INTERNAL_ERROR;
+		}
+		if (0 == status.get(Constants.SMS_RETURNCODE)) {
+			return Response.SUCCESS.setData(code, 0);
+		} else {
+			return Response.FAILURE.setHeader(new ResponseHeader(status.get(Constants.SMS_RETURNCODE), "", 0));
+		}
+	}
+
+	/**
+	 * 获取封面图片
+	 * @return json
+	 */
+	@RequestMapping(value = "/start_page", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getStartPage() {
+		String pageUrl = userService.getStartPage();
+		return Response.SUCCESS.setData(pageUrl, 1);
+	}
+
+	/**
+	 * 获取地址url
+	 * @return
+	 */
+	@RequestMapping(value = "/get_location", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getLocation() {
+		String IP = Utility.getIp(request);
+		 //String IP = "183.14.17.153";
+		RemoteIpInfoDTO remoteIpInfoDTO = userService.getLocation(IP);
+		return Response.SUCCESS.setData(remoteIpInfoDTO, 1);
+	}
+	
+	/**
+	 * 获取app版本号
+	 * @return
+	 */
+	@RequestMapping(value = "/get_version", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getApkVersion() {
+		return Response.SUCCESS.setData(userService.getApkVersion());
+	}
+}

+ 98 - 0
iamberry-app-international/.svn/pristine/0c/0cf71f3a620c6cd571a85d5f1ba5eef080abf47a.svn-base

@@ -0,0 +1,98 @@
+<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>
+	<parent>
+		<groupId>com.iamberry</groupId>
+		<artifactId>iamberry-parent</artifactId>
+		<version>1.0.0</version>
+	</parent>
+
+	<artifactId>iamberry-app-international</artifactId>
+	<packaging>war</packaging>
+
+	<dependencies>
+		<dependency>
+			<groupId>com.iamberry</groupId>
+			<artifactId>iamberry-app-international-service</artifactId>
+			<version>1.0.0</version>
+			<exclusions>
+				<exclusion>
+					<artifactId>spring</artifactId>
+					<groupId>org.springframework</groupId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.slf4j</groupId>
+					<artifactId>jcl-over-slf4j</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.slf4j</groupId>
+					<artifactId>slf4j-jcl</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<!-- 新的项目使用druid -->
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>druid</artifactId>
+			<version>1.0.20</version>
+		</dependency>
+		
+		<!-- 涂鸦包 -->
+		<dependency>
+            <groupId>org.springframework.integration</groupId>
+            <artifactId>spring-integration-kafka</artifactId>
+            <version>2.1.0.RELEASE</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>log4j</groupId>
+                    <artifactId>log4j</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>2.6.6</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <version>2.6.6</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.6.6</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.21</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <version>1.7.21</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>1.1.7</version>
+        </dependency>
+        <dependency>
+            <groupId>org.logback-extensions</groupId>
+            <artifactId>logback-ext-spring</artifactId>
+            <version>0.1.4</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
+            <version>1.1.7</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.14</version>
+        </dependency>
+	</dependencies>
+</project>

+ 389 - 0
iamberry-app-international/.svn/pristine/18/18136ec92a3b2dfb203eaf3d0b7a793fa62ff361.svn-base

@@ -0,0 +1,389 @@
+package com.iamberry.app.international.util;
+
+import static com.iamberry.app.config.ImberryConfig.SMS_PASSWORD;
+import static com.iamberry.app.config.ImberryConfig.SMS_TEXT;
+import static com.iamberry.app.config.ImberryConfig.SMS_URL;
+import static com.iamberry.app.config.ImberryConfig.SMS_USERNAME;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.text.MessageFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.apache.http.entity.mime.content.StringBody;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+
+import com.iamberry.app.config.Constants;
+import com.iamberry.app.core.dto.RecordDTO;
+import com.iamberry.app.tool.dto.AddressDTO;
+import com.iamberry.app.tool.util.HttpUtility;
+import com.iamberry.app.tool.util.JsonParseUtil;
+import com.iamberry.app.tool.util.Result;
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.StaxDriver;
+
+public class Utility {
+
+	public static String DATA_STORE = "";
+	private static final String AB = "123456789abcdefghijklmnpqrstuvwxyz";
+
+	private static Random rnd = new Random();
+
+	public static String getDateByDay() {
+		Calendar cal = Calendar.getInstance();
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(cal.get(Calendar.YEAR));
+		buffer.append(cal.get(Calendar.MONTH) + 1);
+		buffer.append(cal.get(Calendar.DAY_OF_MONTH));
+		return buffer.toString();
+	}
+
+	public static boolean contains(String[] array, String item) {
+		try {
+			for (int i = 0; i < array.length; i++) {
+				if (array[i].equals(item)) {
+					return true;
+				}
+			}
+		} catch (Exception ex) {
+
+		}
+		return false;
+	}
+
+	public static String normalizePath(String path) {
+		return path.replace("\\\\", "\\").replace("\\", "/").replace("//", "/").replace("..", ".");
+	}
+
+	public static String getRandomString(int len) {
+		StringBuilder sb = new StringBuilder(len);
+		for (int i = 0; i < len; i++)
+			sb.append(AB.charAt(rnd.nextInt(AB.length())));
+		return sb.toString();
+	}
+
+	public static int CalculateAge(Long date) {
+		Date birthDate = new Date(0);
+		if (date != null)
+			birthDate = new Date(date);
+		SimpleDateFormat format = new SimpleDateFormat("yyyy");
+		int birthYear = Integer.parseInt(format.format(birthDate));
+		int currentYear = Integer.parseInt(format.format(new Date(System.currentTimeMillis())));
+		int age = currentYear - birthYear;
+
+		return age;
+	}
+
+	public static List<RecordDTO> convertMap(List<Map<String, Object>> list, String dateType) {
+		List<RecordDTO> maps = new ArrayList<RecordDTO>();
+		try {
+			SimpleDateFormat sdf = null;
+			for (Map<String, Object> map : list) {
+				switch (dateType) {
+				case "days":
+					sdf = new SimpleDateFormat("yyyyMMddHH");
+					break;
+				case "weeks":
+					sdf = new SimpleDateFormat("yyyyMMdd");
+					break;
+				case "years":
+					sdf = new SimpleDateFormat("yyyyMM");
+					break;
+				}
+				Date key = sdf.parse(map.get(dateType).toString());
+				Double value = Double.parseDouble(map.get("volume").toString());
+				maps.add(new RecordDTO(key.getTime(), value));
+			}
+		} catch (Exception e) {
+		}
+		return maps;
+	}
+
+	public static Map<String, List<RecordDTO>> synAppMachineRecord(Map<String, List<RecordDTO>> oldMap) {
+		Map<String, List<RecordDTO>> synMap = oldMap;
+		int appSize = synMap.get("app").size();
+		int machineSize = synMap.get("machine").size();
+		int signer = 0;
+		long appDate = 0l, machineDate = 0l;
+		RecordDTO appRecord, machineRecord;
+		for (int i = 0; i < appSize && i < machineSize; i++) {
+			appRecord = synMap.get("app").get(i);
+			machineRecord = synMap.get("machine").get(signer);
+			appDate = appRecord.getRecordDate();
+			machineDate = machineRecord.getRecordDate();
+			if (appDate == machineDate) {
+				signer++;
+			} else if (appDate < machineDate) {
+				synMap.get("machine").add(i, new RecordDTO(appDate, 0));
+				machineSize++;
+				signer++;
+			} else {
+				synMap.get("app").add(signer, new RecordDTO(machineDate, 0));
+				appSize++;
+				signer++;
+			}
+		}
+		while (signer < machineSize) {
+			synMap.get("app").add(new RecordDTO(synMap.get("machine").get(signer).getRecordDate(), 0));
+			signer++;
+		}
+		while (signer < appSize) {
+			synMap.get("machine").add(new RecordDTO(synMap.get("app").get(signer).getRecordDate(), 0));
+			signer++;
+		}
+		return synMap;
+	}
+
+	public static Map<String, List<RecordDTO>> fillAppMachineRecordWithZero(Map<String, List<RecordDTO>> synedMap, String dataType,
+			String chosenDate) {
+		Map<String, List<RecordDTO>> fillMap = synedMap;
+		Calendar calendar = Calendar.getInstance();
+		List<Integer> existTimePoint = new ArrayList<Integer>();
+		long timePoint = 0l;
+		switch (dataType) {
+		case "days":
+			if (fillMap.get("app").isEmpty()) {
+				calendar.setTime(Utility.formatStringToDate("yyyy-MM-dd HH:mm:ss", chosenDate));
+			}
+//			fillMap.get("app").forEach(record -> {
+//				calendar.setTime(new Date(record.getRecordDate()));
+//				existTimePoint.add(calendar.get(Calendar.HOUR_OF_DAY));
+//			});
+			for(RecordDTO record : fillMap.get("app")){
+				calendar.setTime(new Date(record.getRecordDate()));
+				existTimePoint.add(calendar.get(Calendar.HOUR_OF_DAY));
+			}
+			for (int i = 0; i < 24; i++) {
+				if (!existTimePoint.remove(new Integer(i))) {
+					calendar.set(Calendar.HOUR_OF_DAY, i);
+					timePoint = calendar.getTimeInMillis();
+					fillMap.get("app").add(i, new RecordDTO(timePoint, 0));
+					fillMap.get("machine").add(i, new RecordDTO(timePoint, 0));
+				}
+			}
+			break;
+		case "weeks":
+			if (fillMap.get("app").isEmpty()) {
+				calendar.setTime(Utility.formatStringToDate("yyyy-MM-dd HH:mm:ss", chosenDate));
+			}
+			/*fillMap.get("app").forEach(record -> {
+				calendar.setTime(new Date(record.getRecordDate()));
+				existTimePoint.add(calendar.get(Calendar.DAY_OF_WEEK));
+			});*/
+			for(RecordDTO record : fillMap.get("app")){
+				calendar.setTime(new Date(record.getRecordDate()));
+				existTimePoint.add(calendar.get(Calendar.DAY_OF_WEEK));
+			}
+			if (existTimePoint.contains(new Integer(1))) {
+				calendar.add(Calendar.DATE, -7);
+			}
+			for (int i = 2; i <= 7; i++) {
+				if (!existTimePoint.remove(new Integer(i))) {
+					calendar.set(Calendar.DAY_OF_WEEK, i);
+					timePoint = calendar.getTimeInMillis();
+					fillMap.get("app").add(i - 2, new RecordDTO(timePoint, 0));
+					fillMap.get("machine").add(i - 2, new RecordDTO(timePoint, 0));
+				}
+			}
+			if (!existTimePoint.contains(new Integer(1))) {
+				calendar.add(Calendar.DATE, 7);
+				calendar.set(Calendar.DAY_OF_WEEK, 1);
+				timePoint = calendar.getTimeInMillis();
+				fillMap.get("app").add(new RecordDTO(timePoint, 0));
+				fillMap.get("machine").add(new RecordDTO(timePoint, 0));
+			}
+			break;
+		case "years":
+			if (fillMap.get("app").isEmpty()) {
+				calendar.setTime(Utility.formatStringToDate("yyyy-MM-dd HH:mm:ss", chosenDate));
+			}
+			/*fillMap.get("app").forEach(record -> {
+				calendar.setTime(new Date(record.getRecordDate()));
+				existTimePoint.add(calendar.get(Calendar.MONTH));
+			});*/
+			for(RecordDTO record : fillMap.get("app")){
+				calendar.setTime(new Date(record.getRecordDate()));
+				existTimePoint.add(calendar.get(Calendar.MONTH));
+			}
+			for (int i = 0; i <= 11; i++) {
+				if (!existTimePoint.remove(new Integer(i))) {
+					calendar.set(Calendar.MONTH, i);
+					timePoint = calendar.getTimeInMillis();
+					fillMap.get("app").add(i, new RecordDTO(timePoint, 0));
+					fillMap.get("machine").add(i, new RecordDTO(timePoint, 0));
+				}
+			}
+			break;
+		}
+		return fillMap;
+	}
+
+	public static String getRandomCode(int len) {
+		StringBuilder sb = new StringBuilder(len);
+		for (int i = 0; i < len; i++)
+			sb.append("0123456789".charAt(rnd.nextInt("0123456789".length())));
+		return sb.toString();
+	}
+
+	public static String getIp(HttpServletRequest request) {
+		String ip = request.getHeader("x-forwarded-for");
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getHeader("Proxy-Client-IP");
+		}
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getHeader("WL-Proxy-Client-IP");
+		}
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getRemoteAddr();
+		}
+		// 获取ip地址, 若多级代理,第一个IP为客户端真实IP,多个IP按照','分割
+		if (ip != null && ip.indexOf(",") != -1) {
+			ip = ip.split(",")[0];
+		}
+		return ip;
+	}
+
+	public static String CDN_WRITE_BASE_64_URL = "http://cms.iamberry.com/open-cdn/ssl/data/write/base64";
+
+	public static String uploadBase64File(String base64Data, String path) {
+		try {
+			if (base64Data != null) {
+				StringBody pic = new StringBody(base64Data, ContentType.DEFAULT_TEXT);
+				StringBody type = new StringBody("jpg", ContentType.TEXT_PLAIN);
+				HttpEntity entity = MultipartEntityBuilder.create().addPart("type", type).addPart("base64data", pic)
+						.build();
+				String result = HttpUtility.httpsPost(CDN_WRITE_BASE_64_URL, entity);
+
+//				JSONObject json = new JSONObject(result);
+//				int requestSatus = json.getJSONObject("header").getInt("status");
+//				if (1000 == requestSatus) {
+//					path = json.getJSONObject("data").get("url").toString();
+//				}
+
+				return path;
+			}
+		} catch (Exception e) {
+			return null;
+		}
+		return "";
+	}
+
+	public static String readFile(InputStream in) {
+		BufferedReader reader = null;
+		String result = "";
+		try {
+			InputStreamReader inputStreamReader = new InputStreamReader(in, "UTF-8");
+			reader = new BufferedReader(inputStreamReader);
+			String tempString = null;
+			while ((tempString = reader.readLine()) != null) {
+				result += tempString;
+			}
+			reader.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			if (reader != null) {
+				try {
+					reader.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		return result;
+	}
+
+	public static String sendCodeAsSMS(String phoneNum, Map<String, Integer> status) throws Exception {
+		String code = getRandomCode(4);
+		CloseableHttpClient client = HttpClients.createDefault();
+		Map<String, String> params = new HashMap<String, String>();
+		CloseableHttpResponse response = null;
+		params.put("username", SMS_USERNAME);
+		params.put("password", SMS_PASSWORD);
+		params.put("mobile", phoneNum);
+		params.put("content", MessageFormat.format(SMS_TEXT, code));
+		HttpPost method = new HttpPost(SMS_URL);
+		if (params != null) {
+			List<NameValuePair> paramList = new ArrayList<NameValuePair>();
+			for (Map.Entry<String, String> param : params.entrySet()) {
+				NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
+				paramList.add(pair);
+			}
+			method.setEntity(new UrlEncodedFormEntity(paramList, "UTF-8"));
+		}
+		response = client.execute(method);
+		HttpEntity entity = response.getEntity();
+		if (entity != null) {
+			String result = EntityUtils.toString(entity);
+			XStream xs = new XStream(new StaxDriver());
+			xs.alias("result", Result.class);
+			Result object = (Result)xs.fromXML(result);
+			response.close();
+			status.put(Constants.SMS_RETURNCODE, object.getResultcode());
+			if (0 == object.getResultcode()) {
+				return code;
+			}
+		}
+		return null;
+	}
+
+	public static AddressDTO getDefaultAddress(String jsonList) {
+		List<AddressDTO> addressDTOs = JsonParseUtil.parseAddressList(jsonList);
+		for (AddressDTO addressDTO : addressDTOs) {
+			if (addressDTO.getDefaultAddress() == 1) {
+				return addressDTO;
+			}
+		}
+		return null;
+	}
+
+	public static String getOrderSn(Long id) {
+		if (id == null)
+			throw new NullPointerException("id can not be null");
+
+		SimpleDateFormat format = new SimpleDateFormat("yyMMdd");
+		String date = format.format(new Date());
+		String sn = String.format("%0" + 5 + "d", id);
+		return "LTR" + date + sn;
+	}
+
+	public static String formatDateToString(String format, Date date) {
+		SimpleDateFormat sdf = new SimpleDateFormat(format);
+		return sdf.format(date);
+	}
+
+	public static Date formatStringToDate(String format, String dateStr) {
+		SimpleDateFormat sdf = new SimpleDateFormat(format);
+		Date date = null;
+		try {
+			date = sdf.parse(dateStr);
+		} catch (ParseException e) {
+			e.printStackTrace();
+			date = new Date();
+		}
+		return date;
+	}
+
+}

+ 70 - 0
iamberry-app-international/.svn/pristine/22/22173ddf2fa2499295397049407bb587f0551ddb.svn-base

@@ -0,0 +1,70 @@
+package com.iamberry.app.international.util;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.UUID;
+
+/**
+ * @website www.ratfw.com
+ * @author 献
+ * @tel 18271840547
+ * @date 2016年8月30日
+ * @explain 生成安全随机的token工具类
+ */
+public class TokenUtil {
+	private static SecureRandom random = null;
+	static {
+		try {
+			random = SecureRandom.getInstance("SHA1PRNG");
+		} catch (NoSuchAlgorithmException e) {
+		}
+	}
+	/**
+	 * 创建一个安全的随机数组byte[]
+	 * 
+	 * @return
+	 */
+	private static byte[] createRandomByte() {
+		try {
+			byte[] bytes = new byte[1024 / 8];
+			random.nextBytes(bytes);
+			int count = 10;
+			byte[] seed = random.generateSeed(count);
+			random = SecureRandom.getInstance("SHA1PRNG");
+			random.setSeed(seed);
+			SecureRandom random2 = SecureRandom.getInstance("SHA1PRNG");
+			random2.setSeed(seed);
+			return seed;
+		} catch (Exception e) {
+			return UUID.randomUUID().toString().getBytes();
+		}
+	}
+
+	/**
+	 * byte[] 转 字符串
+	 * 
+	 * @param b
+	 * @return
+	 */
+	private static String byte2hex(byte[] b) {
+		String hs = "";
+		String stmp = "";
+		for (int n = 0; n < b.length; n++) {
+			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
+			if (stmp.length() == 1)
+				hs = hs + "0" + stmp;
+			else
+				hs = hs + stmp;
+		}
+		return hs.toUpperCase();
+	}
+
+	/**
+	 * 获取一个安全的token
+	 * 
+	 * @return
+	 */
+	public static String getToken() {
+		return byte2hex(createRandomByte());
+	}
+}

+ 16 - 0
iamberry-app-international/.svn/pristine/25/25df57d6e11c0d8870a45aae8fb3a42c2bcdf849.svn-base

@@ -0,0 +1,16 @@
+SMS_USERNAME=aibeiyuan
+SMS_PASSWORD=aibeiyuan632
+SMS_TEXT=\u3010\u6bd4\u6bd4\u840c\u3011\u60a8\u7684\u9a8c\u8bc1\u7801\u662f\uff1a{0}\uff0c\u5982\u975e\u672c\u4eba\u64cd\u4f5c\uff0c\u8bf7\u5ffd\u7565\u672c\u77ed\u4fe1
+SMS_URL=http://115.29.44.189:8080/sms/smsInterface.do
+SINA_IP_URL=http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip={0}
+APPID=wxe9e992877625202f
+MCH_ID=1316959401
+SECRET=ae12dfeca278d7e4f15047313d453733
+UNIFIED_ORDER_CALLBACK_URL=demo.tronsis.com
+master_secret=ffd6373d25f9e36ba6e9d7c3
+appkey=cef2f16aa36424f2a6d4ca60
+cdnUrl=http://cms.iamberry.com/cdn
+base_url=testtest
+INTER_SMS_URL=https://sms.yunpian.com/v2/sms/single_send.json
+INTER_SMS_TEXT=\u3010simfy\u3011\u60A8\u7684\u9A57\u8B49\u78BC\u662F\uFF1A{0}\uff0c3\u5206\u9418\u5167\u6709\u6548\u3002\u5982\u975e\u672c\u4eba\u64cd\u4f5c\uff0c\u8acb\u5ffd\u7565\u672c\u7c21\u8a0a\u3002
+INTER_SMS_KEY=415754e72ef318ecce825c8ecdd56fae

+ 2 - 0
iamberry-app-international/.svn/pristine/31/319d159ee4424788e6e8b2eded3e240b7fdf53e0.svn-base

@@ -0,0 +1,2 @@
+username-HK=hexziugang
+

+ 34 - 0
iamberry-app-international/.svn/pristine/35/35ad3ecde3e1bbeebeed9371a7be62c1d55c260b.svn-base

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
+<configuration>
+	<!-- 设置  -->
+	<settings>  
+        <!--set lazy fetching-->  
+        <setting name="lazyLoadingEnabled" value="false" />  
+        <setting name="logImpl" value="LOG4J"/>  
+		<setting name="mapUnderscoreToCamelCase" value="true" />
+		<!-- 允许使用列标签代替列名 -->  
+		<setting name="useColumnLabel" value="true" />  
+		<!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->  
+		<setting name="useGeneratedKeys" value="true" />  
+    </settings>
+    
+    <!-- 配置Entitys -->
+    <typeAliases>
+    	<typeAlias type="com.iamberry.app.core.entity.Machine" alias="Machine"/>
+    	<typeAlias type="com.iamberry.app.core.entity.Message" alias="Message"/>
+    	<typeAlias type="com.iamberry.app.core.entity.MilkImages" alias="MilkImages"/>
+    	<typeAlias type="com.iamberry.app.core.entity.MilkMakingRecord" alias="MilkMakingRecord"/>
+    	<typeAlias type="com.iamberry.app.core.entity.MilkPowderInfo" alias="MilkPowderInfo"/>
+    	<typeAlias type="com.iamberry.app.core.entity.SharedMachine" alias="SharedMachine"/>
+    	<typeAlias type="com.iamberry.app.core.entity.SysConfig" alias="SysConfig"/>
+    	<typeAlias type="com.iamberry.app.core.entity.SysLog" alias="SysLog"/>
+    	<typeAlias type="com.iamberry.app.core.entity.User" alias="User"/>
+    	<typeAlias type="com.iamberry.app.core.entity.UserAvator" alias="UserAvator"/>
+    	
+    	<typeAlias type="com.iamberry.wechat.core.entity.PageBean" alias="PageBean"/>
+    	<typeAlias type="com.iamberry.app.core.serch.SerchParam" alias="SerchParam"/>
+    	<typeAlias type="com.iamberry.app.core.entity.CodeValid" alias="CodeValid"/>
+    	
+    </typeAliases>
+</configuration>

+ 26 - 0
iamberry-app-international/.svn/pristine/37/3730fa2b75dd756b12c7caf1e9f9683d8a6f4d60.svn-base

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

+ 93 - 0
iamberry-app-international/.svn/pristine/38/387fc6906a7ce0447af2e1262a05b65eca3df2ed.svn-base

@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
+	id="WebApp_ID" version="3.1">
+	<display-name>iamberry-app-api</display-name>
+
+	<welcome-file-list>
+		<welcome-file>index.html</welcome-file>
+		<welcome-file>index.htm</welcome-file>
+		<welcome-file>index.jsp</welcome-file>
+		<welcome-file>default.html</welcome-file>
+		<welcome-file>default.htm</welcome-file>
+		<welcome-file>default.jsp</welcome-file>
+	</welcome-file-list>
+
+
+	<context-param>
+		<param-name>contextConfigLocation</param-name>
+		<param-value>classpath:iamberry-app-api-ioc.xml</param-value>
+	</context-param>
+	<listener>
+		<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
+	</listener>
+	<listener>
+		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+	</listener>
+
+	<servlet>
+		<servlet-name>springDispatcherServlet</servlet-name>
+		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+		<init-param>
+			<param-name>contextConfigLocation</param-name>
+			<param-value>classpath:iamberry-app-api-mvc.xml</param-value>
+		</init-param>
+		<load-on-startup>1</load-on-startup>
+	</servlet>
+	<servlet-mapping>
+		<servlet-name>springDispatcherServlet</servlet-name>
+		<url-pattern>/</url-pattern>
+	</servlet-mapping>
+
+	<filter>
+		<filter-name>characterEncodingFilter</filter-name>
+		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
+		<init-param>
+			<param-name>encoding</param-name>
+			<param-value>UTF-8</param-value>
+		</init-param>
+		<init-param>
+			<param-name>forceEncoding</param-name>
+			<param-value>true</param-value>
+		</init-param>
+	</filter>
+	<filter-mapping>
+		<filter-name>characterEncodingFilter</filter-name>
+		<url-pattern>/*</url-pattern>
+	</filter-mapping>
+
+	<error-page>
+		<error-code>404</error-code>
+		<location>/view/system_view/404.jsp</location>
+	</error-page>
+	<error-page>
+		<error-code>500</error-code>
+		<location>/view/system_view/500.jsp</location>
+	</error-page>
+	
+	<!-- 数据库监控 -->
+	<servlet>
+        <servlet-name>DruidStatView</servlet-name>
+        <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>DruidStatView</servlet-name>
+        <url-pattern>/admin/druid/*</url-pattern>
+    </servlet-mapping>
+    
+    <!-- web stat -->
+    <filter>
+		<filter-name>DruidWebStatFilter</filter-name>
+		<filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
+	</filter>
+	<filter-mapping>
+	    <filter-name>DruidWebStatFilter</filter-name>
+	    <url-pattern>/*</url-pattern>
+	</filter-mapping>
+	
+	<listener>
+    	<listener-class>com.iamberry.app.international.util.kafka.KafkaConsumer</listener-class>
+    </listener>
+	
+</web-app>

+ 27 - 0
iamberry-app-international/.svn/pristine/39/3901fa8f1c4a005a146b96574b6b8092e8c7285d.svn-base

@@ -0,0 +1,27 @@
+
+package com.iamberry.app.international.util.kafka;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+
+import org.apache.commons.codec.digest.DigestUtils;
+
+public class SaslConfiguration extends Configuration {
+
+	public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
+		String appKey = "5kkyurvvtt58bbuxueee";//填APP KEY
+		String secretKey = "rhj6na6u3y6uhy6qrbb3944mg5uqqpbb";//APP SECRET
+		Map<String, String> options = new HashMap<String, String>();
+		options.put("username", appKey);//APP KEY
+		options.put("password", DigestUtils.md5Hex(appKey + DigestUtils.md5Hex(secretKey)).substring(8, 24));//MD5(APP KEY+MD5(云端APP SECRET))后,取中间16位
+		AppConfigurationEntry entry = new AppConfigurationEntry(
+				"org.apache.kafka.common.security.plain.PlainLoginModule",
+				AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
+		AppConfigurationEntry[] configurationEntries = new AppConfigurationEntry[1];
+		configurationEntries[0] = entry;
+		return configurationEntries;
+	}
+}

+ 532 - 0
iamberry-app-international/.svn/pristine/39/397d38eece729e1d37f9b9d2a1cd0eade570694f.svn-base

@@ -0,0 +1,532 @@
+package com.iamberry.app.international.controller;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.FileUtils;
+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.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import sun.misc.BASE64Decoder;
+
+import com.iamberry.app.config.Constants;
+import com.iamberry.app.config.Response;
+import com.iamberry.app.config.ResponseHeader;
+import com.iamberry.app.core.dto.RemoteIpInfoDTO;
+import com.iamberry.app.core.dto.UserDTO;
+import com.iamberry.app.core.entity.User;
+import com.iamberry.app.international.util.TokenUtil;
+import com.iamberry.app.international.util.Utility;
+import com.iamberry.app.tool.util.AES;
+import com.iamberry.wechat.file.FileType;
+
+/**
+ * UserController
+ *
+ * @author Moon Cheng
+ * @date 2016年1月18日 上午11:53:04
+ */
+@Controller
+@RequestMapping("/secure/user")
+public class UserController extends BaseController {
+
+	@Autowired
+	HttpServletResponse response;
+	
+	private Logger logger = LoggerFactory.getLogger(UserController.class);
+	
+	// 保存用户头像的路径
+	private String saveRootPath = "/common/user_head/";
+	private String domain = "http://hk.iamberry.com";
+
+	@InitBinder("user")
+	public void initBinderUser(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("user.");
+	}
+
+	/**
+	 * 用户手机注册,成功返回json格式的用户信息
+	 * @author Moon Cheng
+	 * @param phone 手机号码
+	 * @param verificationCode 手机收到的短信验证码
+	 * @param password 密码
+	 * @param areacode  地区参数 +86 +866港澳台........
+	 * @return 2101:验证码错误;2102:验证码超时;1000:请求成功;2000:注册失败;
+	 */
+	@RequestMapping(value = "/register", method = RequestMethod.POST)
+	@ResponseBody
+	private Response register(@RequestParam("phone") String phone,
+			@RequestParam("verification_code") String verificationCode,
+			@RequestParam("password") String password,
+			@RequestParam("areacode") String areacode
+			) {
+		User user = new User();
+		int status = checkVerifyCode(phone, verificationCode, 1); //验证手机验证码是否正确
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else
+			if (status == 1) { //验证成功
+			String ip = Utility.getIp(request);
+			user = userService.register(areacode+","+phone, password, ip); 
+			if (user == null) {//注册失败
+				return Response.FAILURE;
+			}
+		}
+		//注册成功,返回用户信息
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * 第三方【微信】用户手机绑定,
+	 * @author Moon Cheng
+	 * @param phone 手机号
+	 * @param openId 微信的open——id
+	 * @return 1000:请求成功;2000:注册失败;
+	 */
+	@RequestMapping(value = "/third_part_binding_phone", method = RequestMethod.POST)
+	@ResponseBody
+	private Response thirdPartBindingPhone(@RequestParam("phone") String phone,
+			@RequestParam("open_id") String openId,@RequestParam("code") String code,
+			@RequestParam("areacode") String areacode 
+			) {
+		User user = new User();
+		int status = checkVerifyCode(phone, code, 1); //验证手机验证码是否正确
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} 
+		user = userService.thirdPartBindingPhone(areacode+","+phone, openId);
+		if (user == null) {
+			return Response.USER_NOT_EXIST;
+		}
+		
+		logger.info(user.getId() + "," + (user.getId().intValue() == 2011));
+		
+		if (user.getPassword() != null && user.getPassword().equals("EXTIES")) {
+			ResponseHeader header = new ResponseHeader(2011, "用户已经存在!", 1);
+			UserDTO dto = userService.tuyaConnect(user);
+			return new Response(header, dto);
+		}
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * login
+	 * 手机号登录,
+	 * @param phone 手机号
+	 * @param password 密码
+	 * @return 2012:身份验证失败;2013:账户冻结;1000:请求成功;
+	 */
+	@RequestMapping(value = "/login", method = RequestMethod.POST)
+	@ResponseBody
+	private Response login(@RequestParam(value = "phone", required = true) String phone,
+			@RequestParam(value = "password", required = true) String password) {
+		Object user = userService.login(phone, password);
+		int status = 0;
+		if (user instanceof Integer) {
+			status = (Integer) user;
+			switch (status) { 
+			case -1: //账号不存在
+				return Response.USER_NOT_EXIST;
+			case -2: //密码错误
+				return Response.AUTHENTICATION_ERROR;
+			case -3: //用户状态不正常
+				return Response.USER_FROZEN_ERROR;
+			}
+		}
+		return Response.SUCCESS.setData((UserDTO) user, 1);
+	}
+
+	/**
+	 * thirdPartLogin
+	 * 第三方登录
+	 * @param openId 微信open_id 
+	 * @param extType 来源 qq或者微信
+	 * @param extName extname
+	 * @param extPicture 图片
+	 * @return 2012:身份验证失败;2013:账户冻结;1000:请求成功;
+	 */
+	@RequestMapping(value = "/third_part_login", method = RequestMethod.POST)
+	@ResponseBody
+	private Response thirdPartLogin(@RequestParam(value = "open_id") String openId,
+			@RequestParam(value = "ext_type") String extType, @RequestParam(value = "ext_name") String extName,
+			@RequestParam(value = "ext_picture") String extPicture
+			) {
+		String ip = Utility.getIp(request);
+		User user1 = userService.thirdPartLogin(openId, extType, extName, extPicture, ip);
+
+		if (Constants.USER_INACTIVE.equals(user1.getStatus_())) {
+			return Response.USER_FROZEN_ERROR;
+		}
+ // 这里不注册涂鸦,给涂鸦账号,密码
+		UserDTO userInfo = new UserDTO(user1.getId(), user1.getUsername(), user1.getPassword(), user1.getToken(), user1.getDisplay_name(),
+				user1.getDisplay_picture(), user1.getCreated_on(), user1.getExt_open_id(), user1.getExt_name(), user1.getExt_type(),
+				user1.getLocation(), user1.getBaby_nickname(), user1.getBaby_dob(), user1.getBaby_gender(), user1.getStatus_());
+		userInfo.setPassword(null);
+		userInfo.setCountry_code(user1.getCountry_code());
+		userInfo.setEncryptUsername(AES.encrypt(user1.getUsername()));
+		userInfo.setUserCode("iamberry123");
+		userInfo.setIs_perfect_user(user1.getIs_perfect_user());
+		
+		return Response.SUCCESS.setData(userInfo);
+	}
+
+	/**
+	 * getUserInfo
+	 * 获取用户基本信息
+	 * @param id 用户id
+	 * @token  用户token 登录的时候设置的唯一的token
+	 * @return Response 2100:无效token;2020:无效用户;1000:请求成功;
+	 */
+	@RequestMapping(value = "/get_user_info", method = RequestMethod.POST)
+	@ResponseBody
+	private Response getUserInfo(@RequestParam(value = "user_id", required = true) Long id,
+			@RequestParam("token") String token) {
+		User userInfo = userService.validateUserToken(token);
+		if (userInfo == null) {//token不存在,表示登录的时候没有..
+			return Response.INVALID_TOKEN;
+		}
+		User user = userService.findById(id);
+		if (user == null) { //未找到
+			return Response.INVALID_PARMS;
+		}
+		return Response.SUCCESS.setData(user, 1);
+	}
+
+	/**
+	 * updateProfile
+	 * 更新用户基本信息
+	 * @param user 用户信息
+	 * @param token token
+	 * @return Response 2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/update_profile", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateProfile(User user, @RequestParam("token") String token) {
+		User user1 = userService.updateUserInfo(user, token);
+		if (user1 == null) {
+			return Response.INVALID_TOKEN;
+		}
+//		userInfo.setEncryptUsername(AES.encrypt(user.getUsername()));
+//		userInfo.setUserCode("iamberry123");
+		
+		UserDTO userInfo = new UserDTO(user1.getId(), user1.getUsername(), user1.getPassword(), user1.getToken(), user1.getDisplay_name(),
+				user1.getDisplay_picture(), user1.getCreated_on(), user1.getExt_open_id(), user1.getExt_name(), user1.getExt_type(),
+				user1.getLocation(), user1.getBaby_nickname(), user1.getBaby_dob(), user1.getBaby_gender(), user1.getStatus_());
+		userInfo.setPassword(null);
+		userInfo.setCountry_code(user1.getCountry_code());
+		userInfo.setEncryptUsername(AES.encrypt(user1.getUsername()));
+		userInfo.setUserCode("iamberry123");
+		return Response.SUCCESS.setData(userInfo, 1);
+	}
+
+	private BASE64Decoder decoder = new BASE64Decoder();  
+	
+	/**
+	 * updateDisplayPicture
+	 * 更改用户头像
+	 * @param user 用户信息
+	 * @param token 唯一标识符
+	 * @return Response
+	 * @throws IOException 
+	 */
+	@RequestMapping(value = "/update_display_picture", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateDisplayPicture(@RequestParam("picture_base64") String pictureBase64,
+			@RequestParam("token") String token, HttpServletRequest request) throws IOException {
+		// 判断文件类型
+		byte [] b = new byte[28];
+		pictureBase64.getBytes(0, 27, b, 0);
+		String temp = new String(b);
+		try {
+			b = decoder.decodeBuffer(temp);
+		} catch (IOException e) {
+			logger.error("updateDisplayPicture:" + e.getMessage());
+			return Response.FAILURE;
+		}
+		String type = null;					// 文件类型
+		String fileHead = byte2hex(b);		// 文件头
+		fileHead = fileHead.toUpperCase();
+		type = getType(fileHead);
+		if (type == null) {
+			return Response.FAILURE;
+		}
+		// 获取保存地址
+		String savePath = request.getServletContext().getRealPath(saveRootPath);
+		StringBuilder tempDir = new StringBuilder(savePath);
+		Long ran = new Date().getTime();
+		tempDir.append(File.separator);
+		tempDir.append(ran);
+		tempDir.append(File.separator);
+		// 判断保存路径是否存在,如果不存在,那么创建
+		File file=new File(savePath);
+		if (!file.exists()) {
+			logger.info("updateDisplayPicture-exists");
+			file.mkdirs();
+		}
+		// 获取保存文件名称
+		StringBuilder saveName = new StringBuilder(TokenUtil.getToken());
+		saveName.append(".").append(type);
+		tempDir.append(saveName);
+		// 保存磁盘
+		String userHeadURL = null;
+		if (!generateImage(pictureBase64, tempDir.toString())) {
+			logger.error("updateDisplayPicture-generateImage saveFile Error");
+			return Response.FAILURE;
+		} else {
+			userHeadURL = domain + request.getContextPath() + saveRootPath + ran + "/" + saveName.toString();
+		}
+		// 保存
+		String path = userService.updateDisplayPicture(userHeadURL, token);
+		return Response.SUCCESS.setData(path, 1);
+	}
+	
+	private String getType(String fileHead) {
+		FileType [] fileTypes = FileType.values();
+		for (FileType fileType : fileTypes) {
+			if (fileHead.startsWith(fileType.getValue())) {
+				return fileType.getSuffix();
+			}
+		}
+		return null;
+	}
+	
+	private boolean generateImage(String imgStr, String imgFilePath) throws IOException {  
+		// Base64解码  
+		byte[] bytes = decoder.decodeBuffer(imgStr);
+		for (int i = 0; i < bytes.length; ++i) {  
+			if (bytes[i] < 0) {
+				// 调整异常数据  
+				bytes[i] += 256;  
+			}  
+		}  
+		// 生成图片 
+		File file = new File(imgFilePath);
+		FileUtils.writeByteArrayToFile(file, bytes);
+		return true;  
+	}
+
+	private String byte2hex(byte[] b) {
+       // 转成16进制字符串
+       String hs = "";
+       String tmp = "";
+       for (int n = 0; n < b.length; n++) {
+           //整数转成十六进制表示
+           tmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
+           if (tmp.length() == 1) {
+               hs = hs + "0" + tmp;
+           } else {
+               hs = hs + tmp;
+           }
+       }
+       tmp = null;
+       return hs;
+   }
+
+	/**
+	 * 此方法可以不再使用
+	 */
+	@RequestMapping(value = "/avator/{id}/{rand}", method = RequestMethod.GET)
+	@ResponseBody
+	@Deprecated
+	private void getDisplayPicture() {
+		String url = request.getRequestURI();
+		url = url.substring(0, url.lastIndexOf('/'));
+		String userID = url.substring(url.lastIndexOf('/') + 1);
+		String avator = userService.selectUserAvator(Long.valueOf(userID));
+		response.setContentType("image/jpg");
+		try {
+			OutputStream os = response.getOutputStream();
+			BASE64Decoder decoder = new BASE64Decoder();
+			byte[] decoderBytes = decoder.decodeBuffer(avator);
+			os.write(decoderBytes);
+			os.flush();
+			os.close();
+		} catch (Exception e) {
+			// TODO: handle exception
+		}
+	}
+
+	/**
+	 * changePassword
+	 * 修改手机密码
+	 * @param oldPassword 新密码
+	 * @param newPassword 旧密码
+	 * @param token token
+	 * @return Response 2101:验证码错误;2102:验证码超时;2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/change_password", method = RequestMethod.POST)
+	@ResponseBody
+	private Response changePassword(@RequestParam("old_password") String oldPassword,
+			@RequestParam("new_password") String newPassword, @RequestParam("token") String token) {
+		int status = userService.changePassword(oldPassword, newPassword, token);
+		if (status == -1) { //token错误
+			return Response.INVALID_TOKEN;
+		} else if (status == 0) { //密码错误
+			return Response.ERROR_OLDPASSWORD;
+		} else { 
+			return Response.SUCCESS.setData(null);
+		}
+	}
+
+	/**
+	 * changePhone
+	 * 修改手机号码
+	 * @author Moon Cheng, Yin
+	 * @param newPhone 新手机号
+	 * @param token token
+	 * @param verificationCode 手机验证码
+	 * @return2101:验证码错误;2102:验证码超时;2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/change_phone", method = RequestMethod.POST)
+	@ResponseBody
+	private Response changePhone(@RequestParam("new_phone") String newPhone,
+			@RequestParam("verification_code") String verificationCode, @RequestParam("token") String token) {
+		int status = checkVerifyCode(newPhone, verificationCode, 2);
+		User user = null;
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else if (status == 1) { 
+			user = userService.changePhone(newPhone, token);
+			if (user == null) {
+				return Response.INVALID_TOKEN;
+			}
+		}
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * resetPassword
+	 * 重置手机密码
+	 * @param username 用户米
+	 * @param newPassword 新密码
+	 * @param verificationCode 验证码
+	 * @return2101:验证码错误;2102:验证码超时;2001:无效用户;2000:重置密码失败; 1000:请求成功;
+	 */
+	@RequestMapping(value = "/reset_password", method = RequestMethod.POST)
+	@ResponseBody
+	private Response resetPassword(@RequestParam(value = "username") String username,
+			@RequestParam("new_password") String newPassword,
+			@RequestParam("verification_code") String verificationCode) {
+		int status = checkVerifyCode(username, verificationCode, 3);
+		if (status == -1) {//验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else if (status == 1) { 
+			status = userService.resetPassWord(username, newPassword);
+			if (status == -3) {//账号不存在
+				return Response.USER_NOT_EXIST; 
+			} else if (status == 0) {
+				return Response.FAILURE;
+			}
+		}
+
+		return Response.SUCCESS.setData(null);
+	}
+
+	/**
+	 * 发送手机验证码
+	 * @param phone 手机号 
+	 * @param statusCode  1代表注册,2代表更换手机号,3代表忘记密码
+	 * @return
+	 */
+	@RequestMapping(value = "/send_code", method = RequestMethod.GET)
+	@ResponseBody
+	private Response sendCode(@RequestParam("phone") String phone, @RequestParam("status_code") int statusCode,@RequestParam("areacode") String areacode) {
+		String code = null;
+		Map<String, Integer> status = new HashMap<>();
+		User user = new User();
+		try {
+			switch (statusCode) {
+			case 1:// register
+				user = userService.selectUserByUsername(phone);
+				if (user != null) {
+					return Response.ERROR_REGISTER;
+				}
+				
+				break;
+			case 2:// change phone
+				user = userService.selectUserByUsername(phone);
+				if (user != null) {
+					return Response.ERROR_REGISTER;
+				}
+
+				break;
+			case 3:// reset password
+				user = userService.selectUserByUsername(phone);
+				if (user == null) {
+					return Response.USER_NOT_EXIST;
+				}
+
+				break;
+			default:
+				break;
+			}
+			codeService.sendCode(areacode+","+phone, statusCode);
+			status.put("code", 0);
+		} catch (Exception e) {
+			System.out.println(e);
+			return Response.SERVER_INTERNAL_ERROR;
+		}
+		if (0 == status.get(Constants.SMS_RETURNCODE)) {
+			return Response.SUCCESS.setData(code, 0);
+		} else {
+			return Response.FAILURE.setHeader(new ResponseHeader(status.get(Constants.SMS_RETURNCODE), "", 0));
+		}
+	}
+
+	/**
+	 * 获取封面图片
+	 * @return json
+	 */
+	@RequestMapping(value = "/start_page", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getStartPage() {
+		String pageUrl = userService.getStartPage();
+		return Response.SUCCESS.setData(pageUrl, 1);
+	}
+
+	/**
+	 * 获取地址url
+	 * @return
+	 */
+	@RequestMapping(value = "/get_location", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getLocation() {
+		String IP = Utility.getIp(request);
+		 //String IP = "183.14.17.153";
+		RemoteIpInfoDTO remoteIpInfoDTO = userService.getLocation(IP);
+		return Response.SUCCESS.setData(remoteIpInfoDTO, 1);
+	}
+	
+	/**
+	 * 获取app版本号
+	 * @return
+	 */
+	@RequestMapping(value = "/get_version", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getApkVersion() {
+		return Response.SUCCESS.setData(userService.getApkVersion());
+	}
+}

+ 64 - 0
iamberry-app-international/.svn/pristine/3c/3c4f44bf9339d557eb54019e823a342acbf69425.svn-base

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+	xmlns:context="http://www.springframework.org/schema/context"
+	xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"
+	xmlns:cache="http://www.springframework.org/schema/cache"
+	xmlns:tx="http://www.springframework.org/schema/tx"
+	default-autowire="byName"
+	default-lazy-init="true"
+    xmlns:task="http://www.springframework.org/schema/task"
+	xmlns:aop="http://www.springframework.org/schema/aop"
+	xmlns:ehcache-spring="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"
+	xmlns:p="http://www.springframework.org/schema/p"
+	xmlns:websocket="http://www.springframework.org/schema/websocket" 
+	xsi:schemaLocation=
+		"http://www.springframework.org/schema/aop
+		http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
+		http://www.springframework.org/schema/beans
+		http://www.springframework.org/schema/beans/spring-beans.xsd
+		http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring
+		http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd
+		http://www.springframework.org/schema/cache
+		http://www.springframework.org/schema/cache/spring-cache-4.1.xsd
+		http://www.springframework.org/schema/tx 
+		http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
+		http://www.springframework.org/schema/task  
+		http://www.springframework.org/schema/task/spring-task-3.1.xsd  
+		http://www.springframework.org/schema/websocket 
+		http://www.springframework.org/schema/websocket/spring-websocket.xsd
+		http://www.springframework.org/schema/context
+		http://www.springframework.org/schema/context/spring-context-3.2.xsd">
+
+	<context:component-scan base-package="com.iamberry.app.international" />
+	
+	<!-- 配置自动扫描的包:不扫描控制器和异常处理 -->
+	<context:component-scan base-package="com.iamberry">
+		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
+		<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
+	</context:component-scan>
+	
+	<!-- 使用CGLIB动态代理 -->
+    <aop:aspectj-autoproxy proxy-target-class="true"/>
+
+	<!-- 开启这个配置,spring才能识别@Scheduled注解 -->
+	<task:annotation-driven/>
+
+ 	<!-- 配置数据库	-->
+    <import resource="classpath:iamberry-app-api-datasource.xml"/> 
+    
+    <!-- spring监控 -->
+    <bean id="druid-stat-interceptor" class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor">
+	</bean>
+	<bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut" scope="prototype">
+		<property name="patterns">
+			<list>
+				<value>com.iamberry.app.service.*</value>
+				<value>com.iamberry.app.mapper.*</value>
+			</list>
+		</property>
+	</bean>
+	<aop:config proxy-target-class="true">
+		<aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" />
+	</aop:config>
+</beans>

+ 1 - 0
iamberry-app-international/.svn/pristine/41/41dfc0a6c92707948578891c51d98c6443be63cc.svn-base

@@ -0,0 +1 @@
+Window

+ 5 - 0
iamberry-app-international/.svn/pristine/42/42a840f2d518a115d4e1c6b2c116af2abdde661a.svn-base

@@ -0,0 +1,5 @@
+<html>
+<body>
+<h2>Hello World!</h2>
+</body>
+</html>

+ 31 - 0
iamberry-app-international/.svn/pristine/50/5033d95392fa59b225fe23ba46d7d989f7ba4e06.svn-base

@@ -0,0 +1,31 @@
+
+package com.iamberry.app.international.util.kafka;
+
+import java.util.Map;
+
+import org.apache.kafka.common.serialization.Deserializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.alibaba.fastjson.JSON;
+
+public class JsonDeserializer<T> implements Deserializer<T> {
+
+	protected static Logger logger = LoggerFactory.getLogger(JsonDeserializer.class);
+
+	public void configure(Map<String, ?> configs, boolean b) {
+	}
+
+	public T deserialize(String topic, byte[] data) {
+		try {
+			T result = (T) JSON.parse(data);
+			return result;
+		} catch (Exception e) {
+			logger.error("", e);
+			return null;
+		}
+	}
+
+	public void close() {
+	}
+}

+ 136 - 0
iamberry-app-international/.svn/pristine/51/5177fd2c3ad5dd453c00b2c19ec6d7f0d3bdf086.svn-base

@@ -0,0 +1,136 @@
+package com.iamberry.app.international.util;
+
+
+import java.util.HashMap;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import cn.jpush.api.JPushClient;
+import cn.jpush.api.common.resp.APIConnectionException;
+import cn.jpush.api.common.resp.APIRequestException;
+import cn.jpush.api.push.PushResult;
+import cn.jpush.api.push.model.Options;
+import cn.jpush.api.push.model.Platform;
+import cn.jpush.api.push.model.PushPayload;
+import cn.jpush.api.push.model.PushPayload.Builder;
+import cn.jpush.api.push.model.audience.Audience;
+import cn.jpush.api.push.model.notification.AndroidNotification;
+import cn.jpush.api.push.model.notification.IosNotification;
+import cn.jpush.api.push.model.notification.Notification;
+
+import com.iamberry.app.core.dto.JpushMessageDTO;
+import com.iamberry.app.core.entity.Message;
+
+
+public class Jdpush {
+	
+	protected static final Logger LOG = LoggerFactory.getLogger(Jdpush.class);  
+    public static final String JpushAppkey ="4aed8013f682a80294510d00";
+    public static final String JpushSecret ="b7228c86effa5468c04983f5";
+    public static final boolean APNOPTION = true; 		//True 表示推送生产环境,False 表示要推送开发环境
+    public static final String PREFIX = "iamberry_"; 	//别名,前缀
+    
+    public static final HashMap<String, Platform> Platforms = new HashMap<String, Platform>(); //平台
+    public static final HashMap<Integer, String> allResultCode = new HashMap<Integer, String>(); //结果集
+
+    /*
+    platform	必填	推送平台设置
+    audience	必填	推送设备指定
+    notification	可选	通知内容体。是被推送到客户端的内容。与 message 一起二者必须有其一,可以二者并存
+    message	可选	消息内容体。是被推送到客户端的内容。与 notification 一起二者必须有其一,可以二者并存
+    sms_message	可选	短信渠道补充送达内容体
+    options	可选	推送参数
+    */
+    static{
+    	Platforms.put("all", Platform.all()); //all
+    	Platforms.put("android", Platform.android()); //android
+    	Platforms.put("ios", Platform.ios()); //ios
+    	
+    	allResultCode.put(200, "发送成功!");allResultCode.put(400, "错误的请求!");
+    	allResultCode.put(401, "未验证");allResultCode.put(403, "被拒绝");
+    	allResultCode.put(404, "无法找到");allResultCode.put(504, "代理超时");
+    }
+    
+    public static String SendPush(PushPayload payload) {  
+    	JPushClient jpushClient = new JPushClient(JpushSecret,JpushAppkey);   //推送客户端
+         //生成推送的内容,
+         PushResult result = null;
+        try {  
+            System.out.println(payload.toString()); 
+            result = jpushClient.sendPush(payload);  
+            LOG.info("Got result - " + result);  
+            LOG.info("Got result code " + result.getResponseCode());  
+           String responseString =  allResultCode.get(result.getResponseCode());
+           if(StringUtils.isNotBlank(responseString)){
+        	   return responseString;
+           }
+        } catch (APIConnectionException e) {  
+            LOG.error("Connection error. Should retry later. ", e);  
+        } catch (APIRequestException e) {  
+            LOG.error("Error response from JPush server. Should review and fix it. ", e);  
+            LOG.info("HTTP Status: " + e.getStatus());  
+            LOG.info("Error Code: " + e.getErrorCode());  
+            LOG.info("Error Message: " + e.getErrorMessage());  
+            LOG.info("Msg ID: " + e.getMsgId());  
+        }
+        return String.valueOf(result.getResponseCode());
+    }  
+      
+	/**
+	 *手动发送消息到-----> 某平台,某消息,某通知
+	 * @param jpushmessage 参数类
+	 * @return 消息封装类
+	 */
+	public static String sendmessage_jpushmessage(JpushMessageDTO jpushmessage) {  
+		PushPayload pushpayload =  PushPayload.newBuilder()  
+                .setPlatform(Platforms.get(jpushmessage.getPlatform()))  
+                .setAudience(Audience.alias(PREFIX+jpushmessage.getTag()))
+                .setNotification(Notification.alert(jpushmessage.getContent()) )//通知消息是 content
+                .setOptions(Options.newBuilder()  
+                .setApnsProduction(APNOPTION)  //True 表示推送生产环境,False 表示要推送开发环境
+                .build())  
+                .build();  
+        return SendPush(pushpayload);
+    }  
+	
+     /**
+      * 程序触发,手动触发
+      * 若别名存在-->则表示对某个人发送,不存在,则表示对所有人
+      * @return 调用结果
+      */
+    public static String buildPushObject_all_notifi(Message messsage) {  
+    	Builder builder = PushPayload.newBuilder(); //所有平台
+    	
+    	//备注中,all,ios,android,其他表示 all,
+    	if(Platforms.containsKey(messsage.getRemark())){
+    		builder.setPlatform(Platforms.get(messsage.getRemark()));
+    	}else{
+    		builder.setPlatform(Platform.all());
+    	}
+    	
+    	if(StringUtils.isNoneEmpty(Long.toString(messsage.getUser()))){
+    		builder.setAudience(Audience.alias(PREFIX+messsage.getUser()));   //某个别名
+    	}
+    	builder.setNotification(Notification.newBuilder()  
+                 .setAlert(messsage.getContent()) //通知消息是alert content
+                 .addPlatformNotification(AndroidNotification.newBuilder()
+                         .setTitle(messsage.getTitle())
+                         .addExtra("forword", messsage.getForword()) //是否在内部打开1内部2外部
+                         .addExtra("send_type", messsage.getSend_type())//推送的类型1文本 2url 3 内部页面
+                         .addExtra("url", messsage.getUrl())//消息URL
+                         .build()) 
+                 .addPlatformNotification(IosNotification.newBuilder()  
+                		 .addExtra("forword", messsage.getForword()) //是否在内部打开1内部2外部
+                         .addExtra("send_type", messsage.getSend_type())//推送的类型1文本 2url 3 内部页面
+                         .addExtra("url", messsage.getUrl())//消息URL
+                         .build())  
+                 .build());
+    	//设置是开发环境还是,生产环境
+    	builder.setOptions(Options.newBuilder()
+                .setApnsProduction(APNOPTION)
+                .build());
+        return  SendPush(builder.build());
+    }
+}

+ 10 - 0
iamberry-app-international/.svn/pristine/52/52acda021ca7bc541f8f8541dabe808ed05bbacc.svn-base

@@ -0,0 +1,10 @@
+jdbc.driver=com.mysql.jdbc.Driver
+jdbc.url=jdbc:mysql://192.168.1.254:3306/iamberry_app?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull
+jdbc.username=root
+jdbc.password=root
+#pool settings
+jdbc.pool.init=1
+jdbc.pool.minIdle=3
+jdbc.pool.maxActive=20
+#jdbc.testSql=SELECT 'x'
+jdbc.testSql=SELECT 'x' FROM DUAL

+ 539 - 0
iamberry-app-international/.svn/pristine/53/53bd5fe7a483ab1fe50a4826ddb607c1664a1a6d.svn-base

@@ -0,0 +1,539 @@
+package com.iamberry.app.international.controller;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.FileUtils;
+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.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import sun.misc.BASE64Decoder;
+
+import com.iamberry.app.config.Constants;
+import com.iamberry.app.config.Response;
+import com.iamberry.app.config.ResponseHeader;
+import com.iamberry.app.core.dto.RemoteIpInfoDTO;
+import com.iamberry.app.core.dto.UserDTO;
+import com.iamberry.app.core.entity.User;
+import com.iamberry.app.international.util.TokenUtil;
+import com.iamberry.app.international.util.Utility;
+import com.iamberry.app.tool.util.AES;
+import com.iamberry.wechat.file.FileType;
+
+/**
+ * UserController
+ *
+ * @author Moon Cheng
+ * @date 2016年1月18日 上午11:53:04
+ */
+@Controller
+@RequestMapping("/secure/user")
+public class UserController extends BaseController {
+
+	@Autowired
+	HttpServletResponse response;
+	
+	private Logger logger = LoggerFactory.getLogger(UserController.class);
+	
+	// 保存用户头像的路径
+	private String saveRootPath = "/common/user_head/";
+	private String domain = "http://hk.iamberry.com";
+
+	@InitBinder("user")
+	public void initBinderUser(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("user.");
+	}
+
+	/**
+	 * 用户手机注册,成功返回json格式的用户信息
+	 * @author Moon Cheng
+	 * @param phone 手机号码
+	 * @param verificationCode 手机收到的短信验证码
+	 * @param password 密码
+	 * @param areacode  地区参数 +86 +866港澳台........
+	 * @return 2101:验证码错误;2102:验证码超时;1000:请求成功;2000:注册失败;
+	 */
+	@RequestMapping(value = "/register", method = RequestMethod.POST)
+	@ResponseBody
+	private Response register(@RequestParam("phone") String phone,
+			@RequestParam("verification_code") String verificationCode,
+			@RequestParam("password") String password,
+			@RequestParam("areacode") String areacode
+			) {
+		User user = new User();
+		int status = checkVerifyCode(phone, verificationCode, 1); //验证手机验证码是否正确
+		status = 1;
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else
+			if (status == 1) { //验证成功
+			User users = userService.selectUserByUsername(phone);
+				if(users == null){
+					String ip = Utility.getIp(request);
+					user = userService.register(areacode+","+phone, password, ip); 
+					if (user == null) {//注册失败
+						return Response.FAILURE;
+					}
+				}else{
+					return Response.ERROR_REGISTER;
+				}
+		}
+		System.out.println(phone+"-注册成功!请求涂鸦");
+		//注册成功,返回用户信息
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * 第三方【微信】用户手机绑定,
+	 * @author Moon Cheng
+	 * @param phone 手机号
+	 * @param openId 微信的open——id
+	 * @return 1000:请求成功;2000:注册失败;
+	 */
+	@RequestMapping(value = "/third_part_binding_phone", method = RequestMethod.POST)
+	@ResponseBody
+	private Response thirdPartBindingPhone(@RequestParam("phone") String phone,
+			@RequestParam("open_id") String openId,@RequestParam("code") String code,
+			@RequestParam("areacode") String areacode 
+			) {
+		User user = new User();
+		int status = checkVerifyCode(phone, code, 1); //验证手机验证码是否正确
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} 
+		user = userService.thirdPartBindingPhone(areacode+","+phone, openId);
+		if (user == null) {
+			return Response.USER_NOT_EXIST;
+		}
+		
+		logger.info(user.getId() + "," + (user.getId().intValue() == 2011));
+		
+		if (user.getPassword() != null && user.getPassword().equals("EXTIES")) {
+			ResponseHeader header = new ResponseHeader(2011, "用户已经存在!", 1);
+			UserDTO dto = userService.tuyaConnect(user);
+			return new Response(header, dto);
+		}
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * login
+	 * 手机号登录,
+	 * @param phone 手机号
+	 * @param password 密码
+	 * @return 2012:身份验证失败;2013:账户冻结;1000:请求成功;
+	 */
+	@RequestMapping(value = "/login", method = RequestMethod.POST)
+	@ResponseBody
+	private Response login(@RequestParam(value = "phone", required = true) String phone,
+			@RequestParam(value = "password", required = true) String password) {
+		Object user = userService.login(phone, password);
+		int status = 0;
+		if (user instanceof Integer) {
+			status = (Integer) user;
+			switch (status) { 
+			case -1: //账号不存在
+				return Response.USER_NOT_EXIST;
+			case -2: //密码错误
+				return Response.AUTHENTICATION_ERROR;
+			case -3: //用户状态不正常
+				return Response.USER_FROZEN_ERROR;
+			}
+		}
+		return Response.SUCCESS.setData((UserDTO) user, 1);
+	}
+
+	/**
+	 * thirdPartLogin
+	 * 第三方登录
+	 * @param openId 微信open_id 
+	 * @param extType 来源 qq或者微信
+	 * @param extName extname
+	 * @param extPicture 图片
+	 * @return 2012:身份验证失败;2013:账户冻结;1000:请求成功;
+	 */
+	@RequestMapping(value = "/third_part_login", method = RequestMethod.POST)
+	@ResponseBody
+	private Response thirdPartLogin(@RequestParam(value = "open_id") String openId,
+			@RequestParam(value = "ext_type") String extType, @RequestParam(value = "ext_name") String extName,
+			@RequestParam(value = "ext_picture") String extPicture
+			) {
+		String ip = Utility.getIp(request);
+		User user1 = userService.thirdPartLogin(openId, extType, extName, extPicture, ip);
+
+		if (Constants.USER_INACTIVE.equals(user1.getStatus_())) {
+			return Response.USER_FROZEN_ERROR;
+		}
+ // 这里不注册涂鸦,给涂鸦账号,密码
+		UserDTO userInfo = new UserDTO(user1.getId(), user1.getUsername(), user1.getPassword(), user1.getToken(), user1.getDisplay_name(),
+				user1.getDisplay_picture(), user1.getCreated_on(), user1.getExt_open_id(), user1.getExt_name(), user1.getExt_type(),
+				user1.getLocation(), user1.getBaby_nickname() == null? "寶寶" : user1.getBaby_nickname(), user1.getBaby_dob(), user1.getBaby_gender(), user1.getStatus_());
+		userInfo.setPassword(null);
+		userInfo.setCountry_code(user1.getCountry_code());
+		userInfo.setEncryptUsername(AES.encrypt(user1.getUsername()));
+		userInfo.setUserCode("iamberry123");
+		userInfo.setIs_perfect_user(user1.getIs_perfect_user() == null? 1 : user1.getIs_perfect_user());
+		
+		return Response.SUCCESS.setData(userInfo);
+	}
+
+	/**
+	 * getUserInfo
+	 * 获取用户基本信息
+	 * @param id 用户id
+	 * @token  用户token 登录的时候设置的唯一的token
+	 * @return Response 2100:无效token;2020:无效用户;1000:请求成功;
+	 */
+	@RequestMapping(value = "/get_user_info", method = RequestMethod.POST)
+	@ResponseBody
+	private Response getUserInfo(@RequestParam(value = "user_id", required = true) Long id,
+			@RequestParam("token") String token) {
+		User userInfo = userService.validateUserToken(token);
+		if (userInfo == null) {//token不存在,表示登录的时候没有..
+			return Response.INVALID_TOKEN;
+		}
+		User user = userService.findById(id);
+		if (user == null) { //未找到
+			return Response.INVALID_PARMS;
+		}
+		return Response.SUCCESS.setData(user, 1);
+	}
+
+	/**
+	 * updateProfile
+	 * 更新用户基本信息
+	 * @param user 用户信息
+	 * @param token token
+	 * @return Response 2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/update_profile", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateProfile(User user, @RequestParam("token") String token) {
+		User user1 = userService.updateUserInfo(user, token);
+		if (user1 == null) {
+			return Response.INVALID_TOKEN;
+		}
+//		userInfo.setEncryptUsername(AES.encrypt(user.getUsername()));
+//		userInfo.setUserCode("iamberry123");
+		
+		UserDTO userInfo = new UserDTO(user1.getId(), user1.getUsername(), user1.getPassword(), user1.getToken(), user1.getDisplay_name(),
+				user1.getDisplay_picture(), user1.getCreated_on(), user1.getExt_open_id(), user1.getExt_name(), user1.getExt_type(),
+				user1.getLocation(), user1.getBaby_nickname(), user1.getBaby_dob(), user1.getBaby_gender(), user1.getStatus_());
+		userInfo.setPassword(null);
+		userInfo.setCountry_code(user1.getCountry_code());
+		userInfo.setEncryptUsername(AES.encrypt(user1.getUsername()));
+		userInfo.setUserCode("iamberry123");
+		return Response.SUCCESS.setData(userInfo, 1);
+	}
+
+	private BASE64Decoder decoder = new BASE64Decoder();  
+	
+	/**
+	 * updateDisplayPicture
+	 * 更改用户头像
+	 * @param user 用户信息
+	 * @param token 唯一标识符
+	 * @return Response
+	 * @throws IOException 
+	 */
+	@RequestMapping(value = "/update_display_picture", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateDisplayPicture(@RequestParam("picture_base64") String pictureBase64,
+			@RequestParam("token") String token, HttpServletRequest request) throws IOException {
+		// 判断文件类型
+		byte [] b = new byte[28];
+		pictureBase64.getBytes(0, 27, b, 0);
+		String temp = new String(b);
+		try {
+			b = decoder.decodeBuffer(temp);
+		} catch (IOException e) {
+			logger.error("updateDisplayPicture:" + e.getMessage());
+			return Response.FAILURE;
+		}
+		String type = null;					// 文件类型
+		String fileHead = byte2hex(b);		// 文件头
+		fileHead = fileHead.toUpperCase();
+		type = getType(fileHead);
+		if (type == null) {
+			return Response.FAILURE;
+		}
+		// 获取保存地址
+		String savePath = request.getServletContext().getRealPath(saveRootPath);
+		StringBuilder tempDir = new StringBuilder(savePath);
+		Long ran = new Date().getTime();
+		tempDir.append(File.separator);
+		tempDir.append(ran);
+		tempDir.append(File.separator);
+		// 判断保存路径是否存在,如果不存在,那么创建
+		File file=new File(savePath);
+		if (!file.exists()) {
+			logger.info("updateDisplayPicture-exists");
+			file.mkdirs();
+		}
+		// 获取保存文件名称
+		StringBuilder saveName = new StringBuilder(TokenUtil.getToken());
+		saveName.append(".").append(type);
+		tempDir.append(saveName);
+		// 保存磁盘
+		String userHeadURL = null;
+		if (!generateImage(pictureBase64, tempDir.toString())) {
+			logger.error("updateDisplayPicture-generateImage saveFile Error");
+			return Response.FAILURE;
+		} else {
+			userHeadURL = domain + request.getContextPath() + saveRootPath + ran + "/" + saveName.toString();
+		}
+		// 保存
+		String path = userService.updateDisplayPicture(userHeadURL, token);
+		return Response.SUCCESS.setData(path, 1);
+	}
+	
+	private String getType(String fileHead) {
+		FileType [] fileTypes = FileType.values();
+		for (FileType fileType : fileTypes) {
+			if (fileHead.startsWith(fileType.getValue())) {
+				return fileType.getSuffix();
+			}
+		}
+		return null;
+	}
+	
+	private boolean generateImage(String imgStr, String imgFilePath) throws IOException {  
+		// Base64解码  
+		byte[] bytes = decoder.decodeBuffer(imgStr);
+		for (int i = 0; i < bytes.length; ++i) {  
+			if (bytes[i] < 0) {
+				// 调整异常数据  
+				bytes[i] += 256;  
+			}  
+		}  
+		// 生成图片 
+		File file = new File(imgFilePath);
+		FileUtils.writeByteArrayToFile(file, bytes);
+		return true;  
+	}
+
+	private String byte2hex(byte[] b) {
+       // 转成16进制字符串
+       String hs = "";
+       String tmp = "";
+       for (int n = 0; n < b.length; n++) {
+           //整数转成十六进制表示
+           tmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
+           if (tmp.length() == 1) {
+               hs = hs + "0" + tmp;
+           } else {
+               hs = hs + tmp;
+           }
+       }
+       tmp = null;
+       return hs;
+   }
+
+	/**
+	 * 此方法可以不再使用
+	 */
+	@RequestMapping(value = "/avator/{id}/{rand}", method = RequestMethod.GET)
+	@ResponseBody
+	@Deprecated
+	private void getDisplayPicture() {
+		String url = request.getRequestURI();
+		url = url.substring(0, url.lastIndexOf('/'));
+		String userID = url.substring(url.lastIndexOf('/') + 1);
+		String avator = userService.selectUserAvator(Long.valueOf(userID));
+		response.setContentType("image/jpg");
+		try {
+			OutputStream os = response.getOutputStream();
+			BASE64Decoder decoder = new BASE64Decoder();
+			byte[] decoderBytes = decoder.decodeBuffer(avator);
+			os.write(decoderBytes);
+			os.flush();
+			os.close();
+		} catch (Exception e) {
+			// TODO: handle exception
+		}
+	}
+
+	/**
+	 * changePassword
+	 * 修改手机密码
+	 * @param oldPassword 新密码
+	 * @param newPassword 旧密码
+	 * @param token token
+	 * @return Response 2101:验证码错误;2102:验证码超时;2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/change_password", method = RequestMethod.POST)
+	@ResponseBody
+	private Response changePassword(@RequestParam("old_password") String oldPassword,
+			@RequestParam("new_password") String newPassword, @RequestParam("token") String token) {
+		int status = userService.changePassword(oldPassword, newPassword, token);
+		if (status == -1) { //token错误
+			return Response.INVALID_TOKEN;
+		} else if (status == 0) { //密码错误
+			return Response.ERROR_OLDPASSWORD;
+		} else { 
+			return Response.SUCCESS.setData(null);
+		}
+	}
+
+	/**
+	 * changePhone
+	 * 修改手机号码
+	 * @author Moon Cheng, Yin
+	 * @param newPhone 新手机号
+	 * @param token token
+	 * @param verificationCode 手机验证码
+	 * @return2101:验证码错误;2102:验证码超时;2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/change_phone", method = RequestMethod.POST)
+	@ResponseBody
+	private Response changePhone(@RequestParam("new_phone") String newPhone,
+			@RequestParam("verification_code") String verificationCode, @RequestParam("token") String token) {
+		int status = checkVerifyCode(newPhone, verificationCode, 2);
+		User user = null;
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else if (status == 1) { 
+			user = userService.changePhone(newPhone, token);
+			if (user == null) {
+				return Response.INVALID_TOKEN;
+			}
+		}
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * resetPassword
+	 * 重置手机密码
+	 * @param username 用户米
+	 * @param newPassword 新密码
+	 * @param verificationCode 验证码
+	 * @return2101:验证码错误;2102:验证码超时;2001:无效用户;2000:重置密码失败; 1000:请求成功;
+	 */
+	@RequestMapping(value = "/reset_password", method = RequestMethod.POST)
+	@ResponseBody
+	private Response resetPassword(@RequestParam(value = "username") String username,
+			@RequestParam("new_password") String newPassword,
+			@RequestParam("verification_code") String verificationCode) {
+		int status = checkVerifyCode(username, verificationCode, 3);
+		if (status == -1) {//验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else if (status == 1) { 
+			status = userService.resetPassWord(username, newPassword);
+			if (status == -3) {//账号不存在
+				return Response.USER_NOT_EXIST; 
+			} else if (status == 0) {
+				return Response.FAILURE;
+			}
+		}
+
+		return Response.SUCCESS.setData(null);
+	}
+
+	/**
+	 * 发送手机验证码
+	 * @param phone 手机号 
+	 * @param statusCode  1代表注册,2代表更换手机号,3代表忘记密码
+	 * @return
+	 */
+	@RequestMapping(value = "/send_code", method = RequestMethod.GET)
+	@ResponseBody
+	private Response sendCode(@RequestParam("phone") String phone, @RequestParam("status_code") int statusCode,@RequestParam("areacode") String areacode) {
+		String code = null;
+		Map<String, Integer> status = new HashMap<>();
+		User user = new User();
+		try {
+			/*switch (statusCode) {
+			case 1:// register
+				user = userService.selectUserByUsername(phone);
+				if (user != null) {
+					return Response.ERROR_REGISTER;
+				}
+				
+				break;
+			case 2:// change phone
+				user = userService.selectUserByUsername(phone);
+				if (user != null) {
+					return Response.ERROR_REGISTER;
+				}
+
+				break;
+			case 3:// reset password
+				user = userService.selectUserByUsername(phone);
+				if (user == null) {
+					return Response.USER_NOT_EXIST;
+				}
+
+				break;
+			default:
+				break;
+			}*/
+			codeService.sendCode(areacode+","+phone, statusCode);
+			status.put("code", 0);
+		} catch (Exception e) {
+			System.out.println(e);
+			return Response.SERVER_INTERNAL_ERROR;
+		}
+		if (0 == status.get(Constants.SMS_RETURNCODE)) {
+			return Response.SUCCESS.setData(code, 0);
+		} else {
+			return Response.FAILURE.setHeader(new ResponseHeader(status.get(Constants.SMS_RETURNCODE), "", 0));
+		}
+	}
+
+	/**
+	 * 获取封面图片
+	 * @return json
+	 */
+	@RequestMapping(value = "/start_page", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getStartPage() {
+		String pageUrl = userService.getStartPage();
+		return Response.SUCCESS.setData(pageUrl, 1);
+	}
+
+	/**
+	 * 获取地址url
+	 * @return
+	 */
+	@RequestMapping(value = "/get_location", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getLocation() {
+		String IP = Utility.getIp(request);
+		 //String IP = "183.14.17.153";
+		RemoteIpInfoDTO remoteIpInfoDTO = userService.getLocation(IP);
+		return Response.SUCCESS.setData(remoteIpInfoDTO, 1);
+	}
+	
+	/**
+	 * 获取app版本号
+	 * @return
+	 */
+	@RequestMapping(value = "/get_version", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getApkVersion() {
+		return Response.SUCCESS.setData(userService.getApkVersion());
+	}
+}

+ 1 - 0
iamberry-app-international/.svn/pristine/5f/5fa5e36180fac8708ac7a25f5380bdb519b8de05.svn-base

@@ -0,0 +1 @@
+username-EN=何秀刚ˆš

+ 13 - 0
iamberry-app-international/.svn/pristine/68/68ca41ed890bd786cc693f5f9b3dd33bf2dbe899.svn-base

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main/webapp"/>
+	<classpathentry kind="src" path="target/m2e-wtp/web-resources"/>
+	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
+		<attributes>
+			<attribute name="hide" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
+	<classpathentry kind="output" path=""/>
+</classpath>

+ 7 - 0
iamberry-app-international/.svn/pristine/69/699dd1b472ad34f5c04d726361332c26f57000d1.svn-base

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+  <fixed facet="wst.jsdt.web"/>
+  <installed facet="java" version="1.5"/>
+  <installed facet="jst.web" version="2.3"/>
+  <installed facet="wst.jsdt.web" version="1.0"/>
+</faceted-project>

+ 260 - 0
iamberry-app-international/.svn/pristine/70/70c2440d479ec32dbfd186726a5d80399cd1ec7f.svn-base

@@ -0,0 +1,260 @@
+package com.iamberry.app.international.controller;
+
+import static com.iamberry.app.config.Response.SUCCESS;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.iamberry.app.config.Response;
+import com.iamberry.app.core.dto.JpushMessageDTO;
+import com.iamberry.app.core.entity.Message;
+import com.iamberry.app.core.entity.User;
+import com.iamberry.app.core.serch.SerchParam;
+import com.iamberry.app.international.util.Jdpush;
+import com.iamberry.wechat.core.entity.PageBean;
+import com.iamberry.wechat.core.entity.banner.MessageDTO;
+
+/**
+ * MessageController
+ *
+ * @author lc
+ * @date 2016年9月13日17:50:59
+ */
+@Controller
+@RequestMapping("/secure/message")
+public class MessageController extends BaseController {
+
+	@InitBinder("message")
+	public void initBinderMessage(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("message.");
+	}
+
+	
+	/**
+	 * 查询所有消息 并分页
+	 * 2016年9月14日09:40:10
+	 * @author lc
+	 * @param page	分页信息
+	 * @return
+	 */
+	@RequestMapping("/list")
+	public ModelAndView getMessageList(@RequestParam(value= "pageSize",defaultValue= "15" ,required=false) Integer pageSize, 
+			@RequestParam(value = "pageNO", defaultValue = "1",required=false) Integer pageNO,
+			SerchParam params,
+			HttpServletRequest request) throws Exception {
+		StringBuffer url = new StringBuffer("/secure/message/list?pageSize=" + pageSize);
+		ModelAndView mv = new ModelAndView("message/messageList");
+		//String goodName = request.getParameter("goodsInfoGoodname");
+		PageBean page = new PageBean();	//分页信息
+		page.setPageSize(pageSize);
+		page.setPageNumber(pageNO);
+		
+		if (StringUtils.isNoneEmpty(params.getTitle())) {
+			url.append("&title=" + params.getTitle());
+		}
+		if (StringUtils.isNoneEmpty(params.getBeginDate())) {
+			url.append("&beginDate=" + params.getBeginDate());
+		}
+		if (StringUtils.isNoneEmpty(params.getEndDate())) {
+			url.append("&endDate=" + params.getEndDate());
+		}
+		if (StringUtils.isNoneEmpty(params.getUsername())) {
+			url.append("&username=" + params.getUsername());
+		}
+		
+System.out.println(url);
+		page.setParams(params);
+		
+		List<Message> messages = messageService.selectMessageRecoreds(page);
+		url.append("&pageNO=");
+		int count = messageService.selectMessageCount(params);
+		int pageCount =  count % page.getPageSize() == 0? count/page.getPageSize():(count/page.getPageSize())+1;
+		//分页用
+		mv.addObject("list", messages);
+		mv.addObject("pageNO", pageNO);
+		mv.addObject("url", url);
+		mv.addObject("params", params);
+		mv.addObject("pageSize", pageCount);	
+		return mv;
+	}
+	
+	/**
+	 * 查询所有用户信息 并分页
+	 * 2016年9月14日09:40:10
+	 * @author lc
+	 * @param page	分页信息
+	 * @return
+	 */
+	@RequestMapping("/listuser")
+	public ModelAndView getUserList(@RequestParam(value= "pageSize",defaultValue= "15" ,required=false) Integer pageSize, 
+			@RequestParam(value = "pageNO", defaultValue = "1",required=false) Integer pageNO, 
+			SerchParam params,
+			HttpServletRequest request) throws Exception {
+		StringBuffer url = new StringBuffer("/secure/message/listuser?pageSize=" + pageSize);
+		ModelAndView mv = new ModelAndView("message/userList");
+		PageBean page = new PageBean();	//分页信息
+		page.setPageSize(pageSize);
+		page.setPageNumber(pageNO);
+		if (StringUtils.isNoneEmpty(params.getUsername())) {
+			url.append("&username=" + params.getUsername());
+		}
+		
+		page.setParams(params);//设置查询条件
+		List<User> users = messageService.selectUser(page);
+		url.append("&pageNO=");
+		int count = messageService.selectUserCount(params);
+		int pageCount =  count % page.getPageSize() == 0? count/page.getPageSize():(count/page.getPageSize())+1;
+		//分页用
+		mv.addObject("memberList", users);
+		mv.addObject("pageNO", pageNO);
+		mv.addObject("url", url);
+		mv.addObject("username", params.getUsername());
+		mv.addObject("pageSize", pageCount);	
+		return mv;
+	}
+	
+	/**
+	 * 进入添加页面
+	 * 2016年4月21日
+	 * @author 穆再兴
+	 * @return
+	 */
+	@RequestMapping(value ="/insert", method = RequestMethod.GET)
+	public ModelAndView toinsertMessage(){
+		ModelAndView mv = new ModelAndView("message/insertMessage");
+		return mv;
+	}
+	
+	/**
+	 * 添加一个消息
+	 * 2016年9月14日09:48:12
+	 * @author lc
+	 * @return
+	 */
+	@RequestMapping(value ="/insert", method = RequestMethod.POST)
+	public ModelAndView insertMessage(HttpServletRequest req,Message message){
+		ModelAndView mv = new ModelAndView("message/insertMessage");
+		
+		Integer n = 0;
+		//这里判断是否需要推送,调用推送util
+		if(message.getIs_needsend()==1){ //1需要推送,2不需要
+			String sendresult = Jdpush.buildPushObject_all_notifi(message);
+			message.setSend_result(sendresult);
+		}
+		//设置调用推送结果,
+		n =  messageService.insertMessage(message);
+		
+		if(n > 0){
+			mv.addObject("msgObj", new MessageDTO(true, "操作结果", "添加成功!"));
+		}else{
+			mv.addObject("msgObj", new MessageDTO(true, "操作结果", "添加失败!"));
+		}
+		
+		return mv;
+	}
+	
+	
+	@RequestMapping(value = "/sendMessage", method = RequestMethod.GET)
+	private ModelAndView sendMessage() {
+		ModelAndView mv = new ModelAndView("/message/sendMessage");
+		return mv;
+	}
+	
+	/**
+	 * 发送极光推送
+	 * @param content 内容
+	 * @param tag 目标人群的标签
+	 * @param platform 平台
+	 * @return
+	 */
+	@RequestMapping(value = "/sendMessage", method = RequestMethod.POST)
+	private ModelAndView sendMessage2(JpushMessageDTO jpushmessage) {
+		ModelAndView mv = new ModelAndView("/message/sendMessage");
+		String  resultCode = Jdpush.sendmessage_jpushmessage(jpushmessage);
+		
+		Message message = new Message();
+		message.setTitle(jpushmessage.getContent());
+		message.setContent(jpushmessage.getContent());
+		message.setUser(Long.parseLong(jpushmessage.getTag())); //tag 有规范,徐特殊处理
+		message.setRemark(jpushmessage.getPlatform());
+		message.setSend_result(resultCode);
+		message.setUrl(request.getParameter("url"));
+		//添加到数据库
+		messageService.insertMessage(message);
+System.out.println(resultCode);
+		return mv;
+	}
+	
+	/**
+	 * 点击发送极光推送
+	 * @param content 内容
+	 * @return
+	 */
+	@RequestMapping(value = "/sendMessageByid", method = RequestMethod.POST)
+	@ResponseBody
+	private MessageDTO sendMessageByid(@RequestParam(value = "recordId") Long recordId) {
+		Message message = messageService.selectUserMessageByid(recordId);
+		//修改到数据库
+		String sendresult = Jdpush.buildPushObject_all_notifi(message);
+		message.setSend_result(sendresult);
+		int i = messageService.updateMessage(message);
+		return new MessageDTO(true, "操作结果",sendresult);
+	}
+	
+	/**
+	 * 获取用户已读,未读消息
+	 * @param token 用户token
+	 * @param isread 1已读,2 未读
+	 * @return 用户已读,未读的条数 
+	 */
+	@RequestMapping(value = "/select_userMessage_byisread", method = RequestMethod.POST)
+	@ResponseBody
+	private Response selectUserMessageByisread(@RequestParam(value = "token") String token,@RequestParam("isread") Long isread) {
+		int messCount = messageService.selectUserMessageByisread(token,isread);
+		if (messCount == -1){
+			return Response.INVALID_TOKEN;
+		}
+		return SUCCESS.setData(messCount, messCount);
+	}
+	
+	/**
+	 * 根据用户token获取用户的所有消息
+	 * @param token 用户token
+	 * @return 用户的所有消息
+	 */
+	@RequestMapping(value = "/select_userMessage_recoreds", method = RequestMethod.POST)
+	@ResponseBody
+	private Response selectUserMessageRecoreds(@RequestParam(value = "token") String token) {
+		List<Message> messages = messageService.selectUserMessageRecoreds(token);
+		if (messages == null){
+			return Response.INVALID_TOKEN;
+		}
+		return SUCCESS.setData(messages, messages.size());
+	}
+	
+	/**
+	 * 根据消息id获取消息实体类--并修改为已读
+	 * @param recordId 消息实体类主键id
+	 * @return 消息实体类
+	 */
+	@RequestMapping(value = "/select_userMessage_byid", method = RequestMethod.POST)
+	@ResponseBody
+	private Response selectUserMessageByid(@RequestParam(value = "recordId") Long recordId) {
+		Message message = messageService.selectUserMessageByid(recordId);
+		if (message == null){
+			return Response.NOT_FOUND;
+		}
+		return SUCCESS.setData(message, 1);
+	}
+}

+ 37 - 0
iamberry-app-international/.svn/pristine/73/7322e445e86a8d348cda9f6affcb614074a0633a.svn-base

@@ -0,0 +1,37 @@
+package com.iamberry.app.international.model;
+
+import java.io.Serializable;
+
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @company	深圳爱贝源科技有限公司
+ * @website www.iamberry.com
+ * @author 	献
+ * @tel		18271840547
+ * @date	2016年9月22日
+ * @explain	上传文件model,只支持上传1张图片
+ */
+public class FileModel implements Serializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 7885284566024140520L;
+	private MultipartFile[] file;
+
+	
+	
+	
+	public FileModel() {
+		super();
+	}
+
+	public MultipartFile[] getFile() {
+		return file;
+	}
+
+	public void setFile(MultipartFile[] file) {
+		this.file = file;
+	}
+}

+ 131 - 0
iamberry-app-international/.svn/pristine/78/784922537c371568589b21ce066069b0048c97e5.svn-base

@@ -0,0 +1,131 @@
+
+package com.iamberry.app.international.util.kafka;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.security.auth.login.Configuration;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+
+import org.apache.kafka.clients.CommonClientConfigs;
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.apache.kafka.clients.consumer.ConsumerRecords;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+import com.alibaba.fastjson.JSON;
+import com.iamberry.app.face.MachineService;
+import com.iamberry.app.face.MilkService;
+
+public class KafkaConsumer implements ServletContextListener {
+
+	private static final Logger logger = LoggerFactory.getLogger(KafkaConsumer.class);
+	
+	public void contextInitialized(ServletContextEvent sce) {
+		WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
+		MachineService machineService = webApplicationContext.getBean(MachineService.class);
+		MilkService milkService = webApplicationContext.getBean(MilkService.class);
+		
+		String appKey = "5kkyurvvtt58bbuxueee";//填APP KEY
+		String secretKey = "rhj6na6u3y6uhy6qrbb3944mg5uqqpbb";//APP SECRET
+		org.apache.kafka.clients.consumer.KafkaConsumer<String, String> consumer = null;
+		Configuration configuration = Configuration.getConfiguration();
+		Configuration.setConfiguration(null);
+		try {
+			java.security.Security.setProperty("login.configuration.provider", "com.iamberry.app.international.util.kafka.SaslConfiguration");
+
+			Properties props = new Properties();
+			//根据不同区域填写,不同区域URL参考文档  https://docs.tuya.com/cn/cloudapi/cloud_access/#kafka
+			props.put("bootstrap.servers", "kafka.cloud.tuyaus.com:8092");
+			String groupId = "aby-real-group";
+			props.put("group.id", groupId);
+
+			InetAddress netAddress = InetAddress.getLocalHost();
+			String clientId = "cloud_" + appKey + "_" + netAddress.getHostAddress();
+			props.put("client.id", clientId);
+			props.put("enable.auto.commit", "true");
+			props.put("auto.commit.interval.ms", "10000");
+			props.put("session.timeout.ms", "30000");
+			props.put("max.poll.records", 1000);
+			props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
+			//可以自定义JSON格式的序列化
+			props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
+
+			props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SASL_PLAINTEXT");
+			props.put("sasl.mechanism", "PLAIN");
+
+			consumer = new org.apache.kafka.clients.consumer.KafkaConsumer<String, String>(props);
+			consumer.subscribe(Arrays.asList("device-cloud-out-" + appKey));
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+		} finally {
+			Configuration.setConfiguration(configuration);
+		}
+		final org.apache.kafka.clients.consumer.KafkaConsumer<String, String> finalKafkaConsumer = consumer;
+		if (consumer != null) {
+			new Thread(){
+				@Override
+				public void run(){
+					while (true) {
+						ConsumerRecords<String, String> records = finalKafkaConsumer.poll(1000);
+						//ConsumerRecord<String, String> record = new ConsumerRecord<String, String>("4", 1, 1, "data", "JD/i7iF1hWmH08X54IGwjQkOy2gSEPTryEPUGbopFa3tC0lAyPx3dHN8enyKEY1zBdZt+bu5RYHnK00TvWD07S+Ryi3vHIGtWhTh7JLSVMAI+PNQeZZ87ZCh+vQaLQletGi/2n9B/pp+GLDDWFEhnl+xaLeVgcR9oGhUxBTwRmQsM1gUrTyEjFxfEhSWDM7Y+oj8NKWtJKpSS2/dv6wxNv+OIs6LCVBq+R1cLb+c0WI=");
+						boolean flog = false;
+						String milkPowder = "";
+						Long milkTime = 0l;
+						try {
+							for (ConsumerRecord<String, String> record : records) {
+								logger.info("Received message: (" + record.key() + ", " + record.value() + ") at offset "
+										+ record.offset() + ",decrypt data="
+										+ AESBase64Util.decrypt(JSONObject.fromObject(record.value()).getString("data"), secretKey.substring(8, 24)));
+							//	+ AESBase64Util.decrypt(record.value(), secretKey.substring(8, 24)));
+								String data = AESBase64Util.decrypt(JSONObject.fromObject(record.value()).getString("data"), secretKey.substring(8, 24));//解析后的真正数据
+								JSONObject jasonObject = JSONObject.fromObject(data);
+						        JSONArray dps = jasonObject.getJSONArray("dps");
+						        for(int i = 0; i < dps.size(); i++){
+						        	Map maps = (Map) JSON.parse(dps.getString(i));
+							        for (Object obj : maps.keySet()){
+							            if(obj.equals("DEVECE_CONTROL_MILK")){
+							            	milkPowder = maps.get(obj).toString();
+							            	flog = true;//如果数据中包含当前字段,表示当前推送的数据为奶粉记录
+							            }
+							            if(obj.equals("t")){
+							            	milkTime = (Long)maps.get((obj));
+							            }
+							        }
+						        }
+						        if(flog){
+						        	// 根据机器ID 获取对应的用户id
+						        	String devId = jasonObject.getString("devId");
+									Long userId = machineService.selectUserIDByDevId(devId);
+									milkService.addRecordData(devId, milkPowder, milkTime, userId);
+									flog = false;
+						        }
+						     }
+						} catch (Exception e) {
+							logger.error("", e);
+						}
+					}
+				}
+			}.start();;
+		}
+	}
+	@Override
+	public void contextDestroyed(ServletContextEvent sce) {
+		// TODO Auto-generated method stub
+		
+	}
+}

+ 297 - 0
iamberry-app-international/.svn/pristine/7a/7abbe70eff09a278f8efbf40d834b54cba105dd5.svn-base

@@ -0,0 +1,297 @@
+package com.iamberry.app.international.controller;
+
+import static com.iamberry.app.config.Response.BARCODE_NOT_FOUND;
+import static com.iamberry.app.config.Response.INVALID_TOKEN;
+import static com.iamberry.app.config.Response.SUCCESS;
+import static com.iamberry.app.config.Response.INSERT_DUPLICATE;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.dao.DataAccessException;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.iamberry.app.config.APIStatus;
+import com.iamberry.app.config.Response;
+import com.iamberry.app.config.ResponseHeader;
+import com.iamberry.app.core.dto.RecordDTO;
+import com.iamberry.app.core.entity.MilkImages;
+import com.iamberry.app.core.entity.MilkMakingRecord;
+import com.iamberry.app.core.entity.MilkPowderInfo;
+import com.iamberry.app.core.entity.User;
+import com.iamberry.wechat.file.FileUtils;
+import com.iamberry.wechat.file.UploadResultBean;
+
+/**
+ * UserController
+ *
+ * @author Moon Cheng
+ * @date 2016年1月18日 上午11:53:04
+ */
+@Controller
+@RequestMapping("/secure/milk")
+public class MilkController extends BaseController {
+
+	@InitBinder("makingRecord")
+	public void initBinderRecord(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("makingRecord.");
+	}
+
+	@InitBinder("milkPowderInfo")
+	public void initBinderMilkPowder(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("milkPowderInfo.");
+	}
+
+	/**
+	 * 添加冲奶信息 
+	 * @author Moon Cheng
+	 * @param token 唯一标识符 
+	 * @param makingRecord 冲奶信息实体类
+	 * @return 1000:请求成功;2100:无效token;
+	 */
+	@RequestMapping(value = "/set_milk_making_record", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMilkMakingRecord(@RequestParam("token") String token, MilkMakingRecord makingRecord) {
+		//目前添加了新的冲奶数据同步接口,所以当前方法做空实现处理
+		if(1 == 1){
+			return SUCCESS.setData(makingRecord, 1);
+		}
+		makingRecord = milkService.setMilkMakingRecord(makingRecord, token);
+		if (makingRecord == null) {
+			return INVALID_TOKEN;
+		}
+		return SUCCESS.setData(makingRecord, 1);
+	}
+
+	/**
+	 *  通过日期,日期类型,统计某时间的,冲奶总量
+	 * @param token   唯一标识符
+	 * @param dateStatus 标识符 : day week year 
+	 * @param chosenDate 结束时间
+	 * @param machineMac 机器mac地址
+	 * @return
+	 */
+	@RequestMapping(value = "/search_user_records_by_time", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchUserRecordsByTime(@RequestParam(value = "token") String token,
+			@RequestParam("date_status") String dateStatus, @RequestParam("chosen_date") String chosenDate,
+			@RequestParam("devid") String machineMac) {
+
+		User userInfo = userService.validateUserToken(token);
+		if (userInfo == null) {
+			return INVALID_TOKEN;
+		}
+		Map<String, List<RecordDTO>> makingRecords = milkService.searchUserRecordsByTime(userInfo.getId(), dateStatus,
+				chosenDate, machineMac);
+		return SUCCESS.setData(makingRecords, makingRecords.size());
+	}
+
+	/**
+	 * 通过冲奶记录id获取冲奶记录详情
+	 * @author Moon Cheng
+	 * @param recordId 冲奶记录,id
+	 * @return 
+	 *//*
+	@RequestMapping(value = "/search_user_record_by_id", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchUserRecordById(@RequestParam(value = "record_id") Long recordId) {
+		MilkMakingRecord makingRecord = milkService.searchUserRecordById(recordId);
+		return SUCCESS.setData(makingRecord, 1);
+	}*/
+
+	/**
+	 * 根据用户id获取用户,冲奶总容量
+	 * @author Moon Cheng
+	 * @param userId  用户id 
+	 * @return
+	 */
+	@RequestMapping(value = "/get_user_total_milk_volume", method = RequestMethod.POST)
+	@ResponseBody
+	private Response getTotalMilkVolumeMadeByUser(@RequestParam(value = "user_id") Long userId) {
+		return SUCCESS.setData(milkService.getTotalMilkVolumeMadeByUser(userId), 0);
+	}
+
+	/**
+	 * 手动添加,奶粉信息!
+	 * @author Moon Cheng
+	 * @param token  唯一标识符
+	 * @param milkPowderInfo  奶粉信息
+	 * @return
+	 */
+	@RequestMapping(value = "/set_milk_powder_info", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMilkPowderInfo(@RequestParam(value = "token") String token, MilkPowderInfo milkPowderInfo) {
+		if(milkPowderInfo.getBar_code() == null){
+			return INVALID_TOKEN;
+		}
+		MilkPowderInfo	milkInfo = milkService.selectMilkPowderByBar(milkPowderInfo.getBar_code());
+		if(milkInfo != null){
+			return INSERT_DUPLICATE;
+		}
+		
+		// 勺量,每勺多少克     量勺 克数范围2-18
+		String amountStr = request.getParameter("a_mount");
+		if (amountStr == null) {
+			// 兼容低版本
+			milkPowderInfo = milkService.setMilkPowderInfo(milkPowderInfo, token);
+			if (milkPowderInfo == null) {
+				return INVALID_TOKEN;
+			}
+			return SUCCESS.setData(milkPowderInfo, 1);
+		}
+		
+		float amount = Float.parseFloat(amountStr);
+		// 勺数,多少少		量勺勺数范围 1-10
+		int spoonNum = Integer.parseInt(request.getParameter("spoon_num"));
+		// ML,1勺多少奶量  水量范围30-300
+		float spoonML = Float.parseFloat(request.getParameter("spoon_ml"));
+		
+		// 毫升/勺	
+		float s = spoonML / spoonNum;
+		
+		// 混合比 计算公式:勺量   * 勺数  / 毫升 / 100 = 混合比
+		float ratio = amount * spoonNum / spoonML * 100;
+		milkPowderInfo.setPowder_ratio(ratio);
+		milkPowderInfo.setWeight_per_spoon(amount);
+		milkPowderInfo.setMilk_volume_per_spoon(s);
+		
+		// 密度
+		/*
+		 *     A<13.2                6
+			   13.21<A<15.3          7
+			   15.31<A<17.4          8 
+			   17.41<A<19.5          9
+			   19.51<A<22.0         10 
+			   22.1 <A              10
+		 */
+		int m = 6;
+		if (ratio < 13.2) {
+			m = 6;
+		} else if (ratio > 13.21 && ratio < 15.3) {
+			m = 7;
+		} else if (ratio > 15.31 && ratio < 17.4) {
+			m = 8;
+		} else if (ratio > 17.41 && ratio < 19.5) {
+			m = 9;
+		} else {
+			m = 10;
+		}
+		milkPowderInfo.setDensity((float)m);
+		
+		// 保存操作
+		try {
+			milkPowderInfo = milkService.setMilkPowderInfo(milkPowderInfo, token);
+		} catch (DataAccessException  e) {
+			return INSERT_DUPLICATE;
+		}
+		
+		if (milkPowderInfo == null) {
+			return INVALID_TOKEN;
+		}
+		
+		// 保存图片
+		String imageFront = request.getParameter("imageFront");
+		String imageBar = request.getParameter("imageBar");
+		String imageFeed = request.getParameter("imageFeed");
+		MilkImages images = new MilkImages();
+		images.setImage_Front(imageFront);
+		images.setImage_Bar(imageBar);
+		images.setImage_Feed(imageFeed);
+		images.setImage_Milk_ID(milkPowderInfo.getId());
+		milkService.setMilkImages(images);
+		return SUCCESS.setData(milkPowderInfo, 1);
+	}
+
+	/**
+	 * 通过,条形码获取奶粉信息
+	 * @author Moon Cheng
+	 * @param barcode 条形码code
+	 * @return
+	 */
+	@RequestMapping(value = "/search_milk_powder_info_by_barcode", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkPowderInfoByBarCode(@RequestParam(value = "barcode") String barcode) {
+		MilkPowderInfo milkPowderInfo = milkService.searchMilkPowderInfoByBarCode(barcode);
+		if (milkPowderInfo == null) {
+			return BARCODE_NOT_FOUND;
+		}
+		return SUCCESS.setData(milkPowderInfo, 1);
+	}
+
+	/**
+	 * 铜鼓品牌名获取奶粉信息
+	 * @author Moon Cheng, Yin
+	 * @param brand 品牌名
+	 * @return
+	 */
+	@RequestMapping(value = "/search_milk_powder_infos_by_brand", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkPowderInfosByBrand(@RequestParam(value = "brand") String brand) {
+		Map<String, List<String>> milkPowderInfos = milkService.searchMilkPowderInfosByBrand(brand);
+		return SUCCESS.setData(milkPowderInfos, milkPowderInfos.size());
+	}
+
+	/**
+	 * 获取奶粉品牌
+	 * @author Yin 
+	 * @return  过滤掉品牌名中有.的 例如 a.b 这里或只查询到a
+	 */
+	@RequestMapping(value = "/search_milk_powder_brand", method = RequestMethod.GET)
+	@ResponseBody
+	private Response searchMilkPowderBrand() {
+		List<String> milkPowderInfos = milkService.searchMilkPowderBrand();
+		return SUCCESS.setData(milkPowderInfos, milkPowderInfos.size());
+	}
+
+	/**
+	 * 通过奶粉品牌、段数、系列、查询奶粉信息
+	 * @param brand 品牌
+	 * @param series 系列
+	 * @param level 段数
+	 * @return
+	 */
+/*	@RequestMapping(value = "/search_milk_info_by_brand_series_level", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkInfoByBrandSeriesLevel(@RequestParam("brand") String brand,
+			@RequestParam("series") String series, @RequestParam("level") String level) {
+		return SUCCESS.setData(milkService.searchMilkInfoByBrandSeriesLevel(brand, series, level), 1);
+	}*/
+
+	/**
+	 * 上传奶粉信息的域名,及保存的路径,需要tomcat单独域名映射/或者是nginx
+	 */
+	private static String SAVE_MILK_IMAGE_DOMAIN = "http://milk.iamberry.com/";
+	private static String SAVE_MILK_IMAGE_PATH = "/common/";
+	/**
+	 * @param model
+	 * @param request
+	 * @return
+	 */
+	@ResponseBody
+	@RequestMapping(value = "/upload_image", method = RequestMethod.POST)
+	public Response uploadFileImage(@RequestParam("file")MultipartFile[] files, HttpServletRequest request) {
+		Map<String, String> filemap= new HashMap<String, String>();
+		
+		for (int i = 0; i < files.length; i++) {
+			MultipartFile file = files[i];
+			// 保存文件
+			UploadResultBean bean = FileUtils.saveFile(request.getServletContext(), file, SAVE_MILK_IMAGE_PATH, false);
+			if (bean == null) {
+				// 文件有误
+				return new Response(new ResponseHeader(4204, "文件有误!", -1));
+			}
+			filemap.put("file"+i,SAVE_MILK_IMAGE_DOMAIN + bean.getSaveFileName());
+		}
+		return SUCCESS.setData(filemap, filemap.size());
+	}
+}

+ 22 - 0
iamberry-app-international/.svn/pristine/83/83ab51b62a8cb82a5ca748ea2c2e180ad5d299c7.svn-base

@@ -0,0 +1,22 @@
+package com.iamberry.app.international.model;
+
+import java.util.Date;
+
+public class FormatModel {
+	private double money;
+	private Date date;
+	public double getMoney() {
+		return money;
+	}
+	public Date getDate() {
+		return date;
+	}
+	public void setDate(Date date) {
+		this.date = date;
+	}
+	public void setMoney(double money) {
+		this.money = money;
+	}
+	
+	
+}

+ 8 - 0
iamberry-app-international/.svn/pristine/84/84d744f1cbbc113016f2802a37bfb20380fbfc72.svn-base

@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.8

+ 1 - 0
iamberry-app-international/.svn/pristine/87/87ab9531e1222351568346cf9057a0cae36112b8.svn-base

@@ -0,0 +1 @@
+org.eclipse.wst.jsdt.launching.baseBrowserLibrary

+ 377 - 0
iamberry-app-international/.svn/pristine/93/93955fa03a184dd76e7a2ee36bf862aae9cd0059.svn-base

@@ -0,0 +1,377 @@
+package com.iamberry.app.international.util;
+
+import static com.iamberry.app.config.ImberryConfig.SMS_PASSWORD;
+import static com.iamberry.app.config.ImberryConfig.SMS_TEXT;
+import static com.iamberry.app.config.ImberryConfig.SMS_URL;
+import static com.iamberry.app.config.ImberryConfig.SMS_USERNAME;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.text.MessageFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.apache.http.entity.mime.content.StringBody;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+
+import com.iamberry.app.config.Constants;
+import com.iamberry.app.core.dto.RecordDTO;
+import com.iamberry.app.tool.dto.AddressDTO;
+import com.iamberry.app.tool.util.HttpUtility;
+import com.iamberry.app.tool.util.JsonParseUtil;
+import com.iamberry.app.tool.util.Result;
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.StaxDriver;
+
+public class Utility {
+
+	public static String DATA_STORE = "";
+	private static final String AB = "123456789abcdefghijklmnpqrstuvwxyz";
+
+	private static Random rnd = new Random();
+
+	public static String getDateByDay() {
+		Calendar cal = Calendar.getInstance();
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(cal.get(Calendar.YEAR));
+		buffer.append(cal.get(Calendar.MONTH) + 1);
+		buffer.append(cal.get(Calendar.DAY_OF_MONTH));
+		return buffer.toString();
+	}
+
+	public static boolean contains(String[] array, String item) {
+		try {
+			for (int i = 0; i < array.length; i++) {
+				if (array[i].equals(item)) {
+					return true;
+				}
+			}
+		} catch (Exception ex) {
+
+		}
+		return false;
+	}
+
+	public static String normalizePath(String path) {
+		return path.replace("\\\\", "\\").replace("\\", "/").replace("//", "/").replace("..", ".");
+	}
+
+	public static String getRandomString(int len) {
+		StringBuilder sb = new StringBuilder(len);
+		for (int i = 0; i < len; i++)
+			sb.append(AB.charAt(rnd.nextInt(AB.length())));
+		return sb.toString();
+	}
+
+	public static int CalculateAge(Long date) {
+		Date birthDate = new Date(0);
+		if (date != null)
+			birthDate = new Date(date);
+		SimpleDateFormat format = new SimpleDateFormat("yyyy");
+		int birthYear = Integer.parseInt(format.format(birthDate));
+		int currentYear = Integer.parseInt(format.format(new Date(System.currentTimeMillis())));
+		int age = currentYear - birthYear;
+
+		return age;
+	}
+
+	public static List<RecordDTO> convertMap(List<Map<String, Object>> list, String dateType) {
+		List<RecordDTO> maps = new ArrayList<RecordDTO>();
+		try {
+			SimpleDateFormat sdf = null;
+			for (Map<String, Object> map : list) {
+				switch (dateType) {
+				case "days":
+					sdf = new SimpleDateFormat("yyyyMMddHH");
+					break;
+				case "weeks":
+					sdf = new SimpleDateFormat("yyyyMMdd");
+					break;
+				case "years":
+					sdf = new SimpleDateFormat("yyyyMM");
+					break;
+				}
+				Date key = sdf.parse(map.get(dateType).toString());
+				Double value = Double.parseDouble(map.get("volume").toString());
+				maps.add(new RecordDTO(key.getTime(), value));
+			}
+		} catch (Exception e) {
+		}
+		return maps;
+	}
+
+	public static Map<String, List<RecordDTO>> synAppMachineRecord(Map<String, List<RecordDTO>> oldMap) {
+		Map<String, List<RecordDTO>> synMap = oldMap;
+		int appSize = synMap.get("app").size();
+		int machineSize = synMap.get("machine").size();
+		int signer = 0;
+		long appDate = 0l, machineDate = 0l;
+		RecordDTO appRecord, machineRecord;
+		for (int i = 0; i < appSize && i < machineSize; i++) {
+			appRecord = synMap.get("app").get(i);
+			machineRecord = synMap.get("machine").get(signer);
+			appDate = appRecord.getRecordDate();
+			machineDate = machineRecord.getRecordDate();
+			if (appDate == machineDate) {
+				signer++;
+			} else if (appDate < machineDate) {
+				synMap.get("machine").add(i, new RecordDTO(appDate, 0));
+				machineSize++;
+				signer++;
+			} else {
+				synMap.get("app").add(signer, new RecordDTO(machineDate, 0));
+				appSize++;
+				signer++;
+			}
+		}
+		while (signer < machineSize) {
+			synMap.get("app").add(new RecordDTO(synMap.get("machine").get(signer).getRecordDate(), 0));
+			signer++;
+		}
+		while (signer < appSize) {
+			synMap.get("machine").add(new RecordDTO(synMap.get("app").get(signer).getRecordDate(), 0));
+			signer++;
+		}
+		return synMap;
+	}
+
+	public static Map<String, List<RecordDTO>> fillAppMachineRecordWithZero(Map<String, List<RecordDTO>> synedMap, String dataType,
+			String chosenDate) {
+		Map<String, List<RecordDTO>> fillMap = synedMap;
+		Calendar calendar = Calendar.getInstance();
+		List<Integer> existTimePoint = new ArrayList<Integer>();
+		long timePoint = 0l;
+		switch (dataType) {
+		case "days":
+			if (fillMap.get("app").isEmpty()) {
+				calendar.setTime(Utility.formatStringToDate("yyyy-MM-dd HH:mm:ss", chosenDate));
+			}
+			fillMap.get("app").forEach(record -> {
+				calendar.setTime(new Date(record.getRecordDate()));
+				existTimePoint.add(calendar.get(Calendar.HOUR_OF_DAY));
+			});
+			for (int i = 0; i < 24; i++) {
+				if (!existTimePoint.remove(new Integer(i))) {
+					calendar.set(Calendar.HOUR_OF_DAY, i);
+					timePoint = calendar.getTimeInMillis();
+					fillMap.get("app").add(i, new RecordDTO(timePoint, 0));
+					fillMap.get("machine").add(i, new RecordDTO(timePoint, 0));
+				}
+			}
+			break;
+		case "weeks":
+			if (fillMap.get("app").isEmpty()) {
+				calendar.setTime(Utility.formatStringToDate("yyyy-MM-dd HH:mm:ss", chosenDate));
+			}
+			fillMap.get("app").forEach(record -> {
+				calendar.setTime(new Date(record.getRecordDate()));
+				existTimePoint.add(calendar.get(Calendar.DAY_OF_WEEK));
+			});
+			if (existTimePoint.contains(new Integer(1))) {
+				calendar.add(Calendar.DATE, -7);
+			}
+			for (int i = 2; i <= 7; i++) {
+				if (!existTimePoint.remove(new Integer(i))) {
+					calendar.set(Calendar.DAY_OF_WEEK, i);
+					timePoint = calendar.getTimeInMillis();
+					fillMap.get("app").add(i - 2, new RecordDTO(timePoint, 0));
+					fillMap.get("machine").add(i - 2, new RecordDTO(timePoint, 0));
+				}
+			}
+			if (!existTimePoint.contains(new Integer(1))) {
+				calendar.add(Calendar.DATE, 7);
+				calendar.set(Calendar.DAY_OF_WEEK, 1);
+				timePoint = calendar.getTimeInMillis();
+				fillMap.get("app").add(new RecordDTO(timePoint, 0));
+				fillMap.get("machine").add(new RecordDTO(timePoint, 0));
+			}
+			break;
+		case "years":
+			if (fillMap.get("app").isEmpty()) {
+				calendar.setTime(Utility.formatStringToDate("yyyy-MM-dd HH:mm:ss", chosenDate));
+			}
+			fillMap.get("app").forEach(record -> {
+				calendar.setTime(new Date(record.getRecordDate()));
+				existTimePoint.add(calendar.get(Calendar.MONTH));
+			});
+			for (int i = 0; i <= 11; i++) {
+				if (!existTimePoint.remove(new Integer(i))) {
+					calendar.set(Calendar.MONTH, i);
+					timePoint = calendar.getTimeInMillis();
+					fillMap.get("app").add(i, new RecordDTO(timePoint, 0));
+					fillMap.get("machine").add(i, new RecordDTO(timePoint, 0));
+				}
+			}
+			break;
+		}
+		return fillMap;
+	}
+
+	public static String getRandomCode(int len) {
+		StringBuilder sb = new StringBuilder(len);
+		for (int i = 0; i < len; i++)
+			sb.append("0123456789".charAt(rnd.nextInt("0123456789".length())));
+		return sb.toString();
+	}
+
+	public static String getIp(HttpServletRequest request) {
+		String ip = request.getHeader("x-forwarded-for");
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getHeader("Proxy-Client-IP");
+		}
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getHeader("WL-Proxy-Client-IP");
+		}
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getRemoteAddr();
+		}
+		// 获取ip地址, 若多级代理,第一个IP为客户端真实IP,多个IP按照','分割
+		if (ip != null && ip.indexOf(",") != -1) {
+			ip = ip.split(",")[0];
+		}
+		return ip;
+	}
+
+	public static String CDN_WRITE_BASE_64_URL = "http://cms.iamberry.com/open-cdn/ssl/data/write/base64";
+
+	public static String uploadBase64File(String base64Data, String path) {
+		try {
+			if (base64Data != null) {
+				StringBody pic = new StringBody(base64Data, ContentType.DEFAULT_TEXT);
+				StringBody type = new StringBody("jpg", ContentType.TEXT_PLAIN);
+				HttpEntity entity = MultipartEntityBuilder.create().addPart("type", type).addPart("base64data", pic)
+						.build();
+				String result = HttpUtility.httpsPost(CDN_WRITE_BASE_64_URL, entity);
+
+//				JSONObject json = new JSONObject(result);
+//				int requestSatus = json.getJSONObject("header").getInt("status");
+//				if (1000 == requestSatus) {
+//					path = json.getJSONObject("data").get("url").toString();
+//				}
+
+				return path;
+			}
+		} catch (Exception e) {
+			return null;
+		}
+		return "";
+	}
+
+	public static String readFile(InputStream in) {
+		BufferedReader reader = null;
+		String result = "";
+		try {
+			InputStreamReader inputStreamReader = new InputStreamReader(in, "UTF-8");
+			reader = new BufferedReader(inputStreamReader);
+			String tempString = null;
+			while ((tempString = reader.readLine()) != null) {
+				result += tempString;
+			}
+			reader.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			if (reader != null) {
+				try {
+					reader.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		return result;
+	}
+
+	public static String sendCodeAsSMS(String phoneNum, Map<String, Integer> status) throws Exception {
+		String code = getRandomCode(4);
+		CloseableHttpClient client = HttpClients.createDefault();
+		Map<String, String> params = new HashMap<String, String>();
+		CloseableHttpResponse response = null;
+		params.put("username", SMS_USERNAME);
+		params.put("password", SMS_PASSWORD);
+		params.put("mobile", phoneNum);
+		params.put("content", MessageFormat.format(SMS_TEXT, code));
+		HttpPost method = new HttpPost(SMS_URL);
+		if (params != null) {
+			List<NameValuePair> paramList = new ArrayList<NameValuePair>();
+			for (Map.Entry<String, String> param : params.entrySet()) {
+				NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
+				paramList.add(pair);
+			}
+			method.setEntity(new UrlEncodedFormEntity(paramList, "UTF-8"));
+		}
+		response = client.execute(method);
+		HttpEntity entity = response.getEntity();
+		if (entity != null) {
+			String result = EntityUtils.toString(entity);
+			XStream xs = new XStream(new StaxDriver());
+			xs.alias("result", Result.class);
+			Result object = (Result)xs.fromXML(result);
+			response.close();
+			status.put(Constants.SMS_RETURNCODE, object.getResultcode());
+			if (0 == object.getResultcode()) {
+				return code;
+			}
+		}
+		return null;
+	}
+
+	public static AddressDTO getDefaultAddress(String jsonList) {
+		List<AddressDTO> addressDTOs = JsonParseUtil.parseAddressList(jsonList);
+		for (AddressDTO addressDTO : addressDTOs) {
+			if (addressDTO.getDefaultAddress() == 1) {
+				return addressDTO;
+			}
+		}
+		return null;
+	}
+
+	public static String getOrderSn(Long id) {
+		if (id == null)
+			throw new NullPointerException("id can not be null");
+
+		SimpleDateFormat format = new SimpleDateFormat("yyMMdd");
+		String date = format.format(new Date());
+		String sn = String.format("%0" + 5 + "d", id);
+		return "LTR" + date + sn;
+	}
+
+	public static String formatDateToString(String format, Date date) {
+		SimpleDateFormat sdf = new SimpleDateFormat(format);
+		return sdf.format(date);
+	}
+
+	public static Date formatStringToDate(String format, String dateStr) {
+		SimpleDateFormat sdf = new SimpleDateFormat(format);
+		Date date = null;
+		try {
+			date = sdf.parse(dateStr);
+		} catch (ParseException e) {
+			e.printStackTrace();
+			date = new Date();
+		}
+		return date;
+	}
+
+}

+ 303 - 0
iamberry-app-international/.svn/pristine/95/95df5945e3fadcd750159ef1304b32ea5dee1c79.svn-base

@@ -0,0 +1,303 @@
+package com.iamberry.app.international.controller;
+
+import static com.iamberry.app.config.Response.BARCODE_NOT_FOUND;
+import static com.iamberry.app.config.Response.INVALID_TOKEN;
+import static com.iamberry.app.config.Response.SUCCESS;
+import static com.iamberry.app.config.Response.INSERT_DUPLICATE;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.dao.DataAccessException;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.iamberry.app.config.APIStatus;
+import com.iamberry.app.config.Response;
+import com.iamberry.app.config.ResponseHeader;
+import com.iamberry.app.core.dto.RecordDTO;
+import com.iamberry.app.core.entity.MilkImages;
+import com.iamberry.app.core.entity.MilkMakingRecord;
+import com.iamberry.app.core.entity.MilkPowderInfo;
+import com.iamberry.app.core.entity.User;
+import com.iamberry.wechat.file.FileUtils;
+import com.iamberry.wechat.file.UploadResultBean;
+
+/**
+ * UserController
+ *
+ * @author Moon Cheng
+ * @date 2016年1月18日 上午11:53:04
+ */
+@Controller
+@RequestMapping("/secure/milk")
+public class MilkController extends BaseController {
+
+	@InitBinder("makingRecord")
+	public void initBinderRecord(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("makingRecord.");
+	}
+
+	@InitBinder("milkPowderInfo")
+	public void initBinderMilkPowder(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("milkPowderInfo.");
+	}
+
+	/**
+	 * 添加冲奶信息 
+	 * @author Moon Cheng
+	 * @param token 唯一标识符 
+	 * @param makingRecord 冲奶信息实体类
+	 * @return 1000:请求成功;2100:无效token;
+	 */
+	@RequestMapping(value = "/set_milk_making_record", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMilkMakingRecord(@RequestParam("token") String token, MilkMakingRecord makingRecord) {
+		//目前添加了新的冲奶数据同步接口,所以当前方法做空实现处理
+		if(1 == 1){
+			return SUCCESS.setData(makingRecord, 1);
+		}
+		makingRecord = milkService.setMilkMakingRecord(makingRecord, token);
+		if (makingRecord == null) {
+			return INVALID_TOKEN;
+		}
+		return SUCCESS.setData(makingRecord, 1);
+	}
+
+	/**
+	 *  通过日期,日期类型,统计某时间的,冲奶总量
+	 * @param token   唯一标识符
+	 * @param dateStatus 标识符 : day week year 
+	 * @param chosenDate 结束时间
+	 * @param machineMac 机器mac地址
+	 * @return
+	 */
+	@RequestMapping(value = "/search_user_records_by_time", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchUserRecordsByTime(@RequestParam(value = "token") String token,
+			@RequestParam("date_status") String dateStatus, @RequestParam("chosen_date") String chosenDate,
+			@RequestParam("devid") String machineMac) {
+
+		User userInfo = userService.validateUserToken(token);
+		if (userInfo == null) {
+			return INVALID_TOKEN;
+		}
+		Map<String, List<RecordDTO>> makingRecords = milkService.searchUserRecordsByTime(userInfo.getId(), dateStatus,
+				chosenDate, machineMac);
+		return SUCCESS.setData(makingRecords, makingRecords.size());
+	}
+
+	/**
+	 * 通过冲奶记录id获取冲奶记录详情
+	 * @author Moon Cheng
+	 * @param recordId 冲奶记录,id
+	 * @return 
+	 *//*
+	@RequestMapping(value = "/search_user_record_by_id", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchUserRecordById(@RequestParam(value = "record_id") Long recordId) {
+		MilkMakingRecord makingRecord = milkService.searchUserRecordById(recordId);
+		return SUCCESS.setData(makingRecord, 1);
+	}*/
+
+	/**
+	 * 根据用户id获取用户,冲奶总容量
+	 * @author Moon Cheng
+	 * @param userId  用户id 
+	 * @return
+	 */
+	@RequestMapping(value = "/get_user_total_milk_volume", method = RequestMethod.POST)
+	@ResponseBody
+	private Response getTotalMilkVolumeMadeByUser(@RequestParam(value = "user_id") Long userId) {
+		return SUCCESS.setData(milkService.getTotalMilkVolumeMadeByUser(userId), 0);
+	}
+
+	/**
+	 * 手动添加,奶粉信息!
+	 * @author Moon Cheng
+	 * @param token  唯一标识符
+	 * @param milkPowderInfo  奶粉信息
+	 * @return
+	 */
+	@RequestMapping(value = "/set_milk_powder_info", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMilkPowderInfo(
+			@RequestParam(value = "a_mount") String amountStr,
+			@RequestParam(value = "spoon_num") String spoon_num,
+			@RequestParam(value = "spoon_ml") String spoon_ml,
+			@RequestParam(value = "imageFront") String imageFront,
+			@RequestParam(value = "imageBar") String imageBar,
+			@RequestParam(value = "imageFeed") String imageFeed,@RequestParam(value = "token") String token, MilkPowderInfo milkPowderInfo) {
+		if(milkPowderInfo.getBar_code() == null){
+			return INVALID_TOKEN;
+		}
+		MilkPowderInfo	milkInfo = milkService.selectMilkPowderByBar(milkPowderInfo.getBar_code());
+		if(milkInfo != null){
+			return INSERT_DUPLICATE;
+		}
+		
+		// 勺量,每勺多少克     量勺 克数范围2-18
+		//String amountStr = request.getParameter("a_mount");
+		if (amountStr == null) {
+			// 兼容低版本
+			milkPowderInfo = milkService.setMilkPowderInfo(milkPowderInfo, token);
+			if (milkPowderInfo == null) {
+				return INVALID_TOKEN;
+			}
+			return SUCCESS.setData(milkPowderInfo, 1);
+		}
+		
+		float amount = Float.parseFloat(amountStr);
+		// 勺数,多少少		量勺勺数范围 1-10
+		int spoonNum = Integer.parseInt(spoon_num);
+		// ML,1勺多少奶量  水量范围30-300
+		float spoonML = Float.parseFloat(spoon_ml);
+		
+		// 毫升/勺	
+		float s = spoonML / spoonNum;
+		
+		// 混合比 计算公式:勺量   * 勺数  / 毫升 / 100 = 混合比
+		float ratio = amount * spoonNum / spoonML * 100;
+		milkPowderInfo.setPowder_ratio(ratio);
+		milkPowderInfo.setWeight_per_spoon(amount);
+		milkPowderInfo.setMilk_volume_per_spoon(s);
+		
+		// 密度
+		/*
+		 *     A<13.2                6
+			   13.21<A<15.3          7
+			   15.31<A<17.4          8 
+			   17.41<A<19.5          9
+			   19.51<A<22.0         10 
+			   22.1 <A              10
+		 */
+		int m = 6;
+		if (ratio < 13.2) {
+			m = 6;
+		} else if (ratio > 13.21 && ratio < 15.3) {
+			m = 7;
+		} else if (ratio > 15.31 && ratio < 17.4) {
+			m = 8;
+		} else if (ratio > 17.41 && ratio < 19.5) {
+			m = 9;
+		} else {
+			m = 10;
+		}
+		milkPowderInfo.setDensity((float)m);
+		milkPowderInfo.setType(m);//同密度字段
+		// 保存操作
+		try {
+			milkPowderInfo = milkService.setMilkPowderInfo(milkPowderInfo, token);
+		} catch (DataAccessException  e) {
+			return INSERT_DUPLICATE;
+		}
+		
+		if (milkPowderInfo == null) {
+			return INVALID_TOKEN;
+		}
+		
+		// 保存图片
+		/*String imageFront = request.getParameter("imageFront");
+		String imageBar = request.getParameter("imageBar");
+		String imageFeed = request.getParameter("imageFeed");*/
+		MilkImages images = new MilkImages();
+		images.setImage_Front(imageFront);
+		images.setImage_Bar(imageBar);
+		images.setImage_Feed(imageFeed);
+		images.setImage_Milk_ID(milkPowderInfo.getId());
+		milkService.setMilkImages(images);
+		return SUCCESS.setData(milkPowderInfo, 1);
+	}
+
+	/**
+	 * 通过,条形码获取奶粉信息
+	 * @author Moon Cheng
+	 * @param barcode 条形码code
+	 * @return
+	 */
+	@RequestMapping(value = "/search_milk_powder_info_by_barcode", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkPowderInfoByBarCode(@RequestParam(value = "barcode") String barcode) {
+		MilkPowderInfo milkPowderInfo = milkService.searchMilkPowderInfoByBarCode(barcode);
+		if (milkPowderInfo == null) {
+			return BARCODE_NOT_FOUND;
+		}
+		return SUCCESS.setData(milkPowderInfo, 1);
+	}
+
+	/**
+	 * 铜鼓品牌名获取奶粉信息
+	 * @author Moon Cheng, Yin
+	 * @param brand 品牌名
+	 * @return
+	 */
+	@RequestMapping(value = "/search_milk_powder_infos_by_brand", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkPowderInfosByBrand(@RequestParam(value = "brand") String brand) {
+		Map<String, List<String>> milkPowderInfos = milkService.searchMilkPowderInfosByBrand(brand);
+		return SUCCESS.setData(milkPowderInfos, milkPowderInfos.size());
+	}
+
+	/**
+	 * 获取奶粉品牌
+	 * @author Yin 
+	 * @return  过滤掉品牌名中有.的 例如 a.b 这里或只查询到a
+	 */
+	@RequestMapping(value = "/search_milk_powder_brand", method = RequestMethod.GET)
+	@ResponseBody
+	private Response searchMilkPowderBrand() {
+		List<String> milkPowderInfos = milkService.searchMilkPowderBrand();
+		return SUCCESS.setData(milkPowderInfos, milkPowderInfos.size());
+	}
+
+	/**
+	 * 通过奶粉品牌、段数、系列、查询奶粉信息
+	 * @param brand 品牌
+	 * @param series 系列
+	 * @param level 段数
+	 * @return
+	 */
+/*	@RequestMapping(value = "/search_milk_info_by_brand_series_level", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkInfoByBrandSeriesLevel(@RequestParam("brand") String brand,
+			@RequestParam("series") String series, @RequestParam("level") String level) {
+		return SUCCESS.setData(milkService.searchMilkInfoByBrandSeriesLevel(brand, series, level), 1);
+	}*/
+
+	/**
+	 * 上传奶粉信息的域名,及保存的路径,需要tomcat单独域名映射/或者是nginx
+	 */
+	private static String SAVE_MILK_IMAGE_DOMAIN = "http://milk.iamberry.com/";
+	private static String SAVE_MILK_IMAGE_PATH = "/common/";
+	/**
+	 * @param model
+	 * @param request
+	 * @return
+	 */
+	@ResponseBody
+	@RequestMapping(value = "/upload_image", method = RequestMethod.POST)
+	public Response uploadFileImage(@RequestParam("file")MultipartFile[] files, HttpServletRequest request) {
+		Map<String, String> filemap= new HashMap<String, String>();
+		
+		for (int i = 0; i < files.length; i++) {
+			MultipartFile file = files[i];
+			// 保存文件
+			UploadResultBean bean = FileUtils.saveFile(request.getServletContext(), file, SAVE_MILK_IMAGE_PATH);
+			if (bean == null) {
+				// 文件有误
+				return new Response(new ResponseHeader(4204, "文件有误!", -1));
+			}
+			filemap.put("file"+i,SAVE_MILK_IMAGE_DOMAIN + bean.getSaveFileName());
+		}
+		return SUCCESS.setData(filemap, filemap.size());
+	}
+}

+ 4 - 0
iamberry-app-international/.svn/pristine/a1/a112be21c325d37ebc17baafd40c0386b5d09df1.svn-base

@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1

+ 79 - 0
iamberry-app-international/.svn/pristine/a1/a152df36efa7f1f06e6e1e722f067909dc39a875.svn-base

@@ -0,0 +1,79 @@
+package com.iamberry.app.international.controller;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.iamberry.app.config.Response;
+import com.iamberry.app.config.ResponseHeader;
+import com.iamberry.app.face.CodeService;
+import com.iamberry.app.face.LogService;
+import com.iamberry.app.face.MachineService;
+import com.iamberry.app.face.MessageService;
+import com.iamberry.app.face.MilkService;
+import com.iamberry.app.face.UserService;
+import com.iamberry.wechat.tools.ResponseJson;
+
+public class BaseController {
+
+	@Autowired
+	protected UserService userService;
+	@Autowired
+	protected MachineService machineService;
+	@Autowired
+	protected MilkService milkService;
+	@Autowired
+	LogService logService;
+	@Autowired
+	MessageService messageService;
+	@Autowired
+	HttpServletRequest request;
+	@Autowired
+	CodeService codeService;
+
+	public final static Map<String, Object> validateCodeMap = new ConcurrentHashMap<>();
+
+	protected static Response createResponse(ResponseHeader header, Object payload) {
+		return new Response(header, payload);
+	}
+
+	protected static Response createResponse(ResponseHeader header) {
+		return new Response(header);
+	}
+
+/**
+ **?*
+ */
+	/**
+	 * 判断用户的手机号码是否和短信验证码匹配,注意,此类实现方法,本身就是一个弊端,系统一旦长期运行,会导致内存崩溃。
+	 * @param phone				手机号码
+	 * @param verificationCode	短信验证码
+	 * @return
+	 */
+	protected int checkVerifyCode(String phone, String verificationCode, int codeScenario) {
+		ResponseJson json = codeService.validCode(phone, verificationCode, codeScenario);
+		if (json.getReturnCode() == 200) {
+			return 1;
+		} else if (json.getReturnCode() == 404) {
+			return -1;
+		}
+		return -2;
+	}
+
+	/**
+	 * 校验时间,如果发送时间+180s 大于 当前时间,返回false 
+	 * @param date
+	 * @return
+	 */
+	protected static boolean verifyCodeTime(Date date) {
+		Long nowDate = new Date().getTime();
+		if (date.getTime() + 180000 > nowDate) {
+			return false;
+		}
+		return true;
+	}
+}

+ 42 - 0
iamberry-app-international/.svn/pristine/a2/a2b094b2906a5f2271b328aaeb7a5285dfdf15a3.svn-base

@@ -0,0 +1,42 @@
+#levels: debug, info, warn, error, fatal
+log4j.rootLogger=info,stdout,infoLog,errorLog,dbLog
+
+#\u63a7\u5236\u53f0
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
+
+#\u4e3b\u65e5\u5fd7\u6587\u4ef6
+log4j.appender.infoLog=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.infoLog.File=D:/log/iamberry/app-international/iamberry_info.log
+log4j.appender.infoLog.Append=true
+log4j.appender.infoLog.Threshold=INFO
+log4j.appender.infoLog.layout=org.apache.log4j.PatternLayout
+log4j.appender.infoLog.layout.ConversionPattern=%d %p [%c] - %m %n 
+log4j.appender.infoLog.encoding=UTF-8
+
+#\u9519\u8bef\u65e5\u5fd7
+log4j.appender.errorLog=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.errorLog.File=D:/log/iamberry/app-international/iamberry_error.log
+log4j.appender.errorLog.Append=true
+log4j.appender.errorLog.Threshold=ERROR
+log4j.appender.errorLog.layout=org.apache.log4j.PatternLayout
+log4j.appender.errorLog.layout.ConversionPattern=%d %p [%c] - %m %n 
+log4j.appender.errorLog.encoding=UTF-8
+
+#debug\u4fe1\u606f
+log4j.appender.dbLog=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.dbLog.File=D:/log/iamberry/app-international/iamberry_debug.log
+log4j.appender.dbLog.Append=true
+log4j.appender.dbLog.Threshold=DEBUG
+log4j.appender.dbLog.layout=org.apache.log4j.PatternLayout
+log4j.appender.dbLog.layout.ConversionPattern=%d %p [%c] - %m %n 
+log4j.appender.dbLog.encoding=UTF-8
+
+#\u663e\u793aSQL\u8bed\u53e5\u90e8\u5206
+log4j.logger.com.iamberry.app=DEBUG
+log4j.logger.java.sql.ResultSet=INFO
+log4j.logger.java.sql.Connection=DEBUG
+log4j.logger.java.sql.Statement=DEBUG
+log4j.logger.java.sql.PreparedStatement=DEBUG

+ 24 - 0
iamberry-app-international/.svn/pristine/a7/a754255887f6026a6c102ed3f4e2e2e96f55fac9.svn-base

@@ -0,0 +1,24 @@
+package com.iamberry.app.international.util.kafka;
+
+import java.security.Key;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.binary.StringUtils;
+
+public class AESBase64Util {
+
+	private static final String AES = "AES";
+
+	public static String decrypt(String encryptedData, String secretKey) throws Exception {
+		Key key = new SecretKeySpec(secretKey.getBytes(), AES);
+		Cipher c = Cipher.getInstance(AES);
+		c.init(2, key);
+		byte[] decodedValue = Base64.decodeBase64(encryptedData);
+		byte[] decValue = c.doFinal(decodedValue);
+		String decryptedValue = StringUtils.newStringUtf8(decValue);
+		return decryptedValue;
+	}
+}

+ 40 - 0
iamberry-app-international/.svn/pristine/aa/aa037c8be163494b85ba4fbd4b4b62d2db35a0e3.svn-base

@@ -0,0 +1,40 @@
+<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>
+	<parent>
+		<groupId>com.iamberry</groupId>
+		<artifactId>iamberry-parent</artifactId>
+		<version>1.0.0</version>
+	</parent>
+
+	<artifactId>iamberry-app-international</artifactId>
+	<packaging>war</packaging>
+
+	<dependencies>
+		<dependency>
+			<groupId>com.iamberry</groupId>
+			<artifactId>iamberry-app-international-service</artifactId>
+			<version>1.0.0</version>
+			<exclusions>
+				<exclusion>
+					<artifactId>spring</artifactId>
+					<groupId>org.springframework</groupId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.slf4j</groupId>
+					<artifactId>jcl-over-slf4j</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.slf4j</groupId>
+					<artifactId>slf4j-jcl</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<!-- 新的项目使用druid -->
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>druid</artifactId>
+			<version>1.0.20</version>
+		</dependency>
+	</dependencies>
+</project>

+ 303 - 0
iamberry-app-international/.svn/pristine/aa/aa5c4f6f4a6d4e500cde870788aa77bffd8eb76c.svn-base

@@ -0,0 +1,303 @@
+package com.iamberry.app.international.controller;
+
+import static com.iamberry.app.config.Response.BARCODE_NOT_FOUND;
+import static com.iamberry.app.config.Response.INVALID_TOKEN;
+import static com.iamberry.app.config.Response.SUCCESS;
+import static com.iamberry.app.config.Response.INSERT_DUPLICATE;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.dao.DataAccessException;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.iamberry.app.config.APIStatus;
+import com.iamberry.app.config.Response;
+import com.iamberry.app.config.ResponseHeader;
+import com.iamberry.app.core.dto.RecordDTO;
+import com.iamberry.app.core.entity.MilkImages;
+import com.iamberry.app.core.entity.MilkMakingRecord;
+import com.iamberry.app.core.entity.MilkPowderInfo;
+import com.iamberry.app.core.entity.User;
+import com.iamberry.wechat.file.FileUtils;
+import com.iamberry.wechat.file.UploadResultBean;
+
+/**
+ * UserController
+ *
+ * @author Moon Cheng
+ * @date 2016年1月18日 上午11:53:04
+ */
+@Controller
+@RequestMapping("/secure/milk")
+public class MilkController extends BaseController {
+
+	@InitBinder("makingRecord")
+	public void initBinderRecord(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("makingRecord.");
+	}
+
+	@InitBinder("milkPowderInfo")
+	public void initBinderMilkPowder(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("milkPowderInfo.");
+	}
+
+	/**
+	 * 添加冲奶信息 
+	 * @author Moon Cheng
+	 * @param token 唯一标识符 
+	 * @param makingRecord 冲奶信息实体类
+	 * @return 1000:请求成功;2100:无效token;
+	 */
+	@RequestMapping(value = "/set_milk_making_record", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMilkMakingRecord(@RequestParam("token") String token, MilkMakingRecord makingRecord) {
+		//目前添加了新的冲奶数据同步接口,所以当前方法做空实现处理
+		if(1 == 1){
+			return SUCCESS.setData(makingRecord, 1);
+		}
+		makingRecord = milkService.setMilkMakingRecord(makingRecord, token);
+		if (makingRecord == null) {
+			return INVALID_TOKEN;
+		}
+		return SUCCESS.setData(makingRecord, 1);
+	}
+
+	/**
+	 *  通过日期,日期类型,统计某时间的,冲奶总量
+	 * @param token   唯一标识符
+	 * @param dateStatus 标识符 : day week year 
+	 * @param chosenDate 结束时间
+	 * @param machineMac 机器mac地址
+	 * @return
+	 */
+	@RequestMapping(value = "/search_user_records_by_time", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchUserRecordsByTime(@RequestParam(value = "token") String token,
+			@RequestParam("date_status") String dateStatus, @RequestParam("chosen_date") String chosenDate,
+			@RequestParam("devid") String machineMac) {
+
+		User userInfo = userService.validateUserToken(token);
+		if (userInfo == null) {
+			return INVALID_TOKEN;
+		}
+		Map<String, List<RecordDTO>> makingRecords = milkService.searchUserRecordsByTime(userInfo.getId(), dateStatus,
+				chosenDate, machineMac);
+		return SUCCESS.setData(makingRecords, makingRecords.size());
+	}
+
+	/**
+	 * 通过冲奶记录id获取冲奶记录详情
+	 * @author Moon Cheng
+	 * @param recordId 冲奶记录,id
+	 * @return 
+	 *//*
+	@RequestMapping(value = "/search_user_record_by_id", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchUserRecordById(@RequestParam(value = "record_id") Long recordId) {
+		MilkMakingRecord makingRecord = milkService.searchUserRecordById(recordId);
+		return SUCCESS.setData(makingRecord, 1);
+	}*/
+
+	/**
+	 * 根据用户id获取用户,冲奶总容量
+	 * @author Moon Cheng
+	 * @param userId  用户id 
+	 * @return
+	 */
+	@RequestMapping(value = "/get_user_total_milk_volume", method = RequestMethod.POST)
+	@ResponseBody
+	private Response getTotalMilkVolumeMadeByUser(@RequestParam(value = "user_id") Long userId) {
+		return SUCCESS.setData(milkService.getTotalMilkVolumeMadeByUser(userId), 0);
+	}
+
+	/**
+	 * 手动添加,奶粉信息!
+	 * @author Moon Cheng
+	 * @param token  唯一标识符
+	 * @param milkPowderInfo  奶粉信息
+	 * @return
+	 */
+	@RequestMapping(value = "/set_milk_powder_info", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMilkPowderInfo(
+			@RequestParam(value = "a_mount") String amountStr,
+			@RequestParam(value = "spoon_num") String spoon_num,
+			@RequestParam(value = "spoon_ml") String spoon_ml,
+			@RequestParam(value = "imageFront") String imageFront,
+			@RequestParam(value = "imageBar") String imageBar,
+			@RequestParam(value = "imageFeed") String imageFeed,@RequestParam(value = "token") String token, MilkPowderInfo milkPowderInfo) {
+		if(milkPowderInfo.getBar_code() == null){
+			return INVALID_TOKEN;
+		}
+		/*MilkPowderInfo	milkInfo = milkService.selectMilkPowderByBar(milkPowderInfo.getBar_code());
+		if(milkInfo != null){
+			return INSERT_DUPLICATE;
+		}*/
+		
+		// 勺量,每勺多少克     量勺 克数范围2-18
+		//String amountStr = request.getParameter("a_mount");
+		if (amountStr == null) {
+			// 兼容低版本
+			milkPowderInfo = milkService.setMilkPowderInfo(milkPowderInfo, token);
+			if (milkPowderInfo == null) {
+				return INVALID_TOKEN;
+			}
+			return SUCCESS.setData(milkPowderInfo, 1);
+		}
+		
+		float amount = Float.parseFloat(amountStr);
+		// 勺数,多少少		量勺勺数范围 1-10
+		int spoonNum = Integer.parseInt(spoon_num);
+		// ML,1勺多少奶量  水量范围30-300
+		float spoonML = Float.parseFloat(spoon_ml);
+		
+		// 毫升/勺	
+		float s = spoonML / spoonNum;
+		
+		// 混合比 计算公式:勺量   * 勺数  / 毫升 / 100 = 混合比
+		float ratio = amount * spoonNum / spoonML * 100;
+		milkPowderInfo.setPowder_ratio(ratio);
+		milkPowderInfo.setWeight_per_spoon(amount);
+		milkPowderInfo.setMilk_volume_per_spoon(s);
+		
+		// 密度
+		/*
+		 *     A<13.2                6
+			   13.21<A<15.3          7
+			   15.31<A<17.4          8 
+			   17.41<A<19.5          9
+			   19.51<A<22.0         10 
+			   22.1 <A              10
+		 */
+		int m = 6;
+		if (ratio < 13.2) {
+			m = 6;
+		} else if (ratio > 13.21 && ratio < 15.3) {
+			m = 7;
+		} else if (ratio > 15.31 && ratio < 17.4) {
+			m = 8;
+		} else if (ratio > 17.41 && ratio < 19.5) {
+			m = 9;
+		} else {
+			m = 10;
+		}
+		milkPowderInfo.setDensity((float)m);
+		milkPowderInfo.setType(m);//同密度字段
+		// 保存操作
+		try {
+			milkPowderInfo = milkService.setMilkPowderInfo(milkPowderInfo, token);
+		} catch (DataAccessException  e) {
+			return INSERT_DUPLICATE;
+		}
+		
+		if (milkPowderInfo == null) {
+			return INVALID_TOKEN;
+		}
+		
+		// 保存图片
+		/*String imageFront = request.getParameter("imageFront");
+		String imageBar = request.getParameter("imageBar");
+		String imageFeed = request.getParameter("imageFeed");*/
+		MilkImages images = new MilkImages();
+		images.setImage_Front(imageFront);
+		images.setImage_Bar(imageBar);
+		images.setImage_Feed(imageFeed);
+		images.setImage_Milk_ID(milkPowderInfo.getId());
+		milkService.setMilkImages(images);
+		return SUCCESS.setData(milkPowderInfo, 1);
+	}
+
+	/**
+	 * 通过,条形码获取奶粉信息
+	 * @author Moon Cheng
+	 * @param barcode 条形码code
+	 * @return
+	 */
+	@RequestMapping(value = "/search_milk_powder_info_by_barcode", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkPowderInfoByBarCode(@RequestParam(value = "barcode") String barcode) {
+		MilkPowderInfo milkPowderInfo = milkService.searchMilkPowderInfoByBarCode(barcode);
+		if (milkPowderInfo == null) {
+			return BARCODE_NOT_FOUND;
+		}
+		return SUCCESS.setData(milkPowderInfo, 1);
+	}
+
+	/**
+	 * 铜鼓品牌名获取奶粉信息
+	 * @author Moon Cheng, Yin
+	 * @param brand 品牌名
+	 * @return
+	 */
+	@RequestMapping(value = "/search_milk_powder_infos_by_brand", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkPowderInfosByBrand(@RequestParam(value = "brand") String brand) {
+		Map<String, List<String>> milkPowderInfos = milkService.searchMilkPowderInfosByBrand(brand);
+		return SUCCESS.setData(milkPowderInfos, milkPowderInfos.size());
+	}
+
+	/**
+	 * 获取奶粉品牌
+	 * @author Yin 
+	 * @return  过滤掉品牌名中有.的 例如 a.b 这里或只查询到a
+	 */
+	@RequestMapping(value = "/search_milk_powder_brand", method = RequestMethod.GET)
+	@ResponseBody
+	private Response searchMilkPowderBrand() {
+		List<String> milkPowderInfos = milkService.searchMilkPowderBrand();
+		return SUCCESS.setData(milkPowderInfos, milkPowderInfos.size());
+	}
+
+	/**
+	 * 通过奶粉品牌、段数、系列、查询奶粉信息
+	 * @param brand 品牌
+	 * @param series 系列
+	 * @param level 段数
+	 * @return
+	 */
+/*	@RequestMapping(value = "/search_milk_info_by_brand_series_level", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkInfoByBrandSeriesLevel(@RequestParam("brand") String brand,
+			@RequestParam("series") String series, @RequestParam("level") String level) {
+		return SUCCESS.setData(milkService.searchMilkInfoByBrandSeriesLevel(brand, series, level), 1);
+	}*/
+
+	/**
+	 * 上传奶粉信息的域名,及保存的路径,需要tomcat单独域名映射/或者是nginx
+	 */
+	private static String SAVE_MILK_IMAGE_DOMAIN = "http://milk.iamberry.com/";
+	private static String SAVE_MILK_IMAGE_PATH = "/common/";
+	/**
+	 * @param model
+	 * @param request
+	 * @return
+	 */
+	@ResponseBody
+	@RequestMapping(value = "/upload_image", method = RequestMethod.POST)
+	public Response uploadFileImage(@RequestParam("file")MultipartFile[] files, HttpServletRequest request) {
+		Map<String, String> filemap= new HashMap<String, String>();
+		
+		for (int i = 0; i < files.length; i++) {
+			MultipartFile file = files[i];
+			// 保存文件
+			UploadResultBean bean = FileUtils.saveFile(request.getServletContext(), file, SAVE_MILK_IMAGE_PATH);
+			if (bean == null) {
+				// 文件有误
+				return new Response(new ResponseHeader(4204, "文件有误!", -1));
+			}
+			filemap.put("file"+i,SAVE_MILK_IMAGE_DOMAIN + bean.getSaveFileName());
+		}
+		return SUCCESS.setData(filemap, filemap.size());
+	}
+}

+ 88 - 0
iamberry-app-international/.svn/pristine/ab/ab039ffeeccfdceaa75e33ca53e2a92c2944371d.svn-base

@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
+	id="WebApp_ID" version="3.1">
+	<display-name>iamberry-app-api</display-name>
+
+	<welcome-file-list>
+		<welcome-file>index.html</welcome-file>
+		<welcome-file>index.htm</welcome-file>
+		<welcome-file>index.jsp</welcome-file>
+		<welcome-file>default.html</welcome-file>
+		<welcome-file>default.htm</welcome-file>
+		<welcome-file>default.jsp</welcome-file>
+	</welcome-file-list>
+
+
+	<context-param>
+		<param-name>contextConfigLocation</param-name>
+		<param-value>classpath:iamberry-app-api-ioc.xml</param-value>
+	</context-param>
+	<listener>
+		<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
+	</listener>
+	<listener>
+		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+	</listener>
+
+	<servlet>
+		<servlet-name>springDispatcherServlet</servlet-name>
+		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+		<init-param>
+			<param-name>contextConfigLocation</param-name>
+			<param-value>classpath:iamberry-app-api-mvc.xml</param-value>
+		</init-param>
+		<load-on-startup>1</load-on-startup>
+	</servlet>
+	<servlet-mapping>
+		<servlet-name>springDispatcherServlet</servlet-name>
+		<url-pattern>/</url-pattern>
+	</servlet-mapping>
+
+	<filter>
+		<filter-name>characterEncodingFilter</filter-name>
+		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
+		<init-param>
+			<param-name>encoding</param-name>
+			<param-value>UTF-8</param-value>
+		</init-param>
+		<init-param>
+			<param-name>forceEncoding</param-name>
+			<param-value>true</param-value>
+		</init-param>
+	</filter>
+	<filter-mapping>
+		<filter-name>characterEncodingFilter</filter-name>
+		<url-pattern>/*</url-pattern>
+	</filter-mapping>
+
+	<error-page>
+		<error-code>404</error-code>
+		<location>/view/system_view/404.jsp</location>
+	</error-page>
+	<error-page>
+		<error-code>500</error-code>
+		<location>/view/system_view/500.jsp</location>
+	</error-page>
+	
+	<!-- 数据库监控 -->
+	<servlet>
+        <servlet-name>DruidStatView</servlet-name>
+        <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>DruidStatView</servlet-name>
+        <url-pattern>/admin/druid/*</url-pattern>
+    </servlet-mapping>
+    
+    <!-- web stat -->
+    <filter>
+		<filter-name>DruidWebStatFilter</filter-name>
+		<filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
+	</filter>
+	<filter-mapping>
+	    <filter-name>DruidWebStatFilter</filter-name>
+	    <url-pattern>/*</url-pattern>
+	</filter-mapping>
+</web-app>

+ 133 - 0
iamberry-app-international/.svn/pristine/b3/b3d4e4b9b583161a83cb5a6676083f8e8d948ffb.svn-base

@@ -0,0 +1,133 @@
+
+package com.iamberry.app.international.util.kafka;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.security.auth.login.Configuration;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+
+import org.apache.kafka.clients.CommonClientConfigs;
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.apache.kafka.clients.consumer.ConsumerRecords;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+import com.alibaba.fastjson.JSON;
+import com.iamberry.app.face.MachineService;
+import com.iamberry.app.face.MilkService;
+
+public class KafkaConsumer implements ServletContextListener {
+
+	private static final Logger logger = LoggerFactory.getLogger(KafkaConsumer.class);
+	
+	public void contextInitialized(ServletContextEvent sce) {
+		WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
+		MachineService machineService = webApplicationContext.getBean(MachineService.class);
+		MilkService milkService = webApplicationContext.getBean(MilkService.class);
+		
+		String appKey = "5kkyurvvtt58bbuxueee";//填APP KEY
+		String secretKey = "rhj6na6u3y6uhy6qrbb3944mg5uqqpbb";//APP SECRET
+		org.apache.kafka.clients.consumer.KafkaConsumer<String, String> consumer = null;
+		Configuration configuration = Configuration.getConfiguration();
+		Configuration.setConfiguration(null);
+		try {
+			java.security.Security.setProperty("login.configuration.provider", "com.iamberry.app.international.util.kafka.SaslConfiguration");
+
+			Properties props = new Properties();
+			//根据不同区域填写,不同区域URL参考文档  https://docs.tuya.com/cn/cloudapi/cloud_access/#kafka
+			props.put("bootstrap.servers", "kafka.cloud.tuyaus.com:8092");
+			String groupId = "aby-real-group";
+			props.put("group.id", groupId);
+
+			InetAddress netAddress = InetAddress.getLocalHost();
+			String clientId = "cloud_" + appKey + "_" + netAddress.getHostAddress();
+			props.put("client.id", clientId);
+			props.put("enable.auto.commit", "true");
+			props.put("auto.commit.interval.ms", "10000");
+			props.put("session.timeout.ms", "30000");
+			props.put("max.poll.records", 1000);
+			props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
+			//可以自定义JSON格式的序列化
+			props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
+
+			props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SASL_PLAINTEXT");
+			props.put("sasl.mechanism", "PLAIN");
+
+			consumer = new org.apache.kafka.clients.consumer.KafkaConsumer<String, String>(props);
+			consumer.subscribe(Arrays.asList("device-cloud-out-" + appKey));
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+		} finally {
+			Configuration.setConfiguration(configuration);
+		}
+		final org.apache.kafka.clients.consumer.KafkaConsumer<String, String> finalKafkaConsumer = consumer;
+		if (consumer != null) {
+			new Thread(){
+				@Override
+				public void run(){
+					while (true) {
+						ConsumerRecords<String, String> records = finalKafkaConsumer.poll(1000);
+						//ConsumerRecord<String, String> record = new ConsumerRecord<String, String>("4", 1, 1, "data", "JD/i7iF1hWmH08X54IGwjQkOy2gSEPTryEPUGbopFa3tC0lAyPx3dHN8enyKEY1zBdZt+bu5RYHnK00TvWD07S+Ryi3vHIGtWhTh7JLSVMAI+PNQeZZ87ZCh+vQaLQletGi/2n9B/pp+GLDDWFEhnl+xaLeVgcR9oGhUxBTwRmQsM1gUrTyEjFxfEhSWDM7Y+oj8NKWtJKpSS2/dv6wxNv+OIs6LCVBq+R1cLb+c0WI=");
+						boolean flog = false;
+						String milkPowder = "";
+						Long milkTime = 0l;
+						try {
+							for (ConsumerRecord<String, String> record : records) {
+								/*logger.info("Received message: (" + record.key() + ", " + record.value() + ") at offset "
+										+ record.offset() + ",decrypt data="
+										+ AESBase64Util.decrypt(JSONObject.fromObject(record.value()).getString("data"), secretKey.substring(8, 24)));
+							//	+ AESBase64Util.decrypt(record.value(), secretKey.substring(8, 24)));
+*/								String data = AESBase64Util.decrypt(JSONObject.fromObject(record.value()).getString("data"), secretKey.substring(8, 24));//解析后的真正数据
+								JSONObject jasonObject = JSONObject.fromObject(data);
+								if(jasonObject.has("dps")){
+									JSONArray dps = jasonObject.getJSONArray("dps");
+							        for(int i = 0; i < dps.size(); i++){
+							        	Map maps = (Map) JSON.parse(dps.getString(i));
+								        for (Object obj : maps.keySet()){
+								            if(obj.equals("DEVECE_CONTROL_MILK")){
+								            	milkPowder = maps.get(obj).toString();
+								            	flog = true;//如果数据中包含当前字段,表示当前推送的数据为奶粉记录
+								            }
+								            if(obj.equals("t")){
+								            	milkTime = (Long)maps.get((obj));
+								            }
+								        }
+							        }
+							        if(flog){
+							        	// 根据机器ID 获取对应的用户id
+							        	String devId = jasonObject.getString("devId");
+										Long userId = machineService.selectUserIDByDevId(devId);
+										milkService.addRecordData(devId, milkPowder, milkTime, userId);
+										flog = false;
+							        }
+								}
+						     }
+						} catch (Exception e) {
+							logger.error("", e);
+						}
+					}
+				}
+			}.start();;
+		}
+	}
+	@Override
+	public void contextDestroyed(ServletContextEvent sce) {
+		// TODO Auto-generated method stub
+		
+	}
+}

+ 1 - 0
iamberry-app-international/.svn/pristine/b6/b6fd1c80f7f0ae3d8b009c634195870d0a4aaf12.svn-base

@@ -0,0 +1 @@
+username-ZH=何秀剛

+ 50 - 0
iamberry-app-international/.svn/pristine/bc/bc7801b95dffb1c2efb3a126c57cffc2b1ac0693.svn-base

@@ -0,0 +1,50 @@
+package com.iamberry.app.international.controller;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Properties;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.util.DefaultPropertiesPersister;
+import org.springframework.util.PropertiesPersister;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.i18n.CookieLocaleResolver;
+import org.springframework.web.servlet.support.RequestContext;
+
+import com.iamberry.app.international.model.FormatModel;
+import com.iamberry.app.international.util.languageUtil;
+import com.iamberry.zk.ZookeeperFactory;
+
+@Controller
+@RequestMapping(value = "/global")
+public class GlobalController{
+    
+    @RequestMapping(value="/test", method = {RequestMethod.GET})
+    public String test(HttpServletRequest request, HttpServletResponse response, Model model, @RequestParam(value="langType", defaultValue="zh") String langType){
+      
+        languageUtil languageutil = new languageUtil();
+    	String username = languageutil.get("username", langType);
+    	model.addAttribute("username", username);
+        return "globaltest";
+    }
+	
+   
+}

+ 68 - 0
iamberry-app-international/.svn/pristine/be/beef0a37b6d6122ac284b52781417f76121f68ab.svn-base

@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	   xmlns:aop="http://www.springframework.org/schema/aop"
+	   xmlns:context="http://www.springframework.org/schema/context"
+	   xmlns:tx="http://www.springframework.org/schema/tx"
+	   xmlns:p="http://www.springframework.org/schema/p"
+	   xsi:schemaLocation="http://www.springframework.org/schema/beans
+					http://www.springframework.org/schema/beans/spring-beans.xsd
+					http://www.springframework.org/schema/aop
+					http://www.springframework.org/schema/aop/spring-aop.xsd
+					http://www.springframework.org/schema/context
+					http://www.springframework.org/schema/context/spring-context.xsd
+					http://www.springframework.org/schema/tx
+					http://www.springframework.org/schema/tx/spring-tx.xsd">
+
+	<!-- 获取jdbc配置文件 -->
+	<context:property-placeholder location="classpath:jdbc.properties"/>
+
+    <!--app 前台配置库数据源-->
+    <bean id="ratfwDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
+        <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
+        <property name="driverClassName" value="${jdbc.driver}" />
+        <!-- 基本属性 url、user、password -->
+        <property name="url" value="${jdbc.url}" />
+        <property name="username" value="${jdbc.username}" />
+        <property name="password" value="${jdbc.password}" />
+        <!-- 配置初始化大小、最小、最大 -->
+        <property name="initialSize" value="${jdbc.pool.init}" />
+        <property name="minIdle" value="${jdbc.pool.minIdle}" />
+        <property name="maxActive" value="${jdbc.pool.maxActive}" />
+        <!-- 配置获取连接等待超时的时间 -->
+        <property name="maxWait" value="60000" />
+        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
+        <property name="timeBetweenEvictionRunsMillis" value="60000" />
+        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
+        <property name="minEvictableIdleTimeMillis" value="300000" />
+        <property name="validationQuery" value="${jdbc.testSql}" />
+        <property name="testWhileIdle" value="true" />
+        <property name="testOnBorrow" value="false" />
+        <property name="testOnReturn" value="false" />
+        <!-- 配置监控统计拦截的filters -->
+        <property name="filters" value="stat,wall" />
+    </bean>
+	
+	<!-- 自动扫描SQL隐射文件 -->
+	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
+		<!-- basePackage:指定SQL映射文件、接口的包,自动加载SQL映射文件和接口 -->
+		<property name="basePackage" value="com.iamberry.app.mapper"></property>
+		<!-- 引用SQLSessionFactoryBean -->
+		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
+	</bean>
+	
+	<!-- 配置SqlSessionFactoryBean -->
+	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
+		<!-- 配置数据源 -->
+		<property name="dataSource" ref="ratfwDataSource" />
+		<property name="configLocation" value="classpath:iamberry-app-service-mybatis.xml" />
+		<property name="mapperLocations" value="classpath:com/iamberry/app/mapper/*.xml" />
+	</bean>
+	
+	<!-- 基于mysql的事物管理,如果是大型项目不建议使用xml配置全部,而是应该使用@Transaction指定方法级别的事务控制 -->
+	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
+		<property name="dataSource" ref="ratfwDataSource" />
+	</bean>
+	<!-- 开启注解事务 -->
+	<tx:annotation-driven transaction-manager="transactionManager"/>
+</beans>

+ 285 - 0
iamberry-app-international/.svn/pristine/c1/c130ba42dbe8c8288f6cde791ad20602c19ff34e.svn-base

@@ -0,0 +1,285 @@
+package com.iamberry.app.international.controller;
+
+import static com.iamberry.app.config.Response.BARCODE_NOT_FOUND;
+import static com.iamberry.app.config.Response.INVALID_TOKEN;
+import static com.iamberry.app.config.Response.SUCCESS;
+import static com.iamberry.app.config.Response.INSERT_DUPLICATE;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.dao.DataAccessException;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.iamberry.app.config.APIStatus;
+import com.iamberry.app.config.Response;
+import com.iamberry.app.config.ResponseHeader;
+import com.iamberry.app.core.dto.RecordDTO;
+import com.iamberry.app.core.entity.MilkImages;
+import com.iamberry.app.core.entity.MilkMakingRecord;
+import com.iamberry.app.core.entity.MilkPowderInfo;
+import com.iamberry.app.core.entity.User;
+import com.iamberry.wechat.file.FileUtils;
+import com.iamberry.wechat.file.UploadResultBean;
+
+/**
+ * UserController
+ *
+ * @author Moon Cheng
+ * @date 2016年1月18日 上午11:53:04
+ */
+@Controller
+@RequestMapping("/secure/milk")
+public class MilkController extends BaseController {
+
+	@InitBinder("makingRecord")
+	public void initBinderRecord(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("makingRecord.");
+	}
+
+	@InitBinder("milkPowderInfo")
+	public void initBinderMilkPowder(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("milkPowderInfo.");
+	}
+
+	/**
+	 * 添加冲奶信息 
+	 * @author Moon Cheng
+	 * @param token 唯一标识符 
+	 * @param makingRecord 冲奶信息实体类
+	 * @return 1000:请求成功;2100:无效token;
+	 */
+	@RequestMapping(value = "/set_milk_making_record", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMilkMakingRecord(@RequestParam("token") String token, MilkMakingRecord makingRecord) {
+		makingRecord = milkService.setMilkMakingRecord(makingRecord, token);
+		if (makingRecord == null) {
+			return INVALID_TOKEN;
+		}
+		return SUCCESS.setData(makingRecord, 1);
+	}
+
+	/**
+	 *  通过日期,日期类型,统计某时间的,冲奶总量
+	 * @param token   唯一标识符
+	 * @param dateStatus 标识符 : day week year 
+	 * @param chosenDate 结束时间
+	 * @param machineMac 机器mac地址
+	 * @return
+	 */
+	@RequestMapping(value = "/search_user_records_by_time", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchUserRecordsByTime(@RequestParam(value = "token") String token,
+			@RequestParam("date_status") String dateStatus, @RequestParam("chosen_date") String chosenDate,
+			@RequestParam("devid") String machineMac) {
+
+		User userInfo = userService.validateUserToken(token);
+		if (userInfo == null) {
+			return INVALID_TOKEN;
+		}
+		Map<String, List<RecordDTO>> makingRecords = milkService.searchUserRecordsByTime(userInfo.getId(), dateStatus,
+				chosenDate, machineMac);
+		return SUCCESS.setData(makingRecords, makingRecords.size());
+	}
+
+	/**
+	 * 通过冲奶记录id获取冲奶记录详情
+	 * @author Moon Cheng
+	 * @param recordId 冲奶记录,id
+	 * @return 
+	 *//*
+	@RequestMapping(value = "/search_user_record_by_id", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchUserRecordById(@RequestParam(value = "record_id") Long recordId) {
+		MilkMakingRecord makingRecord = milkService.searchUserRecordById(recordId);
+		return SUCCESS.setData(makingRecord, 1);
+	}*/
+
+	/**
+	 * 根据用户id获取用户,冲奶总容量
+	 * @author Moon Cheng
+	 * @param userId  用户id 
+	 * @return
+	 */
+	@RequestMapping(value = "/get_user_total_milk_volume", method = RequestMethod.POST)
+	@ResponseBody
+	private Response getTotalMilkVolumeMadeByUser(@RequestParam(value = "user_id") Long userId) {
+		return SUCCESS.setData(milkService.getTotalMilkVolumeMadeByUser(userId), 0);
+	}
+
+	/**
+	 * 手动添加,奶粉信息!
+	 * @author Moon Cheng
+	 * @param token  唯一标识符
+	 * @param milkPowderInfo  奶粉信息
+	 * @return
+	 */
+	@RequestMapping(value = "/set_milk_powder_info", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMilkPowderInfo(@RequestParam(value = "token") String token, MilkPowderInfo milkPowderInfo) {
+		// 勺量,每勺多少克     量勺 克数范围2-18
+		String amountStr = request.getParameter("a_mount");
+		if (amountStr == null) {
+			// 兼容低版本
+			milkPowderInfo = milkService.setMilkPowderInfo(milkPowderInfo, token);
+			if (milkPowderInfo == null) {
+				return INVALID_TOKEN;
+			}
+			return SUCCESS.setData(milkPowderInfo, 1);
+		}
+		
+		float amount = Float.parseFloat(amountStr);
+		// 勺数,多少少		量勺勺数范围 1-10
+		int spoonNum = Integer.parseInt(request.getParameter("spoon_num"));
+		// ML,1勺多少奶量  水量范围30-300
+		float spoonML = Float.parseFloat(request.getParameter("spoon_ml"));
+		
+		// 毫升/勺	
+		float s = spoonML / spoonNum;
+		
+		// 混合比 计算公式:勺量   * 勺数  / 毫升 / 100 = 混合比
+		float ratio = amount * spoonNum / spoonML * 100;
+		milkPowderInfo.setPowder_ratio(ratio);
+		milkPowderInfo.setWeight_per_spoon(amount);
+		milkPowderInfo.setMilk_volume_per_spoon(s);
+		
+		// 密度
+		/*
+		 *     A<13.2                6
+			   13.21<A<15.3          7
+			   15.31<A<17.4          8 
+			   17.41<A<19.5          9
+			   19.51<A<22.0         10 
+			   22.1 <A              10
+		 */
+		int m = 6;
+		if (ratio < 13.2) {
+			m = 6;
+		} else if (ratio > 13.21 && ratio < 15.3) {
+			m = 7;
+		} else if (ratio > 15.31 && ratio < 17.4) {
+			m = 8;
+		} else if (ratio > 17.41 && ratio < 19.5) {
+			m = 9;
+		} else {
+			m = 10;
+		}
+		milkPowderInfo.setDensity((float)m);
+		
+		// 保存操作
+		try {
+			milkPowderInfo = milkService.setMilkPowderInfo(milkPowderInfo, token);
+		} catch (DataAccessException  e) {
+			return INSERT_DUPLICATE;
+		}
+		
+		if (milkPowderInfo == null) {
+			return INVALID_TOKEN;
+		}
+		
+		// 保存图片
+		String imageFront = request.getParameter("imageFront");
+		String imageBar = request.getParameter("imageBar");
+		String imageFeed = request.getParameter("imageFeed");
+		MilkImages images = new MilkImages();
+		images.setImage_Front(imageFront);
+		images.setImage_Bar(imageBar);
+		images.setImage_Feed(imageFeed);
+		images.setImage_Milk_ID(milkPowderInfo.getId());
+		milkService.setMilkImages(images);
+		return SUCCESS.setData(milkPowderInfo, 1);
+	}
+
+	/**
+	 * 通过,条形码获取奶粉信息
+	 * @author Moon Cheng
+	 * @param barcode 条形码code
+	 * @return
+	 */
+	@RequestMapping(value = "/search_milk_powder_info_by_barcode", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkPowderInfoByBarCode(@RequestParam(value = "barcode") String barcode) {
+		MilkPowderInfo milkPowderInfo = milkService.searchMilkPowderInfoByBarCode(barcode);
+		if (milkPowderInfo == null) {
+			return BARCODE_NOT_FOUND;
+		}
+		return SUCCESS.setData(milkPowderInfo, 1);
+	}
+
+	/**
+	 * 铜鼓品牌名获取奶粉信息
+	 * @author Moon Cheng, Yin
+	 * @param brand 品牌名
+	 * @return
+	 */
+	@RequestMapping(value = "/search_milk_powder_infos_by_brand", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkPowderInfosByBrand(@RequestParam(value = "brand") String brand) {
+		Map<String, List<String>> milkPowderInfos = milkService.searchMilkPowderInfosByBrand(brand);
+		return SUCCESS.setData(milkPowderInfos, milkPowderInfos.size());
+	}
+
+	/**
+	 * 获取奶粉品牌
+	 * @author Yin 
+	 * @return  过滤掉品牌名中有.的 例如 a.b 这里或只查询到a
+	 */
+	@RequestMapping(value = "/search_milk_powder_brand", method = RequestMethod.GET)
+	@ResponseBody
+	private Response searchMilkPowderBrand() {
+		List<String> milkPowderInfos = milkService.searchMilkPowderBrand();
+		return SUCCESS.setData(milkPowderInfos, milkPowderInfos.size());
+	}
+
+	/**
+	 * 通过奶粉品牌、段数、系列、查询奶粉信息
+	 * @param brand 品牌
+	 * @param series 系列
+	 * @param level 段数
+	 * @return
+	 */
+/*	@RequestMapping(value = "/search_milk_info_by_brand_series_level", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkInfoByBrandSeriesLevel(@RequestParam("brand") String brand,
+			@RequestParam("series") String series, @RequestParam("level") String level) {
+		return SUCCESS.setData(milkService.searchMilkInfoByBrandSeriesLevel(brand, series, level), 1);
+	}*/
+
+	/**
+	 * 上传奶粉信息的域名,及保存的路径,需要tomcat单独域名映射/或者是nginx
+	 */
+	private static String SAVE_MILK_IMAGE_DOMAIN = "http://milk.iamberry.com/";
+	private static String SAVE_MILK_IMAGE_PATH = "/common/";
+	/**
+	 * @param model
+	 * @param request
+	 * @return
+	 */
+	@ResponseBody
+	@RequestMapping(value = "/upload_image", method = RequestMethod.POST)
+	public Response uploadFileImage(@RequestParam("file")MultipartFile[] files, HttpServletRequest request) {
+		Map<String, String> filemap= new HashMap<String, String>();
+		
+		for (int i = 0; i < files.length; i++) {
+			MultipartFile file = files[i];
+			// 保存文件
+			UploadResultBean bean = FileUtils.saveFile(request.getServletContext(), file, SAVE_MILK_IMAGE_PATH, false);
+			if (bean == null) {
+				// 文件有误
+				return new Response(new ResponseHeader(4204, "文件有误!", -1));
+			}
+			filemap.put("file"+i,SAVE_MILK_IMAGE_DOMAIN + bean.getSaveFileName());
+		}
+		return SUCCESS.setData(filemap, filemap.size());
+	}
+}

+ 3 - 0
iamberry-app-international/.svn/pristine/c2/c28ac1ab4014d61a4153c5aefc5da6e4d4737aa2.svn-base

@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+encoding//src/main/resources=UTF-8
+encoding/<project>=UTF-8

+ 26 - 0
iamberry-app-international/.svn/pristine/cb/cb388b5487acff1f27682d272159552dbbdf23b1.svn-base

@@ -0,0 +1,26 @@
+package com.iamberry.app.international.controller;
+
+import java.io.IOException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+
+@Controller
+@RequestMapping("/test-download/")
+public class ApkDownload extends BaseController {
+
+	@RequestMapping(value = "test_iamberry_release.apk", method = RequestMethod.GET)
+	@ResponseBody
+	private void download(HttpServletResponse response, HttpServletRequest request) {
+		try {
+			response.sendRedirect("/download/iamberry_release_" + userService.getApkVersion() + ".apk");
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+}

+ 116 - 0
iamberry-app-international/.svn/pristine/cd/cd2443d9c124ca0324b51c71ed005f1ea1835a59.svn-base

@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
+	xmlns:mvc="http://www.springframework.org/schema/mvc"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
+		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
+	
+	<!-- 该异常是SpringMVC在检查上传的文件信息时抛出来的,而且此时还没有进入到Controller方法中   遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/views/msg/ploadToSize.jsp页面 -->  
+    <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
+        <property name="exceptionMappings">  
+            <props>  
+                <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">/msg/ploadToSize</prop>  
+            </props>  
+        </property>  
+    </bean>
+	<!-- 配置自定扫描的包,仅handler和Advice -->
+	<context:component-scan base-package="com.iamberry.app.international" use-default-filters="false">
+		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
+		<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
+	</context:component-scan>
+	
+	<!-- 配置freeMarker视图解析器 -->
+    <bean id="viewResolverFtl" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
+        <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>
+        <property name="contentType" value="text/html; charset=UTF-8"/>
+        <property name="exposeRequestAttributes" value="true" />
+        <property name="exposeSessionAttributes" value="true" />
+        <property name="exposeSpringMacroHelpers" value="true" />
+        <property name="requestContextAttribute" value="request"/>
+        <property name="cache" value="true" />
+        <property name="suffix" value=".ftl" />
+        <property name="order" value="0"/>
+    </bean>
+
+    <!-- 配置FREEMARKER的视图解析器 -->
+    <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
+        <property name="templateLoaderPath" value="/WEB-INF/views/"/>
+        <property name="freemarkerVariables">
+            <map>
+                <entry key="xml_escape" value-ref="fmXmlEscape" />
+            </map>
+        </property>
+        <property name="defaultEncoding" value="UTF-8"/>
+        <property name="freemarkerSettings">
+            <props>
+            	<!-- 指定更新模版文件的间隔时间,相当于多长时间检测一下是否有必要重新加载模版文件,0 表示每次都重新加载,否则为多少毫秒钟检测一下模版是否更改 -->
+                <prop key="template_update_delay">3600</prop>
+                <prop key="locale">zh_CN</prop>
+                <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
+                <prop key="date_format">yyyy-MM-dd</prop>
+                <prop key="number_format">#.##</prop>
+            </props>
+        </property>
+    </bean>
+    <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>
+    
+	<!-- 配置JSP视图解析器: 如何把 handler 方法返回值解析为实际的物理视图 -->
+	<bean id="viewResolverJsp" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
+        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
+        <property name="contentType" value="text/html; charset=UTF-8"/>
+		<property name="prefix" value="/WEB-INF/views/"></property>
+		<property name="suffix" value=".jsp"></property>
+        <property name="order" value="1"/> 
+	</bean>
+	
+	<!-- 解决静态资源,提供两种方法 -->
+	<mvc:default-servlet-handler/>
+	<mvc:resources location="/common/css/" mapping="/common/css/**" />
+	<mvc:resources location="/common/images/" mapping="/common/images/**" />
+	<mvc:resources location="/common/js/" mapping="/common/js/**" />
+	<mvc:resources location="/common/other/" mapping="/common/other/**" />
+
+	<!-- 解决配置mvc:default-servlet-handler后,前台handler方法失效问 -->
+	<mvc:annotation-driven></mvc:annotation-driven>
+	<!-- 配置MultipartResolver -->
+	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
+		<!-- 默认的编码 -->
+		<property name="defaultEncoding" value="UTF-8"></property>
+		<!-- 最大上传大小 -->
+		<property name="maxUploadSize" value="1024000000"></property>
+	</bean>
+	<!--避免IE执行AJAX时,返回JSON出现下载文件 -->  
+    <bean id="mappingJacksonHttpMessageConverter"  
+        class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">  
+        <property name="supportedMediaTypes">  
+            <list>  
+               <value>text/html; charset=UTF-8</value>  
+               <value>application/json;charset=UTF-8</value>  
+            </list>  
+        </property>  
+    </bean>
+    <bean  
+        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
+        <property name="messageConverters">  
+            <list>  
+                <ref bean="mappingJacksonHttpMessageConverter" />
+            </list>  
+        </property>  
+    </bean>
+    
+    <!-- 定义国际化消息-->   
+   <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">   
+     
+	     <!--   其中basename用来指定properties文件的通用名
+	              如实例中的messages_en.properties,messages_ja.properties通用名都是messages
+	      -->
+	     <property name="basename" value="messages"/>
+	     <property name="useCodeAsDefaultMessage" value="true" />
+	     
+	</bean>   
+    
+   <!-- 获取本地 -->  
+   <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/> 
+    
+</beans>

+ 301 - 0
iamberry-app-international/.svn/pristine/d3/d3959ceba203d91592413915a90b7753a3bac87e.svn-base

@@ -0,0 +1,301 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schemadesigner version="6.5">
+<source>
+<database charset="utf8" collation="utf8_bin">lottery_db</database>
+</source>
+<canvas zoom="100">
+<tables>
+<table name="lottery" view="colnames">
+<left>60</left>
+<top>439</top>
+<width>179</width>
+<height>197</height>
+<sql_create_table>CREATE TABLE `lottery` (
+  `id` bigint(20) NOT NULL COMMENT 'product_turn',
+  `lottery_detail` blob COMMENT '[transection_id: 1, display_name: Ali, avatar: http://tronsis.com/images/abc.jpg, location: shenzhen guangdong, ip_address: 10.2.3.4, units: 5, time_stamp: 26, 2, 2016 3:45:45 GMT, lottery_numbers {1,2,3,4,5}   ',
+  `winner_lottery_number` varchar(20) COLLATE utf8_bin DEFAULT NULL,
+  `winner` bigint(20) DEFAULT NULL,
+  `winner_info` text COLLATE utf8_bin COMMENT 'wining user',
+  `status_` varchar(20) COLLATE utf8_bin DEFAULT NULL,
+  `timestamp_` timestamp NULL DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  CONSTRAINT `FK_lottery` FOREIGN KEY (`id`) REFERENCES `product_turn` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="product" view="colnames">
+<left>625</left>
+<top>678</top>
+<width>137</width>
+<height>214</height>
+<sql_create_table>CREATE TABLE `product` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `name` varchar(100) COLLATE utf8_bin DEFAULT NULL,
+  `icon` text COLLATE utf8_bin,
+  `introduction` text COLLATE utf8_bin,
+  `images` text COLLATE utf8_bin,
+  `category` bigint(20) DEFAULT NULL,
+  `status_` varchar(20) COLLATE utf8_bin DEFAULT 'active',
+  `timestamp_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="product_category" view="colnames">
+<left>358</left>
+<top>423</top>
+<width>143</width>
+<height>146</height>
+<sql_create_table>CREATE TABLE `product_category` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `name` varchar(100) COLLATE utf8_bin DEFAULT NULL,
+  `icon` blob,
+  `status_` varchar(20) COLLATE utf8_bin DEFAULT 'active',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="product_turn" view="colnames">
+<left>353</left>
+<top>581</top>
+<width>182</width>
+<height>333</height>
+<sql_create_table>CREATE TABLE `product_turn` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `product_id` bigint(20) DEFAULT NULL,
+  `product_name` varchar(100) COLLATE utf8_bin DEFAULT NULL,
+  `product_icon` text COLLATE utf8_bin,
+  `product_introduction` text COLLATE utf8_bin,
+  `product_images` text COLLATE utf8_bin,
+  `product_category` bigint(20) DEFAULT NULL,
+  `turn_count` int(11) DEFAULT '1',
+  `total_units` int(11) DEFAULT '0',
+  `paid_units` int(11) DEFAULT '0',
+  `turn_expiry` date DEFAULT NULL,
+  `status_` varchar(20) COLLATE utf8_bin DEFAULT 'active' COMMENT 'active/computing/closed/expired',
+  `count_down_delay` int(11) DEFAULT NULL COMMENT 'Seconds',
+  `result_time` datetime DEFAULT NULL,
+  `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `recommended_order` int(11) DEFAULT NULL,
+  `modified_by` varchar(50) COLLATE utf8_bin DEFAULT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="review_post" view="colnames">
+<left>677</left>
+<top>402</top>
+<width>117</width>
+<height>214</height>
+<sql_create_table>CREATE TABLE `review_post` (
+  `id` bigint(20) NOT NULL COMMENT 'product_turn',
+  `product_info` text COLLATE utf8_bin NOT NULL COMMENT 'json',
+  `images` text COLLATE utf8_bin NOT NULL COMMENT 'json{images list}',
+  `description` varchar(255) COLLATE utf8_bin NOT NULL,
+  `user` bigint(20) NOT NULL,
+  `liked_by` text COLLATE utf8_bin COMMENT 'json{user_ids}',
+  `status_` varchar(20) COLLATE utf8_bin DEFAULT 'active',
+  `timestamp_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`),
+  KEY `FK_review_post_user` (`user`),
+  CONSTRAINT `FK_review_post` FOREIGN KEY (`id`) REFERENCES `product_turn` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_review_post_user` FOREIGN KEY (`user`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="sys_activity_and_news" view="colnames">
+<left>27</left>
+<top>26</top>
+<width>191</width>
+<height>180</height>
+<sql_create_table>CREATE TABLE `sys_activity_and_news` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `preview_image` text COLLATE utf8_bin,
+  `preview_summery` varchar(200) COLLATE utf8_bin DEFAULT NULL,
+  `detail_info` text COLLATE utf8_bin,
+  `type_` varchar(20) COLLATE utf8_bin DEFAULT 'news' COMMENT 'news/activity',
+  `timestamp_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="sys_coin_transection" view="colnames">
+<left>35</left>
+<top>219</top>
+<width>166</width>
+<height>146</height>
+<sql_create_table>CREATE TABLE `sys_coin_transection` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `coin_holder` bigint(20) DEFAULT NULL,
+  `coin` int(11) DEFAULT NULL,
+  `timestamp_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="sys_faq" view="colnames">
+<left>248</left>
+<top>24</top>
+<width>113</width>
+<height>146</height>
+<sql_create_table>CREATE TABLE `sys_faq` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `title` text COLLATE utf8_bin,
+  `detail` text COLLATE utf8_bin,
+  `timestamp_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="sys_feedback" view="colnames">
+<left>248</left>
+<top>189</top>
+<width>140</width>
+<height>163</height>
+<sql_create_table>CREATE TABLE `sys_feedback` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `feedback_text` varchar(200) COLLATE utf8_bin DEFAULT NULL,
+  `feedback_image` text COLLATE utf8_bin,
+  `feedback_by` varchar(100) COLLATE utf8_bin DEFAULT NULL,
+  `timestamp_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="sys_message" view="colnames">
+<left>420</left>
+<top>13</top>
+<width>129</width>
+<height>180</height>
+<sql_create_table>CREATE TABLE `sys_message` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `title` varchar(100) COLLATE utf8_bin DEFAULT NULL,
+  `detail` text COLLATE utf8_bin,
+  `icon` text COLLATE utf8_bin COMMENT 'BASE64',
+  `message_type` varchar(20) COLLATE utf8_bin DEFAULT 'system' COMMENT 'system/delivery-message',
+  `timestamp_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="sys_payment_transection" view="colnames">
+<left>416</left>
+<top>203</top>
+<width>189</width>
+<height>197</height>
+<sql_create_table>CREATE TABLE `sys_payment_transection` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `paid_by` bigint(20) DEFAULT NULL,
+  `thirdparty_name` varchar(50) COLLATE utf8_bin DEFAULT 'n/a' COMMENT 'wechat/alipay',
+  `thirdparty_transection_id` varchar(100) COLLATE utf8_bin DEFAULT NULL,
+  `amount` int(11) DEFAULT NULL COMMENT 'RMB , real money',
+  `coins` int(11) DEFAULT NULL,
+  `timestamp_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="user" view="colnames">
+<left>1067</left>
+<top>254</top>
+<width>133</width>
+<height>311</height>
+<sql_create_table>CREATE TABLE `user` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `username` varchar(20) COLLATE utf8_bin NOT NULL,
+  `password` varchar(50) COLLATE utf8_bin NOT NULL,
+  `real_name` varchar(50) COLLATE utf8_bin DEFAULT NULL,
+  `display_picture` text COLLATE utf8_bin,
+  `dob` date DEFAULT NULL,
+  `gender` int(11) DEFAULT '0',
+  `points` int(11) DEFAULT NULL,
+  `coins` int(11) DEFAULT NULL COMMENT 'real money',
+  `qq_address` varchar(20) COLLATE utf8_bin DEFAULT NULL,
+  `phone_address` varchar(20) COLLATE utf8_bin DEFAULT NULL,
+  `postal_address` text COLLATE utf8_bin COMMENT 'json:{name, phone, province, city, district, address, isDefault}',
+  `status_` varchar(20) COLLATE utf8_bin DEFAULT 'active',
+  `timestamp_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `username_index` (`username`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="user_cart" view="colnames">
+<left>1057</left>
+<top>593</top>
+<width>119</width>
+<height>163</height>
+<sql_create_table>CREATE TABLE `user_cart` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `user` bigint(20) DEFAULT NULL,
+  `product_turn` bigint(20) DEFAULT NULL,
+  `units` int(11) DEFAULT NULL,
+  `timestamp_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`),
+  KEY `FK_cart` (`product_turn`),
+  CONSTRAINT `FK_cart` FOREIGN KEY (`product_turn`) REFERENCES `product_turn` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="user_share_log" view="colnames">
+<left>1224</left>
+<top>367</top>
+<width>137</width>
+<height>129</height>
+<sql_create_table>CREATE TABLE `user_share_log` (
+  `user_id` bigint(20) NOT NULL,
+  `last_share_date` date DEFAULT NULL,
+  `timestamp_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="user_token" view="colnames">
+<left>1228</left>
+<top>208</top>
+<width>113</width>
+<height>146</height>
+<sql_create_table>CREATE TABLE `user_token` (
+  `token` varchar(100) COLLATE utf8_bin NOT NULL,
+  `user` bigint(20) DEFAULT NULL,
+  `user_agent` varchar(100) COLLATE utf8_bin DEFAULT 'ios-UIODKJIERUI' COMMENT 'UDID/IMEI',
+  `timestamp_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`token`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="user_wish_list" view="colnames">
+<left>1232</left>
+<top>520</top>
+<width>140</width>
+<height>180</height>
+<sql_create_table>CREATE TABLE `user_wish_list` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `title` varchar(100) COLLATE utf8_bin DEFAULT NULL,
+  `description` varchar(200) COLLATE utf8_bin DEFAULT NULL,
+  `status_` varchar(20) COLLATE utf8_bin DEFAULT 'active',
+  `created_by` bigint(20) DEFAULT NULL,
+  `timestamp_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="winner_order" view="colnames">
+<left>60</left>
+<top>648</top>
+<width>190</width>
+<height>248</height>
+<sql_create_table>CREATE TABLE `winner_order` (
+  `id` bigint(20) NOT NULL COMMENT 'product_turn',
+  `sn` varchar(20) COLLATE utf8_bin NOT NULL,
+  `address` text COLLATE utf8_bin COMMENT 'json{Realname, address, district, city, province}',
+  `units_by_winner` int(11) DEFAULT NULL,
+  `status_` varchar(20) COLLATE utf8_bin DEFAULT 'win' COMMENT 'win/confirmed/shipped/received',
+  `user` bigint(20) DEFAULT NULL COMMENT 'winning user id',
+  `lottery` bigint(20) NOT NULL,
+  `delivery_company_name` varchar(200) COLLATE utf8_bin DEFAULT NULL,
+  `delivery_company_sn` varchar(100) COLLATE utf8_bin DEFAULT NULL,
+  `timestamp_` timestamp NULL DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  CONSTRAINT `FK_winner_order` FOREIGN KEY (`id`) REFERENCES `product_turn` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+<table name="sys_search_keyword_frequency" view="colnames">
+<left>575</left>
+<top>18</top>
+<width>225</width>
+<height>129</height>
+<sql_create_table>CREATE TABLE `sys_search_keyword_frequency` (
+  `keyword` varchar(200) COLLATE utf8_bin NOT NULL,
+  `frequency` int(11) DEFAULT NULL,
+  `last_time_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`keyword`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin</sql_create_table>
+</table>
+</tables>
+</canvas>
+</schemadesigner>

+ 2 - 0
iamberry-app-international/.svn/pristine/d4/d484a833555f187f2c607a59d136f423ef3a0af4.svn-base

@@ -0,0 +1,2 @@
+disabled=06target
+eclipse.preferences.version=1

+ 26 - 0
iamberry-app-international/.svn/pristine/e1/e1bb9cf6c5bfa96aecaf5b404755ba3dfba0b7e8.svn-base

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+		<attributes>
+			<attribute name="owner.project.facets" value="java"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

+ 16 - 0
iamberry-app-international/.svn/pristine/e4/e43a492614f0727399ffdb3e905804afe9d5e976.svn-base

@@ -0,0 +1,16 @@
+SMS_USERNAME=aibeiyuan
+SMS_PASSWORD=aibeiyuan632
+SMS_TEXT=\u3010\u6bd4\u6bd4\u840c\u3011\u60a8\u7684\u9a8c\u8bc1\u7801\u662f\uff1a{0}\uff0c\u5982\u975e\u672c\u4eba\u64cd\u4f5c\uff0c\u8bf7\u5ffd\u7565\u672c\u77ed\u4fe1
+SMS_URL=http://115.29.44.189:8080/sms/smsInterface.do
+SINA_IP_URL=http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip={0}
+APPID=wxe9e992877625202f
+MCH_ID=1316959401
+SECRET=ae12dfeca278d7e4f15047313d453733
+UNIFIED_ORDER_CALLBACK_URL=demo.tronsis.com
+master_secret=ffd6373d25f9e36ba6e9d7c3
+appkey=cef2f16aa36424f2a6d4ca60
+cdnUrl=http://cms.iamberry.com/cdn
+base_url=testtest
+INTER_SMS_URL=https://sms.yunpian.com/v2/sms/single_send.json
+INTER_SMS_TEXT=\u3010\u6bd4\u6bd4\u840c\u3011\u60a8\u7684\u9a57\u8b49\u78bc\u662f\uff1a{0}\uff0c3\u5206\u9418\u5167\u6709\u6548\u3002\u5982\u975e\u672c\u4eba\u64cd\u4f5c\uff0c\u8acb\u5ffd\u7565\u672c\u7c21\u8a0a\u3002
+INTER_SMS_KEY=415754e72ef318ecce825c8ecdd56fae

+ 225 - 0
iamberry-app-international/.svn/pristine/e7/e7142d3a63215aae63ce15d5fc9edc2c700574bd.svn-base

@@ -0,0 +1,225 @@
+package com.iamberry.app.international.util;
+
+/*import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Properties;
+
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.util.DefaultPropertiesPersister;
+import org.springframework.util.PropertiesPersister;
+
+import com.iamberry.app.international.controller.GlobalController;
+
+*//**
+ * 国际化工具类
+ * @author Administrator
+ *
+ *//*
+public class languageUtil {
+	    
+	    public String getKey(String keyName, String language) {
+	    	init();
+	    	return properties.get(keyName + "-" + language).toString();
+	    }
+	    
+	    *//**
+		 * 载入多个properties文件, 相同的属性在最后载入的文件中的值将会覆盖之前的载入. 文件路径使用Spring Resource格式, 文件编码使用UTF-8.
+		 * @see org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
+		 *//*
+		public Properties loadProperties(String... resourcesPaths) throws IOException {
+			if (properties != null) {
+				return properties;
+			}
+			if (resourcesPaths == null) {
+				throw new NullPointerException("No resource path");
+			}
+			
+			Properties props = new Properties();
+			for (String location : resourcesPaths) {
+				InputStream is = null;
+				try {
+					Resource resource = resourceLoader.getResource(location);
+					is = resource.getInputStream();
+					propertiesPersister.load(props, new InputStreamReader(is, DEFAULT_ENCODING));
+				} catch (IOException ex) {
+				} finally {
+					if (is != null) {
+						is.close();
+					}
+				}
+			}
+			return props;
+		}
+		// 编码
+		private final String DEFAULT_ENCODING = "UTF-8";
+		// Spring-core 获取配置文件的类
+		private PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();	
+		// Spring-core 获取资源的类
+		private ResourceLoader resourceLoader = new PathMatchingResourcePatternResolver();
+		private Properties properties = null;
+		
+		public void init() {
+			if (properties == null) {
+				try {
+					synchronized (this) {
+						properties = loadProperties("messages_EN.properties,messages_HK.properties,messages_ZH.properties");
+					}
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				} 
+			}
+		}
+		
+		
+		 * 遍历获取国际化文件
+		 
+		private String type; // 后缀名
+	    public languageUtil(String type)
+	    {
+	        this.type = type;
+	    }
+	    public boolean accept(File dir, String name)
+	    {
+	        return name.endsWith(type);
+	    }
+	    static void filterfile(String dir, String suffix, ArrayList<String> fileList)
+	    {
+	        File f = new File(dir);
+	        File [] myList = f.listFiles();
+	        GlobalController filter = new GlobalController(suffix);
+	        String [] files = f.list(filter);
+	        fileList.addAll(Arrays.asList(files));
+	        for (File a : myList)
+	        {
+	            if (a.isDirectory())
+	            {
+	                    filterfile(a.toString(), suffix, fileList);
+	            } 
+	        }
+	    }
+	    
+	    public static void main(String[] args)
+	    {
+	        ArrayList<String> fileList = new ArrayList<String>();
+	        GlobalController.filterfile("src/main/resources", "properties", fileList);
+	        StringBuffer sb = null;
+	        for(String s:fileList)
+	        {
+	            System.out.println(s);
+	            sb.append(s);
+	        }
+	        System.out.println(sb);
+	    }
+}
+*/
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.util.DefaultPropertiesPersister;
+import org.springframework.util.PropertiesPersister;
+
+
+public class languageUtil {
+	
+	/**
+	 * 载入多个properties文件, 相同的属性在最后载入的文件中的值将会覆盖之前的载入. 文件路径使用Spring Resource格式, 文件编码使用UTF-8.
+	 * @see org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
+	 */
+	private synchronized static void loadProperties(String... resourcesPaths) throws IOException {
+		System.out.println("......");
+		if (resourceLoader == null) {
+			resourceLoader = new PathMatchingResourcePatternResolver();
+		}
+		if (propertiesPersister == null) {
+			propertiesPersister = new DefaultPropertiesPersister();
+		}
+		if (resourcesPaths == null) {
+			throw new NullPointerException("No resource path");
+		}
+		Properties props = null;
+		if (properties == null) {
+			props = new Properties();
+			properties = props;
+		} else {
+			props = properties;
+		}
+		for (String location : resourcesPaths) {
+			InputStream is = null;
+			try {
+				Resource resource = resourceLoader.getResource(location);
+				is = resource.getInputStream();
+				propertiesPersister.load(props, new InputStreamReader(is, DEFAULT_ENCODING));
+			} catch (IOException ex) {
+				ex.printStackTrace();
+			} finally {
+				if (is != null) {
+					is.close();
+				}
+			}
+		}
+	}
+	
+	/*public static void main(String[] args) {
+		System.out.println(get("username", "ZH"));
+		System.out.println(get("username", "EN"));
+		System.out.println(get("username", "ZH"));
+		System.out.println(get("username", "EN"));
+		System.out.println(get("username", "ZH"));
+		System.out.println(get("username", "EN"));
+		System.out.println(get("username", "ZH"));
+		System.out.println(get("username", "EN"));
+	}*/
+	
+	// 已经加载过的资源,为了高效,不使用锁
+	private static HashMap<String, String> loadeds = new HashMap<String, String>();
+	
+	/**
+	 * 根据一个key和语言获取对应的数据,并且保证系统延迟加载
+	 * @param key
+	 * @param language
+	 * @return
+	 * @throws IOException
+	 */
+	public static String get(String key, String language) {
+		// 判断是否已经加载过此资源文件
+		if (loadeds.get("messages_" + language) == null) {
+			// 防止多线程
+			synchronized (loadeds) {
+				// 防止重复加载资源
+				if (loadeds.get("messages_" + language) == null) {
+					try {
+						// 加载资源
+						loadProperties("messages_" + language + ".properties");
+						loadeds.put("messages_" + language, "messages_" + language + ".properties");
+					} catch (IOException e) {
+						// 如果失败,默认选择香港
+						return null;
+					}
+				}
+			}
+		}
+		return properties.get(key + "-" + language).toString();
+	}
+	private static Properties properties = null;
+	// 编码
+	private static final String DEFAULT_ENCODING = "UTF-8";
+	// Spring-core 获取配置文件的类
+	private static PropertiesPersister propertiesPersister = null;
+	// Spring-core 获取资源的类
+	private static ResourceLoader resourceLoader = null;
+}

+ 279 - 0
iamberry-app-international/.svn/pristine/e9/e976cfdd82b4e49c7ef7470f148d4c19d0c0b878.svn-base

@@ -0,0 +1,279 @@
+package com.iamberry.app.international.controller;
+
+import static com.iamberry.app.config.Response.BARCODE_NOT_FOUND;
+import static com.iamberry.app.config.Response.INVALID_TOKEN;
+import static com.iamberry.app.config.Response.SUCCESS;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.iamberry.app.config.Response;
+import com.iamberry.app.config.ResponseHeader;
+import com.iamberry.app.core.dto.RecordDTO;
+import com.iamberry.app.core.entity.MilkImages;
+import com.iamberry.app.core.entity.MilkMakingRecord;
+import com.iamberry.app.core.entity.MilkPowderInfo;
+import com.iamberry.app.core.entity.User;
+import com.iamberry.wechat.file.FileUtils;
+import com.iamberry.wechat.file.UploadResultBean;
+
+/**
+ * UserController
+ *
+ * @author Moon Cheng
+ * @date 2016年1月18日 上午11:53:04
+ */
+@Controller
+@RequestMapping("/secure/milk")
+public class MilkController extends BaseController {
+
+	@InitBinder("makingRecord")
+	public void initBinderRecord(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("makingRecord.");
+	}
+
+	@InitBinder("milkPowderInfo")
+	public void initBinderMilkPowder(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("milkPowderInfo.");
+	}
+
+	/**
+	 * 添加冲奶信息 
+	 * @author Moon Cheng
+	 * @param token 唯一标识符 
+	 * @param makingRecord 冲奶信息实体类
+	 * @return 1000:请求成功;2100:无效token;
+	 */
+	@RequestMapping(value = "/set_milk_making_record", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMilkMakingRecord(@RequestParam("token") String token, MilkMakingRecord makingRecord) {
+		makingRecord = milkService.setMilkMakingRecord(makingRecord, token);
+		if (makingRecord == null) {
+			return INVALID_TOKEN;
+		}
+		return SUCCESS.setData(makingRecord, 1);
+	}
+
+	/**
+	 *  通过日期,日期类型,统计某时间的,冲奶总量
+	 * @param token   唯一标识符
+	 * @param dateStatus 标识符 : day week year 
+	 * @param chosenDate 结束时间
+	 * @param machineMac 机器mac地址
+	 * @return
+	 */
+	@RequestMapping(value = "/search_user_records_by_time", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchUserRecordsByTime(@RequestParam(value = "token") String token,
+			@RequestParam("date_status") String dateStatus, @RequestParam("chosen_date") String chosenDate,
+			@RequestParam("devid") String machineMac) {
+
+		User userInfo = userService.validateUserToken(token);
+		if (userInfo == null) {
+			return INVALID_TOKEN;
+		}
+		Map<String, List<RecordDTO>> makingRecords = milkService.searchUserRecordsByTime(userInfo.getId(), dateStatus,
+				chosenDate, machineMac);
+		return SUCCESS.setData(makingRecords, makingRecords.size());
+	}
+
+	/**
+	 * 通过冲奶记录id获取冲奶记录详情
+	 * @author Moon Cheng
+	 * @param recordId 冲奶记录,id
+	 * @return 
+	 *//*
+	@RequestMapping(value = "/search_user_record_by_id", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchUserRecordById(@RequestParam(value = "record_id") Long recordId) {
+		MilkMakingRecord makingRecord = milkService.searchUserRecordById(recordId);
+		return SUCCESS.setData(makingRecord, 1);
+	}*/
+
+	/**
+	 * 根据用户id获取用户,冲奶总容量
+	 * @author Moon Cheng
+	 * @param userId  用户id 
+	 * @return
+	 */
+	@RequestMapping(value = "/get_user_total_milk_volume", method = RequestMethod.POST)
+	@ResponseBody
+	private Response getTotalMilkVolumeMadeByUser(@RequestParam(value = "user_id") Long userId) {
+		return SUCCESS.setData(milkService.getTotalMilkVolumeMadeByUser(userId), 0);
+	}
+
+	/**
+	 * 手动添加,奶粉信息!
+	 * @author Moon Cheng
+	 * @param token  唯一标识符
+	 * @param milkPowderInfo  奶粉信息
+	 * @return
+	 */
+	@RequestMapping(value = "/set_milk_powder_info", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMilkPowderInfo(@RequestParam(value = "token") String token, MilkPowderInfo milkPowderInfo) {
+		
+		// 勺量,每勺多少克     量勺 克数范围2-18
+		String amountStr = request.getParameter("a_mount");
+		if (amountStr == null) {
+			// 兼容低版本
+			milkPowderInfo = milkService.setMilkPowderInfo(milkPowderInfo, token);
+			if (milkPowderInfo == null) {
+				return INVALID_TOKEN;
+			}
+			return SUCCESS.setData(milkPowderInfo, 1);
+		}
+		
+		float amount = Float.parseFloat(amountStr);
+		// 勺数,多少少		量勺勺数范围 1-10
+		int spoonNum = Integer.parseInt(request.getParameter("spoon_num"));
+		// ML,1勺多少奶量  水量范围30-300
+		float spoonML = Float.parseFloat(request.getParameter("spoon_ml"));
+		
+		// 毫升/勺	
+		float s = spoonML / spoonNum;
+		
+		// 混合比 计算公式:勺量   * 勺数  / 毫升 / 100 = 混合比
+		float ratio = amount * spoonNum / spoonML * 100;
+		milkPowderInfo.setPowder_ratio(ratio);
+		milkPowderInfo.setWeight_per_spoon(amount);
+		milkPowderInfo.setMilk_volume_per_spoon(s);
+		
+		// 密度
+		/*
+		 *     A<13.2                6
+			   13.21<A<15.3          7
+			   15.31<A<17.4          8 
+			   17.41<A<19.5          9
+			   19.51<A<22.0         10 
+			   22.1 <A              10
+		 */
+		int m = 6;
+		if (ratio < 13.2) {
+			m = 6;
+		} else if (ratio > 13.21 && ratio < 15.3) {
+			m = 7;
+		} else if (ratio > 15.31 && ratio < 17.4) {
+			m = 8;
+		} else if (ratio > 17.41 && ratio < 19.5) {
+			m = 9;
+		} else {
+			m = 10;
+		}
+		milkPowderInfo.setDensity((float)m);
+		
+		// 保存操作
+		milkPowderInfo = milkService.setMilkPowderInfo(milkPowderInfo, token);
+		if (milkPowderInfo == null) {
+			return INVALID_TOKEN;
+		}
+		
+		// 保存图片
+		String imageFront = request.getParameter("imageFront");
+		String imageBar = request.getParameter("imageBar");
+		String imageFeed = request.getParameter("imageFeed");
+		MilkImages images = new MilkImages();
+		images.setImage_Front(imageFront);
+		images.setImage_Bar(imageBar);
+		images.setImage_Feed(imageFeed);
+		images.setImage_Milk_ID(milkPowderInfo.getId());
+		milkService.setMilkImages(images);
+		
+		return SUCCESS.setData(milkPowderInfo, 1);
+	}
+
+	/**
+	 * 通过,条形码获取奶粉信息
+	 * @author Moon Cheng
+	 * @param barcode 条形码code
+	 * @return
+	 */
+	@RequestMapping(value = "/search_milk_powder_info_by_barcode", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkPowderInfoByBarCode(@RequestParam(value = "barcode") String barcode) {
+		MilkPowderInfo milkPowderInfo = milkService.searchMilkPowderInfoByBarCode(barcode);
+		if (milkPowderInfo == null) {
+			return BARCODE_NOT_FOUND;
+		}
+		return SUCCESS.setData(milkPowderInfo, 1);
+	}
+
+	/**
+	 * 铜鼓品牌名获取奶粉信息
+	 * @author Moon Cheng, Yin
+	 * @param brand 品牌名
+	 * @return
+	 */
+	@RequestMapping(value = "/search_milk_powder_infos_by_brand", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkPowderInfosByBrand(@RequestParam(value = "brand") String brand) {
+		Map<String, List<String>> milkPowderInfos = milkService.searchMilkPowderInfosByBrand(brand);
+		return SUCCESS.setData(milkPowderInfos, milkPowderInfos.size());
+	}
+
+	/**
+	 * 获取奶粉品牌
+	 * @author Yin 
+	 * @return  过滤掉品牌名中有.的 例如 a.b 这里或只查询到a
+	 */
+	@RequestMapping(value = "/search_milk_powder_brand", method = RequestMethod.GET)
+	@ResponseBody
+	private Response searchMilkPowderBrand() {
+		List<String> milkPowderInfos = milkService.searchMilkPowderBrand();
+		return SUCCESS.setData(milkPowderInfos, milkPowderInfos.size());
+	}
+
+	/**
+	 * 通过奶粉品牌、段数、系列、查询奶粉信息
+	 * @param brand 品牌
+	 * @param series 系列
+	 * @param level 段数
+	 * @return
+	 */
+/*	@RequestMapping(value = "/search_milk_info_by_brand_series_level", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkInfoByBrandSeriesLevel(@RequestParam("brand") String brand,
+			@RequestParam("series") String series, @RequestParam("level") String level) {
+		return SUCCESS.setData(milkService.searchMilkInfoByBrandSeriesLevel(brand, series, level), 1);
+	}*/
+
+	/**
+	 * 上传奶粉信息的域名,及保存的路径,需要tomcat单独域名映射/或者是nginx
+	 */
+	private static String SAVE_MILK_IMAGE_DOMAIN = "http://milk.iamberry.com/";
+	private static String SAVE_MILK_IMAGE_PATH = "/common/";
+	/**
+	 * @param model
+	 * @param request
+	 * @return
+	 */
+	@ResponseBody
+	@RequestMapping(value = "/upload_image", method = RequestMethod.POST)
+	public Response uploadFileImage(@RequestParam("file")MultipartFile[] files, HttpServletRequest request) {
+		Map<String, String> filemap= new HashMap<String, String>();
+		
+		for (int i = 0; i < files.length; i++) {
+			MultipartFile file = files[i];
+			// 保存文件
+			UploadResultBean bean = FileUtils.saveFile(request.getServletContext(), file, SAVE_MILK_IMAGE_PATH);
+			if (bean == null) {
+				// 文件有误
+				return new Response(new ResponseHeader(4204, "文件有误!", -1));
+			}
+			filemap.put("file"+i,SAVE_MILK_IMAGE_DOMAIN + bean.getSaveFileName());
+		}
+		return SUCCESS.setData(filemap, filemap.size());
+	}
+}

+ 42 - 0
iamberry-app-international/.svn/pristine/e9/e9b6c776a48fe323db4cdf51277f3c9a767aa1be.svn-base

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>iamberry-app-international</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.validation.validationbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<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>

+ 135 - 0
iamberry-app-international/.svn/pristine/ee/ee58651af845cebfbbc1b4074a47603375032868.svn-base

@@ -0,0 +1,135 @@
+package com.iamberry.app.international.controller;
+
+import java.util.List;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.iamberry.app.config.Response;
+import com.iamberry.app.core.entity.Machine;
+import com.iamberry.app.international.util.Utility;
+
+/**
+ * 	机器操作接口
+ *
+ * @author Moon Cheng
+ * @date 2016年3月23日 下午2:22:25
+ */
+@Controller
+@RequestMapping("/secure/machine")
+public class MachineController extends BaseController {
+	@InitBinder("machine")
+	public void initBinderMachine(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("machine.");
+	}
+
+	/**
+	 * 设置机器信息
+	 *
+	 * @author Moon Cheng
+	 * @param machine 机器信息
+	 * @param token 用户token
+	 * @return
+	 */
+	@RequestMapping(value = "/set_machine", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMachine(Machine machine, @RequestParam("token") String token) {
+		String ip = Utility.getIp(request);
+		machine = machineService.setMachine(machine, token, ip);
+		if (machine == null) {
+			return Response.INVALID_TOKEN;
+		}
+		return Response.SUCCESS.setData(machine, 1);
+	}
+
+	/**
+	 * 更新机器状态
+	 * @author Moon Cheng
+	 * @param machineId 机器id
+	 * @param status 机器状态
+	 * @param token 唯一标识符
+	 * @return 2100:无效token; 1000:请求成功;
+	 */
+	@RequestMapping(value = "/update_machine_status", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateMachineStatus(@RequestParam("machine_id") Long machineId,
+			@RequestParam("status") String status, @RequestParam("token") String token) {
+		int reslut = machineService.updateMachineStatus(machineId, status, token);
+		if (reslut == -1) {
+			return Response.INVALID_TOKEN;
+		}
+		return Response.SUCCESS.setData(null);
+	}
+
+	/**
+	 * 更新机器地理位置
+	 * @author Moon Cheng
+	 * @param machineId 机器id
+	 * @param location 机器位置
+	 * @param token 唯一标识符
+	 * @return
+	 */
+	@RequestMapping(value = "/update_machine_location", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateMachineLocation(@RequestParam("machine_id") Long machineId,
+			@RequestParam("location") String location, @RequestParam("token") String token) {
+		int reslut = machineService.updateMachineLocation(machineId, location, token);
+		if (reslut == -1) {
+			return Response.INVALID_TOKEN;
+		}
+		return Response.SUCCESS.setData(null);
+	}
+
+	/**
+	 * 按用户,查询机器
+	 * @author Moon Cheng
+	 * @param owner 用户id
+	 * @param token 唯一标识符
+	 * @return
+	 */
+	@RequestMapping(value = "/search_machine_by_owner", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMachineByOwner(@RequestParam("user_id") Long owner, @RequestParam("token") String token) {
+		List<Machine> machines = machineService.searchMachineByOwner(owner, token);
+		if (machines == null) {
+			return Response.INVALID_TOKEN;
+		}
+		return Response.SUCCESS.setData(machines, machines.size());
+	}
+
+	/**
+	 * 按机器id,查询机器
+	 * @author Moon Cheng
+	 * @param machineId 机器id
+	 * @param token 用户唯一标识符
+	 * @return
+	 */
+	@RequestMapping(value = "/search_machine_by_id", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMachineById(@RequestParam("machine_id") Long machineId,
+			@RequestParam("token") String token) {
+		Machine machine = machineService.searchMachineById(machineId, token);
+		if (machine == null) {
+			return Response.INVALID_TOKEN;
+		}
+		return Response.SUCCESS.setData(machine, 1);
+	}
+
+	/**
+	 * updateStatus
+	 * 更改机器在线状态
+	 * @param status
+	 * @return
+	 */
+	@RequestMapping(value = "/update_status", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateStatus(@RequestParam("status") String status) {
+		machineService.updateStatus(status);
+		return Response.SUCCESS;
+	}
+}

+ 25 - 0
iamberry-app-international/.svn/pristine/fb/fb18f58e6853e18e5b708b31d03f7d25872b4325.svn-base

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+    <wb-module deploy-name="iamberry-app-international">
+        <wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
+        <wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
+        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
+        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
+        <dependent-module archiveName="iamberry-app-interface-1.0.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/iamberry-app-interface/iamberry-app-interface">
+            <dependency-type>uses</dependency-type>
+        </dependent-module>
+        <dependent-module archiveName="iamberry-common-core-1.0.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/iamberry-common-core/iamberry-common-core">
+            <dependency-type>uses</dependency-type>
+        </dependent-module>
+        <dependent-module archiveName="iamberry-common-tool-1.0.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/iamberry-common-tool/iamberry-common-tool">
+            <dependency-type>uses</dependency-type>
+        </dependent-module>
+        <dependent-module archiveName="iamberry-common-config-1.0.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/iamberry-common-config/iamberry-common-config">
+            <dependency-type>uses</dependency-type>
+        </dependent-module>
+        <dependent-module archiveName="iamberry-common-web-1.0.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/iamberry-common-web/iamberry-common-web">
+            <dependency-type>uses</dependency-type>
+        </dependent-module>
+        <property name="context-root" value="iamberry-app-international"/>
+        <property name="java-output-path" value="/iamberry-app-international/target/classes"/>
+    </wb-module>
+</project-modules>

+ 23 - 0
iamberry-app-international/.svn/pristine/fd/fd923f0c62097e8d78d4b67f23323131bae06cf4.svn-base

@@ -0,0 +1,23 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+    pageEncoding="UTF-8"%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=charset=UTF-8">
+<title>Insert title here</title>
+</head>
+<body>
+ <a href="test?langType=zh">中文</a> | <a href="test?langType=en">英文</a><br/>
+
+    下面展示的是后台获取的国际化信息:<br/>
+    ${username}<br/>
+    ${date}<br/>
+
+    下面展示的是视图中直接绑定的国际化信息:<br/>
+    <spring:message code="money"/>:<br/>
+    <spring:eval expression="contentModel.money"></spring:eval><br/>
+    <spring:message code="date"/>:<br/>
+    <spring:eval expression="contentModel.date"></spring:eval><br/>
+
+</body>
+</html>

二進制
iamberry-app-international/.svn/wc.db


+ 98 - 0
iamberry-app-international/pom.xml

@@ -0,0 +1,98 @@
+<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>
+	<parent>
+		<groupId>com.iamberry</groupId>
+		<artifactId>iamberry-parent</artifactId>
+		<version>1.0.0</version>
+	</parent>
+
+	<artifactId>iamberry-app-international</artifactId>
+	<packaging>war</packaging>
+
+	<dependencies>
+		<dependency>
+			<groupId>com.iamberry</groupId>
+			<artifactId>iamberry-app-international-service</artifactId>
+			<version>1.0.0</version>
+			<exclusions>
+				<exclusion>
+					<artifactId>spring</artifactId>
+					<groupId>org.springframework</groupId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.slf4j</groupId>
+					<artifactId>jcl-over-slf4j</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.slf4j</groupId>
+					<artifactId>slf4j-jcl</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<!-- 新的项目使用druid -->
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>druid</artifactId>
+			<version>1.0.20</version>
+		</dependency>
+		
+		<!-- 涂鸦包 -->
+		<dependency>
+            <groupId>org.springframework.integration</groupId>
+            <artifactId>spring-integration-kafka</artifactId>
+            <version>2.1.0.RELEASE</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>log4j</groupId>
+                    <artifactId>log4j</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>2.6.6</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <version>2.6.6</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.6.6</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.21</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <version>1.7.21</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>1.1.7</version>
+        </dependency>
+        <dependency>
+            <groupId>org.logback-extensions</groupId>
+            <artifactId>logback-ext-spring</artifactId>
+            <version>0.1.4</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
+            <version>1.1.7</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.14</version>
+        </dependency>
+	</dependencies>
+</project>

+ 26 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/controller/ApkDownload.java

@@ -0,0 +1,26 @@
+package com.iamberry.app.international.controller;
+
+import java.io.IOException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+
+@Controller
+@RequestMapping("/test-download/")
+public class ApkDownload extends BaseController {
+
+	@RequestMapping(value = "test_iamberry_release.apk", method = RequestMethod.GET)
+	@ResponseBody
+	private void download(HttpServletResponse response, HttpServletRequest request) {
+		try {
+			response.sendRedirect("/download/iamberry_release_" + userService.getApkVersion() + ".apk");
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+}

+ 79 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/controller/BaseController.java

@@ -0,0 +1,79 @@
+package com.iamberry.app.international.controller;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.iamberry.app.config.Response;
+import com.iamberry.app.config.ResponseHeader;
+import com.iamberry.app.face.CodeService;
+import com.iamberry.app.face.LogService;
+import com.iamberry.app.face.MachineService;
+import com.iamberry.app.face.MessageService;
+import com.iamberry.app.face.MilkService;
+import com.iamberry.app.face.UserService;
+import com.iamberry.wechat.tools.ResponseJson;
+
+public class BaseController {
+
+	@Autowired
+	protected UserService userService;
+	@Autowired
+	protected MachineService machineService;
+	@Autowired
+	protected MilkService milkService;
+	@Autowired
+	LogService logService;
+	@Autowired
+	MessageService messageService;
+	@Autowired
+	HttpServletRequest request;
+	@Autowired
+	CodeService codeService;
+
+	public final static Map<String, Object> validateCodeMap = new ConcurrentHashMap<>();
+
+	protected static Response createResponse(ResponseHeader header, Object payload) {
+		return new Response(header, payload);
+	}
+
+	protected static Response createResponse(ResponseHeader header) {
+		return new Response(header);
+	}
+
+/**
+ **?*
+ */
+	/**
+	 * 判断用户的手机号码是否和短信验证码匹配,注意,此类实现方法,本身就是一个弊端,系统一旦长期运行,会导致内存崩溃。
+	 * @param phone				手机号码
+	 * @param verificationCode	短信验证码
+	 * @return
+	 */
+	protected int checkVerifyCode(String phone, String verificationCode, int codeScenario) {
+		ResponseJson json = codeService.validCode(phone, verificationCode, codeScenario);
+		if (json.getReturnCode() == 200) {
+			return 1;
+		} else if (json.getReturnCode() == 404) {
+			return -1;
+		}
+		return -2;
+	}
+
+	/**
+	 * 校验时间,如果发送时间+180s 大于 当前时间,返回false 
+	 * @param date
+	 * @return
+	 */
+	protected static boolean verifyCodeTime(Date date) {
+		Long nowDate = new Date().getTime();
+		if (date.getTime() + 180000 > nowDate) {
+			return false;
+		}
+		return true;
+	}
+}

+ 50 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/controller/GlobalController.java

@@ -0,0 +1,50 @@
+package com.iamberry.app.international.controller;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Properties;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.util.DefaultPropertiesPersister;
+import org.springframework.util.PropertiesPersister;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.i18n.CookieLocaleResolver;
+import org.springframework.web.servlet.support.RequestContext;
+
+import com.iamberry.app.international.model.FormatModel;
+import com.iamberry.app.international.util.languageUtil;
+import com.iamberry.zk.ZookeeperFactory;
+
+@Controller
+@RequestMapping(value = "/global")
+public class GlobalController{
+    
+    @RequestMapping(value="/test", method = {RequestMethod.GET})
+    public String test(HttpServletRequest request, HttpServletResponse response, Model model, @RequestParam(value="langType", defaultValue="zh") String langType){
+      
+        languageUtil languageutil = new languageUtil();
+    	String username = languageutil.get("username", langType);
+    	model.addAttribute("username", username);
+        return "globaltest";
+    }
+	
+   
+}

+ 135 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/controller/MachineController.java

@@ -0,0 +1,135 @@
+package com.iamberry.app.international.controller;
+
+import java.util.List;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.iamberry.app.config.Response;
+import com.iamberry.app.core.entity.Machine;
+import com.iamberry.app.international.util.Utility;
+
+/**
+ * 	机器操作接口
+ *
+ * @author Moon Cheng
+ * @date 2016年3月23日 下午2:22:25
+ */
+@Controller
+@RequestMapping("/secure/machine")
+public class MachineController extends BaseController {
+	@InitBinder("machine")
+	public void initBinderMachine(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("machine.");
+	}
+
+	/**
+	 * 设置机器信息
+	 *
+	 * @author Moon Cheng
+	 * @param machine 机器信息
+	 * @param token 用户token
+	 * @return
+	 */
+	@RequestMapping(value = "/set_machine", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMachine(Machine machine, @RequestParam("token") String token) {
+		String ip = Utility.getIp(request);
+		machine = machineService.setMachine(machine, token, ip);
+		if (machine == null) {
+			return Response.INVALID_TOKEN;
+		}
+		return Response.SUCCESS.setData(machine, 1);
+	}
+
+	/**
+	 * 更新机器状态
+	 * @author Moon Cheng
+	 * @param machineId 机器id
+	 * @param status 机器状态
+	 * @param token 唯一标识符
+	 * @return 2100:无效token; 1000:请求成功;
+	 */
+	@RequestMapping(value = "/update_machine_status", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateMachineStatus(@RequestParam("machine_id") Long machineId,
+			@RequestParam("status") String status, @RequestParam("token") String token) {
+		int reslut = machineService.updateMachineStatus(machineId, status, token);
+		if (reslut == -1) {
+			return Response.INVALID_TOKEN;
+		}
+		return Response.SUCCESS.setData(null);
+	}
+
+	/**
+	 * 更新机器地理位置
+	 * @author Moon Cheng
+	 * @param machineId 机器id
+	 * @param location 机器位置
+	 * @param token 唯一标识符
+	 * @return
+	 */
+	@RequestMapping(value = "/update_machine_location", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateMachineLocation(@RequestParam("machine_id") Long machineId,
+			@RequestParam("location") String location, @RequestParam("token") String token) {
+		int reslut = machineService.updateMachineLocation(machineId, location, token);
+		if (reslut == -1) {
+			return Response.INVALID_TOKEN;
+		}
+		return Response.SUCCESS.setData(null);
+	}
+
+	/**
+	 * 按用户,查询机器
+	 * @author Moon Cheng
+	 * @param owner 用户id
+	 * @param token 唯一标识符
+	 * @return
+	 */
+	@RequestMapping(value = "/search_machine_by_owner", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMachineByOwner(@RequestParam("user_id") Long owner, @RequestParam("token") String token) {
+		List<Machine> machines = machineService.searchMachineByOwner(owner, token);
+		if (machines == null) {
+			return Response.INVALID_TOKEN;
+		}
+		return Response.SUCCESS.setData(machines, machines.size());
+	}
+
+	/**
+	 * 按机器id,查询机器
+	 * @author Moon Cheng
+	 * @param machineId 机器id
+	 * @param token 用户唯一标识符
+	 * @return
+	 */
+	@RequestMapping(value = "/search_machine_by_id", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMachineById(@RequestParam("machine_id") Long machineId,
+			@RequestParam("token") String token) {
+		Machine machine = machineService.searchMachineById(machineId, token);
+		if (machine == null) {
+			return Response.INVALID_TOKEN;
+		}
+		return Response.SUCCESS.setData(machine, 1);
+	}
+
+	/**
+	 * updateStatus
+	 * 更改机器在线状态
+	 * @param status
+	 * @return
+	 */
+	@RequestMapping(value = "/update_status", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateStatus(@RequestParam("status") String status) {
+		machineService.updateStatus(status);
+		return Response.SUCCESS;
+	}
+}

+ 260 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/controller/MessageController.java

@@ -0,0 +1,260 @@
+package com.iamberry.app.international.controller;
+
+import static com.iamberry.app.config.Response.SUCCESS;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.iamberry.app.config.Response;
+import com.iamberry.app.core.dto.JpushMessageDTO;
+import com.iamberry.app.core.entity.Message;
+import com.iamberry.app.core.entity.User;
+import com.iamberry.app.core.serch.SerchParam;
+import com.iamberry.app.international.util.Jdpush;
+import com.iamberry.wechat.core.entity.PageBean;
+import com.iamberry.wechat.core.entity.banner.MessageDTO;
+
+/**
+ * MessageController
+ *
+ * @author lc
+ * @date 2016年9月13日17:50:59
+ */
+@Controller
+@RequestMapping("/secure/message")
+public class MessageController extends BaseController {
+
+	@InitBinder("message")
+	public void initBinderMessage(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("message.");
+	}
+
+	
+	/**
+	 * 查询所有消息 并分页
+	 * 2016年9月14日09:40:10
+	 * @author lc
+	 * @param page	分页信息
+	 * @return
+	 */
+	@RequestMapping("/list")
+	public ModelAndView getMessageList(@RequestParam(value= "pageSize",defaultValue= "15" ,required=false) Integer pageSize, 
+			@RequestParam(value = "pageNO", defaultValue = "1",required=false) Integer pageNO,
+			SerchParam params,
+			HttpServletRequest request) throws Exception {
+		StringBuffer url = new StringBuffer("/secure/message/list?pageSize=" + pageSize);
+		ModelAndView mv = new ModelAndView("message/messageList");
+		//String goodName = request.getParameter("goodsInfoGoodname");
+		PageBean page = new PageBean();	//分页信息
+		page.setPageSize(pageSize);
+		page.setPageNumber(pageNO);
+		
+		if (StringUtils.isNoneEmpty(params.getTitle())) {
+			url.append("&title=" + params.getTitle());
+		}
+		if (StringUtils.isNoneEmpty(params.getBeginDate())) {
+			url.append("&beginDate=" + params.getBeginDate());
+		}
+		if (StringUtils.isNoneEmpty(params.getEndDate())) {
+			url.append("&endDate=" + params.getEndDate());
+		}
+		if (StringUtils.isNoneEmpty(params.getUsername())) {
+			url.append("&username=" + params.getUsername());
+		}
+		
+System.out.println(url);
+		page.setParams(params);
+		
+		List<Message> messages = messageService.selectMessageRecoreds(page);
+		url.append("&pageNO=");
+		int count = messageService.selectMessageCount(params);
+		int pageCount =  count % page.getPageSize() == 0? count/page.getPageSize():(count/page.getPageSize())+1;
+		//分页用
+		mv.addObject("list", messages);
+		mv.addObject("pageNO", pageNO);
+		mv.addObject("url", url);
+		mv.addObject("params", params);
+		mv.addObject("pageSize", pageCount);	
+		return mv;
+	}
+	
+	/**
+	 * 查询所有用户信息 并分页
+	 * 2016年9月14日09:40:10
+	 * @author lc
+	 * @param page	分页信息
+	 * @return
+	 */
+	@RequestMapping("/listuser")
+	public ModelAndView getUserList(@RequestParam(value= "pageSize",defaultValue= "15" ,required=false) Integer pageSize, 
+			@RequestParam(value = "pageNO", defaultValue = "1",required=false) Integer pageNO, 
+			SerchParam params,
+			HttpServletRequest request) throws Exception {
+		StringBuffer url = new StringBuffer("/secure/message/listuser?pageSize=" + pageSize);
+		ModelAndView mv = new ModelAndView("message/userList");
+		PageBean page = new PageBean();	//分页信息
+		page.setPageSize(pageSize);
+		page.setPageNumber(pageNO);
+		if (StringUtils.isNoneEmpty(params.getUsername())) {
+			url.append("&username=" + params.getUsername());
+		}
+		
+		page.setParams(params);//设置查询条件
+		List<User> users = messageService.selectUser(page);
+		url.append("&pageNO=");
+		int count = messageService.selectUserCount(params);
+		int pageCount =  count % page.getPageSize() == 0? count/page.getPageSize():(count/page.getPageSize())+1;
+		//分页用
+		mv.addObject("memberList", users);
+		mv.addObject("pageNO", pageNO);
+		mv.addObject("url", url);
+		mv.addObject("username", params.getUsername());
+		mv.addObject("pageSize", pageCount);	
+		return mv;
+	}
+	
+	/**
+	 * 进入添加页面
+	 * 2016年4月21日
+	 * @author 穆再兴
+	 * @return
+	 */
+	@RequestMapping(value ="/insert", method = RequestMethod.GET)
+	public ModelAndView toinsertMessage(){
+		ModelAndView mv = new ModelAndView("message/insertMessage");
+		return mv;
+	}
+	
+	/**
+	 * 添加一个消息
+	 * 2016年9月14日09:48:12
+	 * @author lc
+	 * @return
+	 */
+	@RequestMapping(value ="/insert", method = RequestMethod.POST)
+	public ModelAndView insertMessage(HttpServletRequest req,Message message){
+		ModelAndView mv = new ModelAndView("message/insertMessage");
+		
+		Integer n = 0;
+		//这里判断是否需要推送,调用推送util
+		if(message.getIs_needsend()==1){ //1需要推送,2不需要
+			String sendresult = Jdpush.buildPushObject_all_notifi(message);
+			message.setSend_result(sendresult);
+		}
+		//设置调用推送结果,
+		n =  messageService.insertMessage(message);
+		
+		if(n > 0){
+			mv.addObject("msgObj", new MessageDTO(true, "操作结果", "添加成功!"));
+		}else{
+			mv.addObject("msgObj", new MessageDTO(true, "操作结果", "添加失败!"));
+		}
+		
+		return mv;
+	}
+	
+	
+	@RequestMapping(value = "/sendMessage", method = RequestMethod.GET)
+	private ModelAndView sendMessage() {
+		ModelAndView mv = new ModelAndView("/message/sendMessage");
+		return mv;
+	}
+	
+	/**
+	 * 发送极光推送
+	 * @param content 内容
+	 * @param tag 目标人群的标签
+	 * @param platform 平台
+	 * @return
+	 */
+	@RequestMapping(value = "/sendMessage", method = RequestMethod.POST)
+	private ModelAndView sendMessage2(JpushMessageDTO jpushmessage) {
+		ModelAndView mv = new ModelAndView("/message/sendMessage");
+		String  resultCode = Jdpush.sendmessage_jpushmessage(jpushmessage);
+		
+		Message message = new Message();
+		message.setTitle(jpushmessage.getContent());
+		message.setContent(jpushmessage.getContent());
+		message.setUser(Long.parseLong(jpushmessage.getTag())); //tag 有规范,徐特殊处理
+		message.setRemark(jpushmessage.getPlatform());
+		message.setSend_result(resultCode);
+		message.setUrl(request.getParameter("url"));
+		//添加到数据库
+		messageService.insertMessage(message);
+System.out.println(resultCode);
+		return mv;
+	}
+	
+	/**
+	 * 点击发送极光推送
+	 * @param content 内容
+	 * @return
+	 */
+	@RequestMapping(value = "/sendMessageByid", method = RequestMethod.POST)
+	@ResponseBody
+	private MessageDTO sendMessageByid(@RequestParam(value = "recordId") Long recordId) {
+		Message message = messageService.selectUserMessageByid(recordId);
+		//修改到数据库
+		String sendresult = Jdpush.buildPushObject_all_notifi(message);
+		message.setSend_result(sendresult);
+		int i = messageService.updateMessage(message);
+		return new MessageDTO(true, "操作结果",sendresult);
+	}
+	
+	/**
+	 * 获取用户已读,未读消息
+	 * @param token 用户token
+	 * @param isread 1已读,2 未读
+	 * @return 用户已读,未读的条数 
+	 */
+	@RequestMapping(value = "/select_userMessage_byisread", method = RequestMethod.POST)
+	@ResponseBody
+	private Response selectUserMessageByisread(@RequestParam(value = "token") String token,@RequestParam("isread") Long isread) {
+		int messCount = messageService.selectUserMessageByisread(token,isread);
+		if (messCount == -1){
+			return Response.INVALID_TOKEN;
+		}
+		return SUCCESS.setData(messCount, messCount);
+	}
+	
+	/**
+	 * 根据用户token获取用户的所有消息
+	 * @param token 用户token
+	 * @return 用户的所有消息
+	 */
+	@RequestMapping(value = "/select_userMessage_recoreds", method = RequestMethod.POST)
+	@ResponseBody
+	private Response selectUserMessageRecoreds(@RequestParam(value = "token") String token) {
+		List<Message> messages = messageService.selectUserMessageRecoreds(token);
+		if (messages == null){
+			return Response.INVALID_TOKEN;
+		}
+		return SUCCESS.setData(messages, messages.size());
+	}
+	
+	/**
+	 * 根据消息id获取消息实体类--并修改为已读
+	 * @param recordId 消息实体类主键id
+	 * @return 消息实体类
+	 */
+	@RequestMapping(value = "/select_userMessage_byid", method = RequestMethod.POST)
+	@ResponseBody
+	private Response selectUserMessageByid(@RequestParam(value = "recordId") Long recordId) {
+		Message message = messageService.selectUserMessageByid(recordId);
+		if (message == null){
+			return Response.NOT_FOUND;
+		}
+		return SUCCESS.setData(message, 1);
+	}
+}

+ 303 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/controller/MilkController.java

@@ -0,0 +1,303 @@
+package com.iamberry.app.international.controller;
+
+import static com.iamberry.app.config.Response.BARCODE_NOT_FOUND;
+import static com.iamberry.app.config.Response.INVALID_TOKEN;
+import static com.iamberry.app.config.Response.SUCCESS;
+import static com.iamberry.app.config.Response.INSERT_DUPLICATE;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.dao.DataAccessException;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.iamberry.app.config.APIStatus;
+import com.iamberry.app.config.Response;
+import com.iamberry.app.config.ResponseHeader;
+import com.iamberry.app.core.dto.RecordDTO;
+import com.iamberry.app.core.entity.MilkImages;
+import com.iamberry.app.core.entity.MilkMakingRecord;
+import com.iamberry.app.core.entity.MilkPowderInfo;
+import com.iamberry.app.core.entity.User;
+import com.iamberry.wechat.file.FileUtils;
+import com.iamberry.wechat.file.UploadResultBean;
+
+/**
+ * UserController
+ *
+ * @author Moon Cheng
+ * @date 2016年1月18日 上午11:53:04
+ */
+@Controller
+@RequestMapping("/secure/milk")
+public class MilkController extends BaseController {
+
+	@InitBinder("makingRecord")
+	public void initBinderRecord(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("makingRecord.");
+	}
+
+	@InitBinder("milkPowderInfo")
+	public void initBinderMilkPowder(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("milkPowderInfo.");
+	}
+
+	/**
+	 * 添加冲奶信息 
+	 * @author Moon Cheng
+	 * @param token 唯一标识符 
+	 * @param makingRecord 冲奶信息实体类
+	 * @return 1000:请求成功;2100:无效token;
+	 */
+	@RequestMapping(value = "/set_milk_making_record", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMilkMakingRecord(@RequestParam("token") String token, MilkMakingRecord makingRecord) {
+		//目前添加了新的冲奶数据同步接口,所以当前方法做空实现处理
+		if(1 == 1){
+			return SUCCESS.setData(makingRecord, 1);
+		}
+		makingRecord = milkService.setMilkMakingRecord(makingRecord, token);
+		if (makingRecord == null) {
+			return INVALID_TOKEN;
+		}
+		return SUCCESS.setData(makingRecord, 1);
+	}
+
+	/**
+	 *  通过日期,日期类型,统计某时间的,冲奶总量
+	 * @param token   唯一标识符
+	 * @param dateStatus 标识符 : day week year 
+	 * @param chosenDate 结束时间
+	 * @param machineMac 机器mac地址
+	 * @return
+	 */
+	@RequestMapping(value = "/search_user_records_by_time", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchUserRecordsByTime(@RequestParam(value = "token") String token,
+			@RequestParam("date_status") String dateStatus, @RequestParam("chosen_date") String chosenDate,
+			@RequestParam("devid") String machineMac) {
+
+		User userInfo = userService.validateUserToken(token);
+		if (userInfo == null) {
+			return INVALID_TOKEN;
+		}
+		Map<String, List<RecordDTO>> makingRecords = milkService.searchUserRecordsByTime(userInfo.getId(), dateStatus,
+				chosenDate, machineMac);
+		return SUCCESS.setData(makingRecords, makingRecords.size());
+	}
+
+	/**
+	 * 通过冲奶记录id获取冲奶记录详情
+	 * @author Moon Cheng
+	 * @param recordId 冲奶记录,id
+	 * @return 
+	 *//*
+	@RequestMapping(value = "/search_user_record_by_id", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchUserRecordById(@RequestParam(value = "record_id") Long recordId) {
+		MilkMakingRecord makingRecord = milkService.searchUserRecordById(recordId);
+		return SUCCESS.setData(makingRecord, 1);
+	}*/
+
+	/**
+	 * 根据用户id获取用户,冲奶总容量
+	 * @author Moon Cheng
+	 * @param userId  用户id 
+	 * @return
+	 */
+	@RequestMapping(value = "/get_user_total_milk_volume", method = RequestMethod.POST)
+	@ResponseBody
+	private Response getTotalMilkVolumeMadeByUser(@RequestParam(value = "user_id") Long userId) {
+		return SUCCESS.setData(milkService.getTotalMilkVolumeMadeByUser(userId), 0);
+	}
+
+	/**
+	 * 手动添加,奶粉信息!
+	 * @author Moon Cheng
+	 * @param token  唯一标识符
+	 * @param milkPowderInfo  奶粉信息
+	 * @return
+	 */
+	@RequestMapping(value = "/set_milk_powder_info", method = RequestMethod.POST)
+	@ResponseBody
+	private Response setMilkPowderInfo(
+			@RequestParam(value = "a_mount") String amountStr,
+			@RequestParam(value = "spoon_num") String spoon_num,
+			@RequestParam(value = "spoon_ml") String spoon_ml,
+			@RequestParam(value = "imageFront") String imageFront,
+			@RequestParam(value = "imageBar") String imageBar,
+			@RequestParam(value = "imageFeed") String imageFeed,@RequestParam(value = "token") String token, MilkPowderInfo milkPowderInfo) {
+		if(milkPowderInfo.getBar_code() == null){
+			return INVALID_TOKEN;
+		}
+		MilkPowderInfo	milkInfo = milkService.selectMilkPowderByBar(milkPowderInfo.getBar_code());
+		if(milkInfo != null){
+			return INSERT_DUPLICATE;
+		}
+		
+		// 勺量,每勺多少克     量勺 克数范围2-18
+		//String amountStr = request.getParameter("a_mount");
+		if (amountStr == null) {
+			// 兼容低版本
+			milkPowderInfo = milkService.setMilkPowderInfo(milkPowderInfo, token);
+			if (milkPowderInfo == null) {
+				return INVALID_TOKEN;
+			}
+			return SUCCESS.setData(milkPowderInfo, 1);
+		}
+		
+		float amount = Float.parseFloat(amountStr);
+		// 勺数,多少少		量勺勺数范围 1-10
+		int spoonNum = Integer.parseInt(spoon_num);
+		// ML,1勺多少奶量  水量范围30-300
+		float spoonML = Float.parseFloat(spoon_ml);
+		
+		// 毫升/勺	
+		float s = spoonML / spoonNum;
+		
+		// 混合比 计算公式:勺量   * 勺数  / 毫升 / 100 = 混合比
+		float ratio = amount * spoonNum / spoonML * 100;
+		milkPowderInfo.setPowder_ratio(ratio);
+		milkPowderInfo.setWeight_per_spoon(amount);
+		milkPowderInfo.setMilk_volume_per_spoon(s);
+		
+		// 密度
+		/*
+		 *     A<13.2                6
+			   13.21<A<15.3          7
+			   15.31<A<17.4          8 
+			   17.41<A<19.5          9
+			   19.51<A<22.0         10 
+			   22.1 <A              10
+		 */
+		int m = 6;
+		if (ratio < 13.2) {
+			m = 6;
+		} else if (ratio > 13.21 && ratio < 15.3) {
+			m = 7;
+		} else if (ratio > 15.31 && ratio < 17.4) {
+			m = 8;
+		} else if (ratio > 17.41 && ratio < 19.5) {
+			m = 9;
+		} else {
+			m = 10;
+		}
+		milkPowderInfo.setDensity((float)m);
+		milkPowderInfo.setType(m);//同密度字段
+		// 保存操作
+		try {
+			milkPowderInfo = milkService.setMilkPowderInfo(milkPowderInfo, token);
+		} catch (DataAccessException  e) {
+			return INSERT_DUPLICATE;
+		}
+		
+		if (milkPowderInfo == null) {
+			return INVALID_TOKEN;
+		}
+		
+		// 保存图片
+		/*String imageFront = request.getParameter("imageFront");
+		String imageBar = request.getParameter("imageBar");
+		String imageFeed = request.getParameter("imageFeed");*/
+		MilkImages images = new MilkImages();
+		images.setImage_Front(imageFront);
+		images.setImage_Bar(imageBar);
+		images.setImage_Feed(imageFeed);
+		images.setImage_Milk_ID(milkPowderInfo.getId());
+		milkService.setMilkImages(images);
+		return SUCCESS.setData(milkPowderInfo, 1);
+	}
+
+	/**
+	 * 通过,条形码获取奶粉信息
+	 * @author Moon Cheng
+	 * @param barcode 条形码code
+	 * @return
+	 */
+	@RequestMapping(value = "/search_milk_powder_info_by_barcode", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkPowderInfoByBarCode(@RequestParam(value = "barcode") String barcode) {
+		MilkPowderInfo milkPowderInfo = milkService.searchMilkPowderInfoByBarCode(barcode);
+		if (milkPowderInfo == null) {
+			return BARCODE_NOT_FOUND;
+		}
+		return SUCCESS.setData(milkPowderInfo, 1);
+	}
+
+	/**
+	 * 铜鼓品牌名获取奶粉信息
+	 * @author Moon Cheng, Yin
+	 * @param brand 品牌名
+	 * @return
+	 */
+	@RequestMapping(value = "/search_milk_powder_infos_by_brand", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkPowderInfosByBrand(@RequestParam(value = "brand") String brand) {
+		Map<String, List<String>> milkPowderInfos = milkService.searchMilkPowderInfosByBrand(brand);
+		return SUCCESS.setData(milkPowderInfos, milkPowderInfos.size());
+	}
+
+	/**
+	 * 获取奶粉品牌
+	 * @author Yin 
+	 * @return  过滤掉品牌名中有.的 例如 a.b 这里或只查询到a
+	 */
+	@RequestMapping(value = "/search_milk_powder_brand", method = RequestMethod.GET)
+	@ResponseBody
+	private Response searchMilkPowderBrand() {
+		List<String> milkPowderInfos = milkService.searchMilkPowderBrand();
+		return SUCCESS.setData(milkPowderInfos, milkPowderInfos.size());
+	}
+
+	/**
+	 * 通过奶粉品牌、段数、系列、查询奶粉信息
+	 * @param brand 品牌
+	 * @param series 系列
+	 * @param level 段数
+	 * @return
+	 */
+/*	@RequestMapping(value = "/search_milk_info_by_brand_series_level", method = RequestMethod.POST)
+	@ResponseBody
+	private Response searchMilkInfoByBrandSeriesLevel(@RequestParam("brand") String brand,
+			@RequestParam("series") String series, @RequestParam("level") String level) {
+		return SUCCESS.setData(milkService.searchMilkInfoByBrandSeriesLevel(brand, series, level), 1);
+	}*/
+
+	/**
+	 * 上传奶粉信息的域名,及保存的路径,需要tomcat单独域名映射/或者是nginx
+	 */
+	private static String SAVE_MILK_IMAGE_DOMAIN = "http://milk.iamberry.com/";
+	private static String SAVE_MILK_IMAGE_PATH = "/common/";
+	/**
+	 * @param model
+	 * @param request
+	 * @return
+	 */
+	@ResponseBody
+	@RequestMapping(value = "/upload_image", method = RequestMethod.POST)
+	public Response uploadFileImage(@RequestParam("file")MultipartFile[] files, HttpServletRequest request) {
+		Map<String, String> filemap= new HashMap<String, String>();
+		
+		for (int i = 0; i < files.length; i++) {
+			MultipartFile file = files[i];
+			// 保存文件
+			UploadResultBean bean = FileUtils.saveFile(request.getServletContext(), file, SAVE_MILK_IMAGE_PATH);
+			if (bean == null) {
+				// 文件有误
+				return new Response(new ResponseHeader(4204, "文件有误!", -1));
+			}
+			filemap.put("file"+i,SAVE_MILK_IMAGE_DOMAIN + bean.getSaveFileName());
+		}
+		return SUCCESS.setData(filemap, filemap.size());
+	}
+}

+ 539 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/controller/UserController.java

@@ -0,0 +1,539 @@
+package com.iamberry.app.international.controller;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.FileUtils;
+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.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import sun.misc.BASE64Decoder;
+
+import com.iamberry.app.config.Constants;
+import com.iamberry.app.config.Response;
+import com.iamberry.app.config.ResponseHeader;
+import com.iamberry.app.core.dto.RemoteIpInfoDTO;
+import com.iamberry.app.core.dto.UserDTO;
+import com.iamberry.app.core.entity.User;
+import com.iamberry.app.international.util.TokenUtil;
+import com.iamberry.app.international.util.Utility;
+import com.iamberry.app.tool.util.AES;
+import com.iamberry.wechat.file.FileType;
+
+/**
+ * UserController
+ *
+ * @author Moon Cheng
+ * @date 2016年1月18日 上午11:53:04
+ */
+@Controller
+@RequestMapping("/secure/user")
+public class UserController extends BaseController {
+
+	@Autowired
+	HttpServletResponse response;
+	
+	private Logger logger = LoggerFactory.getLogger(UserController.class);
+	
+	// 保存用户头像的路径
+	private String saveRootPath = "/common/user_head/";
+	private String domain = "http://hk.iamberry.com";
+
+	@InitBinder("user")
+	public void initBinderUser(WebDataBinder binder) {
+		binder.setFieldDefaultPrefix("user.");
+	}
+
+	/**
+	 * 用户手机注册,成功返回json格式的用户信息
+	 * @author Moon Cheng
+	 * @param phone 手机号码
+	 * @param verificationCode 手机收到的短信验证码
+	 * @param password 密码
+	 * @param areacode  地区参数 +86 +866港澳台........
+	 * @return 2101:验证码错误;2102:验证码超时;1000:请求成功;2000:注册失败;
+	 */
+	@RequestMapping(value = "/register", method = RequestMethod.POST)
+	@ResponseBody
+	private Response register(@RequestParam("phone") String phone,
+			@RequestParam("verification_code") String verificationCode,
+			@RequestParam("password") String password,
+			@RequestParam("areacode") String areacode
+			) {
+		User user = new User();
+		int status = checkVerifyCode(phone, verificationCode, 1); //验证手机验证码是否正确
+		status = 1;
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else
+			if (status == 1) { //验证成功
+			User users = userService.selectUserByUsername(phone);
+				if(users == null){
+					String ip = Utility.getIp(request);
+					user = userService.register(areacode+","+phone, password, ip); 
+					if (user == null) {//注册失败
+						return Response.FAILURE;
+					}
+				}else{
+					return Response.ERROR_REGISTER;
+				}
+		}
+		System.out.println(phone+"-注册成功!请求涂鸦");
+		//注册成功,返回用户信息
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * 第三方【微信】用户手机绑定,
+	 * @author Moon Cheng
+	 * @param phone 手机号
+	 * @param openId 微信的open——id
+	 * @return 1000:请求成功;2000:注册失败;
+	 */
+	@RequestMapping(value = "/third_part_binding_phone", method = RequestMethod.POST)
+	@ResponseBody
+	private Response thirdPartBindingPhone(@RequestParam("phone") String phone,
+			@RequestParam("open_id") String openId,@RequestParam("code") String code,
+			@RequestParam("areacode") String areacode 
+			) {
+		User user = new User();
+		int status = checkVerifyCode(phone, code, 1); //验证手机验证码是否正确
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} 
+		user = userService.thirdPartBindingPhone(areacode+","+phone, openId);
+		if (user == null) {
+			return Response.USER_NOT_EXIST;
+		}
+		
+		logger.info(user.getId() + "," + (user.getId().intValue() == 2011));
+		
+		if (user.getPassword() != null && user.getPassword().equals("EXTIES")) {
+			ResponseHeader header = new ResponseHeader(2011, "用户已经存在!", 1);
+			UserDTO dto = userService.tuyaConnect(user);
+			return new Response(header, dto);
+		}
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * login
+	 * 手机号登录,
+	 * @param phone 手机号
+	 * @param password 密码
+	 * @return 2012:身份验证失败;2013:账户冻结;1000:请求成功;
+	 */
+	@RequestMapping(value = "/login", method = RequestMethod.POST)
+	@ResponseBody
+	private Response login(@RequestParam(value = "phone", required = true) String phone,
+			@RequestParam(value = "password", required = true) String password) {
+		Object user = userService.login(phone, password);
+		int status = 0;
+		if (user instanceof Integer) {
+			status = (Integer) user;
+			switch (status) { 
+			case -1: //账号不存在
+				return Response.USER_NOT_EXIST;
+			case -2: //密码错误
+				return Response.AUTHENTICATION_ERROR;
+			case -3: //用户状态不正常
+				return Response.USER_FROZEN_ERROR;
+			}
+		}
+		return Response.SUCCESS.setData((UserDTO) user, 1);
+	}
+
+	/**
+	 * thirdPartLogin
+	 * 第三方登录
+	 * @param openId 微信open_id 
+	 * @param extType 来源 qq或者微信
+	 * @param extName extname
+	 * @param extPicture 图片
+	 * @return 2012:身份验证失败;2013:账户冻结;1000:请求成功;
+	 */
+	@RequestMapping(value = "/third_part_login", method = RequestMethod.POST)
+	@ResponseBody
+	private Response thirdPartLogin(@RequestParam(value = "open_id") String openId,
+			@RequestParam(value = "ext_type") String extType, @RequestParam(value = "ext_name") String extName,
+			@RequestParam(value = "ext_picture") String extPicture
+			) {
+		String ip = Utility.getIp(request);
+		User user1 = userService.thirdPartLogin(openId, extType, extName, extPicture, ip);
+
+		if (Constants.USER_INACTIVE.equals(user1.getStatus_())) {
+			return Response.USER_FROZEN_ERROR;
+		}
+ // 这里不注册涂鸦,给涂鸦账号,密码
+		UserDTO userInfo = new UserDTO(user1.getId(), user1.getUsername(), user1.getPassword(), user1.getToken(), user1.getDisplay_name(),
+				user1.getDisplay_picture(), user1.getCreated_on(), user1.getExt_open_id(), user1.getExt_name(), user1.getExt_type(),
+				user1.getLocation(), user1.getBaby_nickname() == null? "寶寶" : user1.getBaby_nickname(), user1.getBaby_dob(), user1.getBaby_gender(), user1.getStatus_());
+		userInfo.setPassword(null);
+		userInfo.setCountry_code(user1.getCountry_code());
+		userInfo.setEncryptUsername(AES.encrypt(user1.getUsername()));
+		userInfo.setUserCode("iamberry123");
+		userInfo.setIs_perfect_user(user1.getIs_perfect_user() == null? 1 : user1.getIs_perfect_user());
+		
+		return Response.SUCCESS.setData(userInfo);
+	}
+
+	/**
+	 * getUserInfo
+	 * 获取用户基本信息
+	 * @param id 用户id
+	 * @token  用户token 登录的时候设置的唯一的token
+	 * @return Response 2100:无效token;2020:无效用户;1000:请求成功;
+	 */
+	@RequestMapping(value = "/get_user_info", method = RequestMethod.POST)
+	@ResponseBody
+	private Response getUserInfo(@RequestParam(value = "user_id", required = true) Long id,
+			@RequestParam("token") String token) {
+		User userInfo = userService.validateUserToken(token);
+		if (userInfo == null) {//token不存在,表示登录的时候没有..
+			return Response.INVALID_TOKEN;
+		}
+		User user = userService.findById(id);
+		if (user == null) { //未找到
+			return Response.INVALID_PARMS;
+		}
+		return Response.SUCCESS.setData(user, 1);
+	}
+
+	/**
+	 * updateProfile
+	 * 更新用户基本信息
+	 * @param user 用户信息
+	 * @param token token
+	 * @return Response 2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/update_profile", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateProfile(User user, @RequestParam("token") String token) {
+		User user1 = userService.updateUserInfo(user, token);
+		if (user1 == null) {
+			return Response.INVALID_TOKEN;
+		}
+//		userInfo.setEncryptUsername(AES.encrypt(user.getUsername()));
+//		userInfo.setUserCode("iamberry123");
+		
+		UserDTO userInfo = new UserDTO(user1.getId(), user1.getUsername(), user1.getPassword(), user1.getToken(), user1.getDisplay_name(),
+				user1.getDisplay_picture(), user1.getCreated_on(), user1.getExt_open_id(), user1.getExt_name(), user1.getExt_type(),
+				user1.getLocation(), user1.getBaby_nickname(), user1.getBaby_dob(), user1.getBaby_gender(), user1.getStatus_());
+		userInfo.setPassword(null);
+		userInfo.setCountry_code(user1.getCountry_code());
+		userInfo.setEncryptUsername(AES.encrypt(user1.getUsername()));
+		userInfo.setUserCode("iamberry123");
+		return Response.SUCCESS.setData(userInfo, 1);
+	}
+
+	private BASE64Decoder decoder = new BASE64Decoder();  
+	
+	/**
+	 * updateDisplayPicture
+	 * 更改用户头像
+	 * @param user 用户信息
+	 * @param token 唯一标识符
+	 * @return Response
+	 * @throws IOException 
+	 */
+	@RequestMapping(value = "/update_display_picture", method = RequestMethod.POST)
+	@ResponseBody
+	private Response updateDisplayPicture(@RequestParam("picture_base64") String pictureBase64,
+			@RequestParam("token") String token, HttpServletRequest request) throws IOException {
+		// 判断文件类型
+		byte [] b = new byte[28];
+		pictureBase64.getBytes(0, 27, b, 0);
+		String temp = new String(b);
+		try {
+			b = decoder.decodeBuffer(temp);
+		} catch (IOException e) {
+			logger.error("updateDisplayPicture:" + e.getMessage());
+			return Response.FAILURE;
+		}
+		String type = null;					// 文件类型
+		String fileHead = byte2hex(b);		// 文件头
+		fileHead = fileHead.toUpperCase();
+		type = getType(fileHead);
+		if (type == null) {
+			return Response.FAILURE;
+		}
+		// 获取保存地址
+		String savePath = request.getServletContext().getRealPath(saveRootPath);
+		StringBuilder tempDir = new StringBuilder(savePath);
+		Long ran = new Date().getTime();
+		tempDir.append(File.separator);
+		tempDir.append(ran);
+		tempDir.append(File.separator);
+		// 判断保存路径是否存在,如果不存在,那么创建
+		File file=new File(savePath);
+		if (!file.exists()) {
+			logger.info("updateDisplayPicture-exists");
+			file.mkdirs();
+		}
+		// 获取保存文件名称
+		StringBuilder saveName = new StringBuilder(TokenUtil.getToken());
+		saveName.append(".").append(type);
+		tempDir.append(saveName);
+		// 保存磁盘
+		String userHeadURL = null;
+		if (!generateImage(pictureBase64, tempDir.toString())) {
+			logger.error("updateDisplayPicture-generateImage saveFile Error");
+			return Response.FAILURE;
+		} else {
+			userHeadURL = domain + request.getContextPath() + saveRootPath + ran + "/" + saveName.toString();
+		}
+		// 保存
+		String path = userService.updateDisplayPicture(userHeadURL, token);
+		return Response.SUCCESS.setData(path, 1);
+	}
+	
+	private String getType(String fileHead) {
+		FileType [] fileTypes = FileType.values();
+		for (FileType fileType : fileTypes) {
+			if (fileHead.startsWith(fileType.getValue())) {
+				return fileType.getSuffix();
+			}
+		}
+		return null;
+	}
+	
+	private boolean generateImage(String imgStr, String imgFilePath) throws IOException {  
+		// Base64解码  
+		byte[] bytes = decoder.decodeBuffer(imgStr);
+		for (int i = 0; i < bytes.length; ++i) {  
+			if (bytes[i] < 0) {
+				// 调整异常数据  
+				bytes[i] += 256;  
+			}  
+		}  
+		// 生成图片 
+		File file = new File(imgFilePath);
+		FileUtils.writeByteArrayToFile(file, bytes);
+		return true;  
+	}
+
+	private String byte2hex(byte[] b) {
+       // 转成16进制字符串
+       String hs = "";
+       String tmp = "";
+       for (int n = 0; n < b.length; n++) {
+           //整数转成十六进制表示
+           tmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
+           if (tmp.length() == 1) {
+               hs = hs + "0" + tmp;
+           } else {
+               hs = hs + tmp;
+           }
+       }
+       tmp = null;
+       return hs;
+   }
+
+	/**
+	 * 此方法可以不再使用
+	 */
+	@RequestMapping(value = "/avator/{id}/{rand}", method = RequestMethod.GET)
+	@ResponseBody
+	@Deprecated
+	private void getDisplayPicture() {
+		String url = request.getRequestURI();
+		url = url.substring(0, url.lastIndexOf('/'));
+		String userID = url.substring(url.lastIndexOf('/') + 1);
+		String avator = userService.selectUserAvator(Long.valueOf(userID));
+		response.setContentType("image/jpg");
+		try {
+			OutputStream os = response.getOutputStream();
+			BASE64Decoder decoder = new BASE64Decoder();
+			byte[] decoderBytes = decoder.decodeBuffer(avator);
+			os.write(decoderBytes);
+			os.flush();
+			os.close();
+		} catch (Exception e) {
+			// TODO: handle exception
+		}
+	}
+
+	/**
+	 * changePassword
+	 * 修改手机密码
+	 * @param oldPassword 新密码
+	 * @param newPassword 旧密码
+	 * @param token token
+	 * @return Response 2101:验证码错误;2102:验证码超时;2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/change_password", method = RequestMethod.POST)
+	@ResponseBody
+	private Response changePassword(@RequestParam("old_password") String oldPassword,
+			@RequestParam("new_password") String newPassword, @RequestParam("token") String token) {
+		int status = userService.changePassword(oldPassword, newPassword, token);
+		if (status == -1) { //token错误
+			return Response.INVALID_TOKEN;
+		} else if (status == 0) { //密码错误
+			return Response.ERROR_OLDPASSWORD;
+		} else { 
+			return Response.SUCCESS.setData(null);
+		}
+	}
+
+	/**
+	 * changePhone
+	 * 修改手机号码
+	 * @author Moon Cheng, Yin
+	 * @param newPhone 新手机号
+	 * @param token token
+	 * @param verificationCode 手机验证码
+	 * @return2101:验证码错误;2102:验证码超时;2100:无效token;1000:请求成功;
+	 */
+	@RequestMapping(value = "/change_phone", method = RequestMethod.POST)
+	@ResponseBody
+	private Response changePhone(@RequestParam("new_phone") String newPhone,
+			@RequestParam("verification_code") String verificationCode, @RequestParam("token") String token) {
+		int status = checkVerifyCode(newPhone, verificationCode, 2);
+		User user = null;
+		if (status == -1) { //验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else if (status == 1) { 
+			user = userService.changePhone(newPhone, token);
+			if (user == null) {
+				return Response.INVALID_TOKEN;
+			}
+		}
+		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
+	}
+
+	/**
+	 * resetPassword
+	 * 重置手机密码
+	 * @param username 用户米
+	 * @param newPassword 新密码
+	 * @param verificationCode 验证码
+	 * @return2101:验证码错误;2102:验证码超时;2001:无效用户;2000:重置密码失败; 1000:请求成功;
+	 */
+	@RequestMapping(value = "/reset_password", method = RequestMethod.POST)
+	@ResponseBody
+	private Response resetPassword(@RequestParam(value = "username") String username,
+			@RequestParam("new_password") String newPassword,
+			@RequestParam("verification_code") String verificationCode) {
+		int status = checkVerifyCode(username, verificationCode, 3);
+		if (status == -1) {//验证码错误
+			return Response.ERROR_CODE;
+		} else if (status == -2) { //验证码超时
+			return Response.CODE_TIMEOUT;
+		} else if (status == 1) { 
+			status = userService.resetPassWord(username, newPassword);
+			if (status == -3) {//账号不存在
+				return Response.USER_NOT_EXIST; 
+			} else if (status == 0) {
+				return Response.FAILURE;
+			}
+		}
+
+		return Response.SUCCESS.setData(null);
+	}
+
+	/**
+	 * 发送手机验证码
+	 * @param phone 手机号 
+	 * @param statusCode  1代表注册,2代表更换手机号,3代表忘记密码
+	 * @return
+	 */
+	@RequestMapping(value = "/send_code", method = RequestMethod.GET)
+	@ResponseBody
+	private Response sendCode(@RequestParam("phone") String phone, @RequestParam("status_code") int statusCode,@RequestParam("areacode") String areacode) {
+		String code = null;
+		Map<String, Integer> status = new HashMap<>();
+		User user = new User();
+		try {
+			switch (statusCode) {
+			case 1:// register
+				user = userService.selectUserByUsername(phone);
+				if (user != null) {
+					return Response.ERROR_REGISTER;
+				}
+				
+				break;
+			case 2:// change phone
+				user = userService.selectUserByUsername(phone);
+				if (user != null) {
+					return Response.ERROR_REGISTER;
+				}
+
+				break;
+			case 3:// reset password
+				user = userService.selectUserByUsername(phone);
+				if (user == null) {
+					return Response.USER_NOT_EXIST;
+				}
+
+				break;
+			default:
+				break;
+			}
+			codeService.sendCode(areacode+","+phone, statusCode);
+			status.put("code", 0);
+		} catch (Exception e) {
+			System.out.println(e);
+			return Response.SERVER_INTERNAL_ERROR;
+		}
+		if (0 == status.get(Constants.SMS_RETURNCODE)) {
+			return Response.SUCCESS.setData(code, 0);
+		} else {
+			return Response.FAILURE.setHeader(new ResponseHeader(status.get(Constants.SMS_RETURNCODE), "", 0));
+		}
+	}
+
+	/**
+	 * 获取封面图片
+	 * @return json
+	 */
+	@RequestMapping(value = "/start_page", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getStartPage() {
+		String pageUrl = userService.getStartPage();
+		return Response.SUCCESS.setData(pageUrl, 1);
+	}
+
+	/**
+	 * 获取地址url
+	 * @return
+	 */
+	@RequestMapping(value = "/get_location", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getLocation() {
+		String IP = Utility.getIp(request);
+		 //String IP = "183.14.17.153";
+		RemoteIpInfoDTO remoteIpInfoDTO = userService.getLocation(IP);
+		return Response.SUCCESS.setData(remoteIpInfoDTO, 1);
+	}
+	
+	/**
+	 * 获取app版本号
+	 * @return
+	 */
+	@RequestMapping(value = "/get_version", method = RequestMethod.GET)
+	@ResponseBody
+	private Response getApkVersion() {
+		return Response.SUCCESS.setData(userService.getApkVersion());
+	}
+}

+ 37 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/model/FileModel.java

@@ -0,0 +1,37 @@
+package com.iamberry.app.international.model;
+
+import java.io.Serializable;
+
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @company	深圳爱贝源科技有限公司
+ * @website www.iamberry.com
+ * @author 	献
+ * @tel		18271840547
+ * @date	2016年9月22日
+ * @explain	上传文件model,只支持上传1张图片
+ */
+public class FileModel implements Serializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 7885284566024140520L;
+	private MultipartFile[] file;
+
+	
+	
+	
+	public FileModel() {
+		super();
+	}
+
+	public MultipartFile[] getFile() {
+		return file;
+	}
+
+	public void setFile(MultipartFile[] file) {
+		this.file = file;
+	}
+}

+ 22 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/model/FormatModel.java

@@ -0,0 +1,22 @@
+package com.iamberry.app.international.model;
+
+import java.util.Date;
+
+public class FormatModel {
+	private double money;
+	private Date date;
+	public double getMoney() {
+		return money;
+	}
+	public Date getDate() {
+		return date;
+	}
+	public void setDate(Date date) {
+		this.date = date;
+	}
+	public void setMoney(double money) {
+		this.money = money;
+	}
+	
+	
+}

+ 136 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/util/Jdpush.java

@@ -0,0 +1,136 @@
+package com.iamberry.app.international.util;
+
+
+import java.util.HashMap;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import cn.jpush.api.JPushClient;
+import cn.jpush.api.common.resp.APIConnectionException;
+import cn.jpush.api.common.resp.APIRequestException;
+import cn.jpush.api.push.PushResult;
+import cn.jpush.api.push.model.Options;
+import cn.jpush.api.push.model.Platform;
+import cn.jpush.api.push.model.PushPayload;
+import cn.jpush.api.push.model.PushPayload.Builder;
+import cn.jpush.api.push.model.audience.Audience;
+import cn.jpush.api.push.model.notification.AndroidNotification;
+import cn.jpush.api.push.model.notification.IosNotification;
+import cn.jpush.api.push.model.notification.Notification;
+
+import com.iamberry.app.core.dto.JpushMessageDTO;
+import com.iamberry.app.core.entity.Message;
+
+
+public class Jdpush {
+	
+	protected static final Logger LOG = LoggerFactory.getLogger(Jdpush.class);  
+    public static final String JpushAppkey ="4aed8013f682a80294510d00";
+    public static final String JpushSecret ="b7228c86effa5468c04983f5";
+    public static final boolean APNOPTION = true; 		//True 表示推送生产环境,False 表示要推送开发环境
+    public static final String PREFIX = "iamberry_"; 	//别名,前缀
+    
+    public static final HashMap<String, Platform> Platforms = new HashMap<String, Platform>(); //平台
+    public static final HashMap<Integer, String> allResultCode = new HashMap<Integer, String>(); //结果集
+
+    /*
+    platform	必填	推送平台设置
+    audience	必填	推送设备指定
+    notification	可选	通知内容体。是被推送到客户端的内容。与 message 一起二者必须有其一,可以二者并存
+    message	可选	消息内容体。是被推送到客户端的内容。与 notification 一起二者必须有其一,可以二者并存
+    sms_message	可选	短信渠道补充送达内容体
+    options	可选	推送参数
+    */
+    static{
+    	Platforms.put("all", Platform.all()); //all
+    	Platforms.put("android", Platform.android()); //android
+    	Platforms.put("ios", Platform.ios()); //ios
+    	
+    	allResultCode.put(200, "发送成功!");allResultCode.put(400, "错误的请求!");
+    	allResultCode.put(401, "未验证");allResultCode.put(403, "被拒绝");
+    	allResultCode.put(404, "无法找到");allResultCode.put(504, "代理超时");
+    }
+    
+    public static String SendPush(PushPayload payload) {  
+    	JPushClient jpushClient = new JPushClient(JpushSecret,JpushAppkey);   //推送客户端
+         //生成推送的内容,
+         PushResult result = null;
+        try {  
+            System.out.println(payload.toString()); 
+            result = jpushClient.sendPush(payload);  
+            LOG.info("Got result - " + result);  
+            LOG.info("Got result code " + result.getResponseCode());  
+           String responseString =  allResultCode.get(result.getResponseCode());
+           if(StringUtils.isNotBlank(responseString)){
+        	   return responseString;
+           }
+        } catch (APIConnectionException e) {  
+            LOG.error("Connection error. Should retry later. ", e);  
+        } catch (APIRequestException e) {  
+            LOG.error("Error response from JPush server. Should review and fix it. ", e);  
+            LOG.info("HTTP Status: " + e.getStatus());  
+            LOG.info("Error Code: " + e.getErrorCode());  
+            LOG.info("Error Message: " + e.getErrorMessage());  
+            LOG.info("Msg ID: " + e.getMsgId());  
+        }
+        return String.valueOf(result.getResponseCode());
+    }  
+      
+	/**
+	 *手动发送消息到-----> 某平台,某消息,某通知
+	 * @param jpushmessage 参数类
+	 * @return 消息封装类
+	 */
+	public static String sendmessage_jpushmessage(JpushMessageDTO jpushmessage) {  
+		PushPayload pushpayload =  PushPayload.newBuilder()  
+                .setPlatform(Platforms.get(jpushmessage.getPlatform()))  
+                .setAudience(Audience.alias(PREFIX+jpushmessage.getTag()))
+                .setNotification(Notification.alert(jpushmessage.getContent()) )//通知消息是 content
+                .setOptions(Options.newBuilder()  
+                .setApnsProduction(APNOPTION)  //True 表示推送生产环境,False 表示要推送开发环境
+                .build())  
+                .build();  
+        return SendPush(pushpayload);
+    }  
+	
+     /**
+      * 程序触发,手动触发
+      * 若别名存在-->则表示对某个人发送,不存在,则表示对所有人
+      * @return 调用结果
+      */
+    public static String buildPushObject_all_notifi(Message messsage) {  
+    	Builder builder = PushPayload.newBuilder(); //所有平台
+    	
+    	//备注中,all,ios,android,其他表示 all,
+    	if(Platforms.containsKey(messsage.getRemark())){
+    		builder.setPlatform(Platforms.get(messsage.getRemark()));
+    	}else{
+    		builder.setPlatform(Platform.all());
+    	}
+    	
+    	if(StringUtils.isNoneEmpty(Long.toString(messsage.getUser()))){
+    		builder.setAudience(Audience.alias(PREFIX+messsage.getUser()));   //某个别名
+    	}
+    	builder.setNotification(Notification.newBuilder()  
+                 .setAlert(messsage.getContent()) //通知消息是alert content
+                 .addPlatformNotification(AndroidNotification.newBuilder()
+                         .setTitle(messsage.getTitle())
+                         .addExtra("forword", messsage.getForword()) //是否在内部打开1内部2外部
+                         .addExtra("send_type", messsage.getSend_type())//推送的类型1文本 2url 3 内部页面
+                         .addExtra("url", messsage.getUrl())//消息URL
+                         .build()) 
+                 .addPlatformNotification(IosNotification.newBuilder()  
+                		 .addExtra("forword", messsage.getForword()) //是否在内部打开1内部2外部
+                         .addExtra("send_type", messsage.getSend_type())//推送的类型1文本 2url 3 内部页面
+                         .addExtra("url", messsage.getUrl())//消息URL
+                         .build())  
+                 .build());
+    	//设置是开发环境还是,生产环境
+    	builder.setOptions(Options.newBuilder()
+                .setApnsProduction(APNOPTION)
+                .build());
+        return  SendPush(builder.build());
+    }
+}

+ 70 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/util/TokenUtil.java

@@ -0,0 +1,70 @@
+package com.iamberry.app.international.util;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.UUID;
+
+/**
+ * @website www.ratfw.com
+ * @author 献
+ * @tel 18271840547
+ * @date 2016年8月30日
+ * @explain 生成安全随机的token工具类
+ */
+public class TokenUtil {
+	private static SecureRandom random = null;
+	static {
+		try {
+			random = SecureRandom.getInstance("SHA1PRNG");
+		} catch (NoSuchAlgorithmException e) {
+		}
+	}
+	/**
+	 * 创建一个安全的随机数组byte[]
+	 * 
+	 * @return
+	 */
+	private static byte[] createRandomByte() {
+		try {
+			byte[] bytes = new byte[1024 / 8];
+			random.nextBytes(bytes);
+			int count = 10;
+			byte[] seed = random.generateSeed(count);
+			random = SecureRandom.getInstance("SHA1PRNG");
+			random.setSeed(seed);
+			SecureRandom random2 = SecureRandom.getInstance("SHA1PRNG");
+			random2.setSeed(seed);
+			return seed;
+		} catch (Exception e) {
+			return UUID.randomUUID().toString().getBytes();
+		}
+	}
+
+	/**
+	 * byte[] 转 字符串
+	 * 
+	 * @param b
+	 * @return
+	 */
+	private static String byte2hex(byte[] b) {
+		String hs = "";
+		String stmp = "";
+		for (int n = 0; n < b.length; n++) {
+			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
+			if (stmp.length() == 1)
+				hs = hs + "0" + stmp;
+			else
+				hs = hs + stmp;
+		}
+		return hs.toUpperCase();
+	}
+
+	/**
+	 * 获取一个安全的token
+	 * 
+	 * @return
+	 */
+	public static String getToken() {
+		return byte2hex(createRandomByte());
+	}
+}

+ 389 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/util/Utility.java

@@ -0,0 +1,389 @@
+package com.iamberry.app.international.util;
+
+import static com.iamberry.app.config.ImberryConfig.SMS_PASSWORD;
+import static com.iamberry.app.config.ImberryConfig.SMS_TEXT;
+import static com.iamberry.app.config.ImberryConfig.SMS_URL;
+import static com.iamberry.app.config.ImberryConfig.SMS_USERNAME;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.text.MessageFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.apache.http.entity.mime.content.StringBody;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+
+import com.iamberry.app.config.Constants;
+import com.iamberry.app.core.dto.RecordDTO;
+import com.iamberry.app.tool.dto.AddressDTO;
+import com.iamberry.app.tool.util.HttpUtility;
+import com.iamberry.app.tool.util.JsonParseUtil;
+import com.iamberry.app.tool.util.Result;
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.StaxDriver;
+
+public class Utility {
+
+	public static String DATA_STORE = "";
+	private static final String AB = "123456789abcdefghijklmnpqrstuvwxyz";
+
+	private static Random rnd = new Random();
+
+	public static String getDateByDay() {
+		Calendar cal = Calendar.getInstance();
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(cal.get(Calendar.YEAR));
+		buffer.append(cal.get(Calendar.MONTH) + 1);
+		buffer.append(cal.get(Calendar.DAY_OF_MONTH));
+		return buffer.toString();
+	}
+
+	public static boolean contains(String[] array, String item) {
+		try {
+			for (int i = 0; i < array.length; i++) {
+				if (array[i].equals(item)) {
+					return true;
+				}
+			}
+		} catch (Exception ex) {
+
+		}
+		return false;
+	}
+
+	public static String normalizePath(String path) {
+		return path.replace("\\\\", "\\").replace("\\", "/").replace("//", "/").replace("..", ".");
+	}
+
+	public static String getRandomString(int len) {
+		StringBuilder sb = new StringBuilder(len);
+		for (int i = 0; i < len; i++)
+			sb.append(AB.charAt(rnd.nextInt(AB.length())));
+		return sb.toString();
+	}
+
+	public static int CalculateAge(Long date) {
+		Date birthDate = new Date(0);
+		if (date != null)
+			birthDate = new Date(date);
+		SimpleDateFormat format = new SimpleDateFormat("yyyy");
+		int birthYear = Integer.parseInt(format.format(birthDate));
+		int currentYear = Integer.parseInt(format.format(new Date(System.currentTimeMillis())));
+		int age = currentYear - birthYear;
+
+		return age;
+	}
+
+	public static List<RecordDTO> convertMap(List<Map<String, Object>> list, String dateType) {
+		List<RecordDTO> maps = new ArrayList<RecordDTO>();
+		try {
+			SimpleDateFormat sdf = null;
+			for (Map<String, Object> map : list) {
+				switch (dateType) {
+				case "days":
+					sdf = new SimpleDateFormat("yyyyMMddHH");
+					break;
+				case "weeks":
+					sdf = new SimpleDateFormat("yyyyMMdd");
+					break;
+				case "years":
+					sdf = new SimpleDateFormat("yyyyMM");
+					break;
+				}
+				Date key = sdf.parse(map.get(dateType).toString());
+				Double value = Double.parseDouble(map.get("volume").toString());
+				maps.add(new RecordDTO(key.getTime(), value));
+			}
+		} catch (Exception e) {
+		}
+		return maps;
+	}
+
+	public static Map<String, List<RecordDTO>> synAppMachineRecord(Map<String, List<RecordDTO>> oldMap) {
+		Map<String, List<RecordDTO>> synMap = oldMap;
+		int appSize = synMap.get("app").size();
+		int machineSize = synMap.get("machine").size();
+		int signer = 0;
+		long appDate = 0l, machineDate = 0l;
+		RecordDTO appRecord, machineRecord;
+		for (int i = 0; i < appSize && i < machineSize; i++) {
+			appRecord = synMap.get("app").get(i);
+			machineRecord = synMap.get("machine").get(signer);
+			appDate = appRecord.getRecordDate();
+			machineDate = machineRecord.getRecordDate();
+			if (appDate == machineDate) {
+				signer++;
+			} else if (appDate < machineDate) {
+				synMap.get("machine").add(i, new RecordDTO(appDate, 0));
+				machineSize++;
+				signer++;
+			} else {
+				synMap.get("app").add(signer, new RecordDTO(machineDate, 0));
+				appSize++;
+				signer++;
+			}
+		}
+		while (signer < machineSize) {
+			synMap.get("app").add(new RecordDTO(synMap.get("machine").get(signer).getRecordDate(), 0));
+			signer++;
+		}
+		while (signer < appSize) {
+			synMap.get("machine").add(new RecordDTO(synMap.get("app").get(signer).getRecordDate(), 0));
+			signer++;
+		}
+		return synMap;
+	}
+
+	public static Map<String, List<RecordDTO>> fillAppMachineRecordWithZero(Map<String, List<RecordDTO>> synedMap, String dataType,
+			String chosenDate) {
+		Map<String, List<RecordDTO>> fillMap = synedMap;
+		Calendar calendar = Calendar.getInstance();
+		List<Integer> existTimePoint = new ArrayList<Integer>();
+		long timePoint = 0l;
+		switch (dataType) {
+		case "days":
+			if (fillMap.get("app").isEmpty()) {
+				calendar.setTime(Utility.formatStringToDate("yyyy-MM-dd HH:mm:ss", chosenDate));
+			}
+//			fillMap.get("app").forEach(record -> {
+//				calendar.setTime(new Date(record.getRecordDate()));
+//				existTimePoint.add(calendar.get(Calendar.HOUR_OF_DAY));
+//			});
+			for(RecordDTO record : fillMap.get("app")){
+				calendar.setTime(new Date(record.getRecordDate()));
+				existTimePoint.add(calendar.get(Calendar.HOUR_OF_DAY));
+			}
+			for (int i = 0; i < 24; i++) {
+				if (!existTimePoint.remove(new Integer(i))) {
+					calendar.set(Calendar.HOUR_OF_DAY, i);
+					timePoint = calendar.getTimeInMillis();
+					fillMap.get("app").add(i, new RecordDTO(timePoint, 0));
+					fillMap.get("machine").add(i, new RecordDTO(timePoint, 0));
+				}
+			}
+			break;
+		case "weeks":
+			if (fillMap.get("app").isEmpty()) {
+				calendar.setTime(Utility.formatStringToDate("yyyy-MM-dd HH:mm:ss", chosenDate));
+			}
+			/*fillMap.get("app").forEach(record -> {
+				calendar.setTime(new Date(record.getRecordDate()));
+				existTimePoint.add(calendar.get(Calendar.DAY_OF_WEEK));
+			});*/
+			for(RecordDTO record : fillMap.get("app")){
+				calendar.setTime(new Date(record.getRecordDate()));
+				existTimePoint.add(calendar.get(Calendar.DAY_OF_WEEK));
+			}
+			if (existTimePoint.contains(new Integer(1))) {
+				calendar.add(Calendar.DATE, -7);
+			}
+			for (int i = 2; i <= 7; i++) {
+				if (!existTimePoint.remove(new Integer(i))) {
+					calendar.set(Calendar.DAY_OF_WEEK, i);
+					timePoint = calendar.getTimeInMillis();
+					fillMap.get("app").add(i - 2, new RecordDTO(timePoint, 0));
+					fillMap.get("machine").add(i - 2, new RecordDTO(timePoint, 0));
+				}
+			}
+			if (!existTimePoint.contains(new Integer(1))) {
+				calendar.add(Calendar.DATE, 7);
+				calendar.set(Calendar.DAY_OF_WEEK, 1);
+				timePoint = calendar.getTimeInMillis();
+				fillMap.get("app").add(new RecordDTO(timePoint, 0));
+				fillMap.get("machine").add(new RecordDTO(timePoint, 0));
+			}
+			break;
+		case "years":
+			if (fillMap.get("app").isEmpty()) {
+				calendar.setTime(Utility.formatStringToDate("yyyy-MM-dd HH:mm:ss", chosenDate));
+			}
+			/*fillMap.get("app").forEach(record -> {
+				calendar.setTime(new Date(record.getRecordDate()));
+				existTimePoint.add(calendar.get(Calendar.MONTH));
+			});*/
+			for(RecordDTO record : fillMap.get("app")){
+				calendar.setTime(new Date(record.getRecordDate()));
+				existTimePoint.add(calendar.get(Calendar.MONTH));
+			}
+			for (int i = 0; i <= 11; i++) {
+				if (!existTimePoint.remove(new Integer(i))) {
+					calendar.set(Calendar.MONTH, i);
+					timePoint = calendar.getTimeInMillis();
+					fillMap.get("app").add(i, new RecordDTO(timePoint, 0));
+					fillMap.get("machine").add(i, new RecordDTO(timePoint, 0));
+				}
+			}
+			break;
+		}
+		return fillMap;
+	}
+
+	public static String getRandomCode(int len) {
+		StringBuilder sb = new StringBuilder(len);
+		for (int i = 0; i < len; i++)
+			sb.append("0123456789".charAt(rnd.nextInt("0123456789".length())));
+		return sb.toString();
+	}
+
+	public static String getIp(HttpServletRequest request) {
+		String ip = request.getHeader("x-forwarded-for");
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getHeader("Proxy-Client-IP");
+		}
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getHeader("WL-Proxy-Client-IP");
+		}
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getRemoteAddr();
+		}
+		// 获取ip地址, 若多级代理,第一个IP为客户端真实IP,多个IP按照','分割
+		if (ip != null && ip.indexOf(",") != -1) {
+			ip = ip.split(",")[0];
+		}
+		return ip;
+	}
+
+	public static String CDN_WRITE_BASE_64_URL = "http://cms.iamberry.com/open-cdn/ssl/data/write/base64";
+
+	public static String uploadBase64File(String base64Data, String path) {
+		try {
+			if (base64Data != null) {
+				StringBody pic = new StringBody(base64Data, ContentType.DEFAULT_TEXT);
+				StringBody type = new StringBody("jpg", ContentType.TEXT_PLAIN);
+				HttpEntity entity = MultipartEntityBuilder.create().addPart("type", type).addPart("base64data", pic)
+						.build();
+				String result = HttpUtility.httpsPost(CDN_WRITE_BASE_64_URL, entity);
+
+//				JSONObject json = new JSONObject(result);
+//				int requestSatus = json.getJSONObject("header").getInt("status");
+//				if (1000 == requestSatus) {
+//					path = json.getJSONObject("data").get("url").toString();
+//				}
+
+				return path;
+			}
+		} catch (Exception e) {
+			return null;
+		}
+		return "";
+	}
+
+	public static String readFile(InputStream in) {
+		BufferedReader reader = null;
+		String result = "";
+		try {
+			InputStreamReader inputStreamReader = new InputStreamReader(in, "UTF-8");
+			reader = new BufferedReader(inputStreamReader);
+			String tempString = null;
+			while ((tempString = reader.readLine()) != null) {
+				result += tempString;
+			}
+			reader.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			if (reader != null) {
+				try {
+					reader.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		return result;
+	}
+
+	public static String sendCodeAsSMS(String phoneNum, Map<String, Integer> status) throws Exception {
+		String code = getRandomCode(4);
+		CloseableHttpClient client = HttpClients.createDefault();
+		Map<String, String> params = new HashMap<String, String>();
+		CloseableHttpResponse response = null;
+		params.put("username", SMS_USERNAME);
+		params.put("password", SMS_PASSWORD);
+		params.put("mobile", phoneNum);
+		params.put("content", MessageFormat.format(SMS_TEXT, code));
+		HttpPost method = new HttpPost(SMS_URL);
+		if (params != null) {
+			List<NameValuePair> paramList = new ArrayList<NameValuePair>();
+			for (Map.Entry<String, String> param : params.entrySet()) {
+				NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
+				paramList.add(pair);
+			}
+			method.setEntity(new UrlEncodedFormEntity(paramList, "UTF-8"));
+		}
+		response = client.execute(method);
+		HttpEntity entity = response.getEntity();
+		if (entity != null) {
+			String result = EntityUtils.toString(entity);
+			XStream xs = new XStream(new StaxDriver());
+			xs.alias("result", Result.class);
+			Result object = (Result)xs.fromXML(result);
+			response.close();
+			status.put(Constants.SMS_RETURNCODE, object.getResultcode());
+			if (0 == object.getResultcode()) {
+				return code;
+			}
+		}
+		return null;
+	}
+
+	public static AddressDTO getDefaultAddress(String jsonList) {
+		List<AddressDTO> addressDTOs = JsonParseUtil.parseAddressList(jsonList);
+		for (AddressDTO addressDTO : addressDTOs) {
+			if (addressDTO.getDefaultAddress() == 1) {
+				return addressDTO;
+			}
+		}
+		return null;
+	}
+
+	public static String getOrderSn(Long id) {
+		if (id == null)
+			throw new NullPointerException("id can not be null");
+
+		SimpleDateFormat format = new SimpleDateFormat("yyMMdd");
+		String date = format.format(new Date());
+		String sn = String.format("%0" + 5 + "d", id);
+		return "LTR" + date + sn;
+	}
+
+	public static String formatDateToString(String format, Date date) {
+		SimpleDateFormat sdf = new SimpleDateFormat(format);
+		return sdf.format(date);
+	}
+
+	public static Date formatStringToDate(String format, String dateStr) {
+		SimpleDateFormat sdf = new SimpleDateFormat(format);
+		Date date = null;
+		try {
+			date = sdf.parse(dateStr);
+		} catch (ParseException e) {
+			e.printStackTrace();
+			date = new Date();
+		}
+		return date;
+	}
+
+}

+ 24 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/util/kafka/AESBase64Util.java

@@ -0,0 +1,24 @@
+package com.iamberry.app.international.util.kafka;
+
+import java.security.Key;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.binary.StringUtils;
+
+public class AESBase64Util {
+
+	private static final String AES = "AES";
+
+	public static String decrypt(String encryptedData, String secretKey) throws Exception {
+		Key key = new SecretKeySpec(secretKey.getBytes(), AES);
+		Cipher c = Cipher.getInstance(AES);
+		c.init(2, key);
+		byte[] decodedValue = Base64.decodeBase64(encryptedData);
+		byte[] decValue = c.doFinal(decodedValue);
+		String decryptedValue = StringUtils.newStringUtf8(decValue);
+		return decryptedValue;
+	}
+}

+ 31 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/util/kafka/JsonDeserializer.java

@@ -0,0 +1,31 @@
+
+package com.iamberry.app.international.util.kafka;
+
+import java.util.Map;
+
+import org.apache.kafka.common.serialization.Deserializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.alibaba.fastjson.JSON;
+
+public class JsonDeserializer<T> implements Deserializer<T> {
+
+	protected static Logger logger = LoggerFactory.getLogger(JsonDeserializer.class);
+
+	public void configure(Map<String, ?> configs, boolean b) {
+	}
+
+	public T deserialize(String topic, byte[] data) {
+		try {
+			T result = (T) JSON.parse(data);
+			return result;
+		} catch (Exception e) {
+			logger.error("", e);
+			return null;
+		}
+	}
+
+	public void close() {
+	}
+}

+ 133 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/util/kafka/KafkaConsumer.java

@@ -0,0 +1,133 @@
+
+package com.iamberry.app.international.util.kafka;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.security.auth.login.Configuration;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+
+import org.apache.kafka.clients.CommonClientConfigs;
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.apache.kafka.clients.consumer.ConsumerRecords;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+import com.alibaba.fastjson.JSON;
+import com.iamberry.app.face.MachineService;
+import com.iamberry.app.face.MilkService;
+
+public class KafkaConsumer implements ServletContextListener {
+
+	private static final Logger logger = LoggerFactory.getLogger(KafkaConsumer.class);
+	
+	public void contextInitialized(ServletContextEvent sce) {
+		WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
+		MachineService machineService = webApplicationContext.getBean(MachineService.class);
+		MilkService milkService = webApplicationContext.getBean(MilkService.class);
+		
+		String appKey = "5kkyurvvtt58bbuxueee";//填APP KEY
+		String secretKey = "rhj6na6u3y6uhy6qrbb3944mg5uqqpbb";//APP SECRET
+		org.apache.kafka.clients.consumer.KafkaConsumer<String, String> consumer = null;
+		Configuration configuration = Configuration.getConfiguration();
+		Configuration.setConfiguration(null);
+		try {
+			java.security.Security.setProperty("login.configuration.provider", "com.iamberry.app.international.util.kafka.SaslConfiguration");
+
+			Properties props = new Properties();
+			//根据不同区域填写,不同区域URL参考文档  https://docs.tuya.com/cn/cloudapi/cloud_access/#kafka
+			props.put("bootstrap.servers", "kafka.cloud.tuyaus.com:8092");
+			String groupId = "aby-real-group";
+			props.put("group.id", groupId);
+
+			InetAddress netAddress = InetAddress.getLocalHost();
+			String clientId = "cloud_" + appKey + "_" + netAddress.getHostAddress();
+			props.put("client.id", clientId);
+			props.put("enable.auto.commit", "true");
+			props.put("auto.commit.interval.ms", "10000");
+			props.put("session.timeout.ms", "30000");
+			props.put("max.poll.records", 1000);
+			props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
+			//可以自定义JSON格式的序列化
+			props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
+
+			props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SASL_PLAINTEXT");
+			props.put("sasl.mechanism", "PLAIN");
+
+			consumer = new org.apache.kafka.clients.consumer.KafkaConsumer<String, String>(props);
+			consumer.subscribe(Arrays.asList("device-cloud-out-" + appKey));
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+		} finally {
+			Configuration.setConfiguration(configuration);
+		}
+		final org.apache.kafka.clients.consumer.KafkaConsumer<String, String> finalKafkaConsumer = consumer;
+		if (consumer != null) {
+			new Thread(){
+				@Override
+				public void run(){
+					while (true) {
+						ConsumerRecords<String, String> records = finalKafkaConsumer.poll(1000);
+						//ConsumerRecord<String, String> record = new ConsumerRecord<String, String>("4", 1, 1, "data", "JD/i7iF1hWmH08X54IGwjQkOy2gSEPTryEPUGbopFa3tC0lAyPx3dHN8enyKEY1zBdZt+bu5RYHnK00TvWD07S+Ryi3vHIGtWhTh7JLSVMAI+PNQeZZ87ZCh+vQaLQletGi/2n9B/pp+GLDDWFEhnl+xaLeVgcR9oGhUxBTwRmQsM1gUrTyEjFxfEhSWDM7Y+oj8NKWtJKpSS2/dv6wxNv+OIs6LCVBq+R1cLb+c0WI=");
+						boolean flog = false;
+						String milkPowder = "";
+						Long milkTime = 0l;
+						try {
+							for (ConsumerRecord<String, String> record : records) {
+								/*logger.info("Received message: (" + record.key() + ", " + record.value() + ") at offset "
+										+ record.offset() + ",decrypt data="
+										+ AESBase64Util.decrypt(JSONObject.fromObject(record.value()).getString("data"), secretKey.substring(8, 24)));
+							//	+ AESBase64Util.decrypt(record.value(), secretKey.substring(8, 24)));
+*/								String data = AESBase64Util.decrypt(JSONObject.fromObject(record.value()).getString("data"), secretKey.substring(8, 24));//解析后的真正数据
+								JSONObject jasonObject = JSONObject.fromObject(data);
+								if(jasonObject.has("dps")){
+									JSONArray dps = jasonObject.getJSONArray("dps");
+							        for(int i = 0; i < dps.size(); i++){
+							        	Map maps = (Map) JSON.parse(dps.getString(i));
+								        for (Object obj : maps.keySet()){
+								            if(obj.equals("DEVECE_CONTROL_MILK")){
+								            	milkPowder = maps.get(obj).toString();
+								            	flog = true;//如果数据中包含当前字段,表示当前推送的数据为奶粉记录
+								            }
+								            if(obj.equals("t")){
+								            	milkTime = (Long)maps.get((obj));
+								            }
+								        }
+							        }
+							        if(flog){
+							        	// 根据机器ID 获取对应的用户id
+							        	String devId = jasonObject.getString("devId");
+										Long userId = machineService.selectUserIDByDevId(devId);
+										milkService.addRecordData(devId, milkPowder, milkTime, userId);
+										flog = false;
+							        }
+								}
+						     }
+						} catch (Exception e) {
+							logger.error("", e);
+						}
+					}
+				}
+			}.start();;
+		}
+	}
+	@Override
+	public void contextDestroyed(ServletContextEvent sce) {
+		// TODO Auto-generated method stub
+		
+	}
+}

+ 27 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/util/kafka/SaslConfiguration.java

@@ -0,0 +1,27 @@
+
+package com.iamberry.app.international.util.kafka;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+
+import org.apache.commons.codec.digest.DigestUtils;
+
+public class SaslConfiguration extends Configuration {
+
+	public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
+		String appKey = "5kkyurvvtt58bbuxueee";//填APP KEY
+		String secretKey = "rhj6na6u3y6uhy6qrbb3944mg5uqqpbb";//APP SECRET
+		Map<String, String> options = new HashMap<String, String>();
+		options.put("username", appKey);//APP KEY
+		options.put("password", DigestUtils.md5Hex(appKey + DigestUtils.md5Hex(secretKey)).substring(8, 24));//MD5(APP KEY+MD5(云端APP SECRET))后,取中间16位
+		AppConfigurationEntry entry = new AppConfigurationEntry(
+				"org.apache.kafka.common.security.plain.PlainLoginModule",
+				AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
+		AppConfigurationEntry[] configurationEntries = new AppConfigurationEntry[1];
+		configurationEntries[0] = entry;
+		return configurationEntries;
+	}
+}

+ 225 - 0
iamberry-app-international/src/main/java/com/iamberry/app/international/util/languageUtil.java

@@ -0,0 +1,225 @@
+package com.iamberry.app.international.util;
+
+/*import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Properties;
+
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.util.DefaultPropertiesPersister;
+import org.springframework.util.PropertiesPersister;
+
+import com.iamberry.app.international.controller.GlobalController;
+
+*//**
+ * 国际化工具类
+ * @author Administrator
+ *
+ *//*
+public class languageUtil {
+	    
+	    public String getKey(String keyName, String language) {
+	    	init();
+	    	return properties.get(keyName + "-" + language).toString();
+	    }
+	    
+	    *//**
+		 * 载入多个properties文件, 相同的属性在最后载入的文件中的值将会覆盖之前的载入. 文件路径使用Spring Resource格式, 文件编码使用UTF-8.
+		 * @see org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
+		 *//*
+		public Properties loadProperties(String... resourcesPaths) throws IOException {
+			if (properties != null) {
+				return properties;
+			}
+			if (resourcesPaths == null) {
+				throw new NullPointerException("No resource path");
+			}
+			
+			Properties props = new Properties();
+			for (String location : resourcesPaths) {
+				InputStream is = null;
+				try {
+					Resource resource = resourceLoader.getResource(location);
+					is = resource.getInputStream();
+					propertiesPersister.load(props, new InputStreamReader(is, DEFAULT_ENCODING));
+				} catch (IOException ex) {
+				} finally {
+					if (is != null) {
+						is.close();
+					}
+				}
+			}
+			return props;
+		}
+		// 编码
+		private final String DEFAULT_ENCODING = "UTF-8";
+		// Spring-core 获取配置文件的类
+		private PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();	
+		// Spring-core 获取资源的类
+		private ResourceLoader resourceLoader = new PathMatchingResourcePatternResolver();
+		private Properties properties = null;
+		
+		public void init() {
+			if (properties == null) {
+				try {
+					synchronized (this) {
+						properties = loadProperties("messages_EN.properties,messages_HK.properties,messages_ZH.properties");
+					}
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				} 
+			}
+		}
+		
+		
+		 * 遍历获取国际化文件
+		 
+		private String type; // 后缀名
+	    public languageUtil(String type)
+	    {
+	        this.type = type;
+	    }
+	    public boolean accept(File dir, String name)
+	    {
+	        return name.endsWith(type);
+	    }
+	    static void filterfile(String dir, String suffix, ArrayList<String> fileList)
+	    {
+	        File f = new File(dir);
+	        File [] myList = f.listFiles();
+	        GlobalController filter = new GlobalController(suffix);
+	        String [] files = f.list(filter);
+	        fileList.addAll(Arrays.asList(files));
+	        for (File a : myList)
+	        {
+	            if (a.isDirectory())
+	            {
+	                    filterfile(a.toString(), suffix, fileList);
+	            } 
+	        }
+	    }
+	    
+	    public static void main(String[] args)
+	    {
+	        ArrayList<String> fileList = new ArrayList<String>();
+	        GlobalController.filterfile("src/main/resources", "properties", fileList);
+	        StringBuffer sb = null;
+	        for(String s:fileList)
+	        {
+	            System.out.println(s);
+	            sb.append(s);
+	        }
+	        System.out.println(sb);
+	    }
+}
+*/
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.util.DefaultPropertiesPersister;
+import org.springframework.util.PropertiesPersister;
+
+
+public class languageUtil {
+	
+	/**
+	 * 载入多个properties文件, 相同的属性在最后载入的文件中的值将会覆盖之前的载入. 文件路径使用Spring Resource格式, 文件编码使用UTF-8.
+	 * @see org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
+	 */
+	private synchronized static void loadProperties(String... resourcesPaths) throws IOException {
+		System.out.println("......");
+		if (resourceLoader == null) {
+			resourceLoader = new PathMatchingResourcePatternResolver();
+		}
+		if (propertiesPersister == null) {
+			propertiesPersister = new DefaultPropertiesPersister();
+		}
+		if (resourcesPaths == null) {
+			throw new NullPointerException("No resource path");
+		}
+		Properties props = null;
+		if (properties == null) {
+			props = new Properties();
+			properties = props;
+		} else {
+			props = properties;
+		}
+		for (String location : resourcesPaths) {
+			InputStream is = null;
+			try {
+				Resource resource = resourceLoader.getResource(location);
+				is = resource.getInputStream();
+				propertiesPersister.load(props, new InputStreamReader(is, DEFAULT_ENCODING));
+			} catch (IOException ex) {
+				ex.printStackTrace();
+			} finally {
+				if (is != null) {
+					is.close();
+				}
+			}
+		}
+	}
+	
+	/*public static void main(String[] args) {
+		System.out.println(get("username", "ZH"));
+		System.out.println(get("username", "EN"));
+		System.out.println(get("username", "ZH"));
+		System.out.println(get("username", "EN"));
+		System.out.println(get("username", "ZH"));
+		System.out.println(get("username", "EN"));
+		System.out.println(get("username", "ZH"));
+		System.out.println(get("username", "EN"));
+	}*/
+	
+	// 已经加载过的资源,为了高效,不使用锁
+	private static HashMap<String, String> loadeds = new HashMap<String, String>();
+	
+	/**
+	 * 根据一个key和语言获取对应的数据,并且保证系统延迟加载
+	 * @param key
+	 * @param language
+	 * @return
+	 * @throws IOException
+	 */
+	public static String get(String key, String language) {
+		// 判断是否已经加载过此资源文件
+		if (loadeds.get("messages_" + language) == null) {
+			// 防止多线程
+			synchronized (loadeds) {
+				// 防止重复加载资源
+				if (loadeds.get("messages_" + language) == null) {
+					try {
+						// 加载资源
+						loadProperties("messages_" + language + ".properties");
+						loadeds.put("messages_" + language, "messages_" + language + ".properties");
+					} catch (IOException e) {
+						// 如果失败,默认选择香港
+						return null;
+					}
+				}
+			}
+		}
+		return properties.get(key + "-" + language).toString();
+	}
+	private static Properties properties = null;
+	// 编码
+	private static final String DEFAULT_ENCODING = "UTF-8";
+	// Spring-core 获取配置文件的类
+	private static PropertiesPersister propertiesPersister = null;
+	// Spring-core 获取资源的类
+	private static ResourceLoader resourceLoader = null;
+}

+ 68 - 0
iamberry-app-international/src/main/resources/iamberry-app-api-datasource.xml

@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	   xmlns:aop="http://www.springframework.org/schema/aop"
+	   xmlns:context="http://www.springframework.org/schema/context"
+	   xmlns:tx="http://www.springframework.org/schema/tx"
+	   xmlns:p="http://www.springframework.org/schema/p"
+	   xsi:schemaLocation="http://www.springframework.org/schema/beans
+					http://www.springframework.org/schema/beans/spring-beans.xsd
+					http://www.springframework.org/schema/aop
+					http://www.springframework.org/schema/aop/spring-aop.xsd
+					http://www.springframework.org/schema/context
+					http://www.springframework.org/schema/context/spring-context.xsd
+					http://www.springframework.org/schema/tx
+					http://www.springframework.org/schema/tx/spring-tx.xsd">
+
+	<!-- 获取jdbc配置文件 -->
+	<context:property-placeholder location="classpath:jdbc.properties"/>
+
+    <!--app 前台配置库数据源-->
+    <bean id="ratfwDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
+        <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
+        <property name="driverClassName" value="${jdbc.driver}" />
+        <!-- 基本属性 url、user、password -->
+        <property name="url" value="${jdbc.url}" />
+        <property name="username" value="${jdbc.username}" />
+        <property name="password" value="${jdbc.password}" />
+        <!-- 配置初始化大小、最小、最大 -->
+        <property name="initialSize" value="${jdbc.pool.init}" />
+        <property name="minIdle" value="${jdbc.pool.minIdle}" />
+        <property name="maxActive" value="${jdbc.pool.maxActive}" />
+        <!-- 配置获取连接等待超时的时间 -->
+        <property name="maxWait" value="60000" />
+        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
+        <property name="timeBetweenEvictionRunsMillis" value="60000" />
+        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
+        <property name="minEvictableIdleTimeMillis" value="300000" />
+        <property name="validationQuery" value="${jdbc.testSql}" />
+        <property name="testWhileIdle" value="true" />
+        <property name="testOnBorrow" value="false" />
+        <property name="testOnReturn" value="false" />
+        <!-- 配置监控统计拦截的filters -->
+        <property name="filters" value="stat,wall" />
+    </bean>
+	
+	<!-- 自动扫描SQL隐射文件 -->
+	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
+		<!-- basePackage:指定SQL映射文件、接口的包,自动加载SQL映射文件和接口 -->
+		<property name="basePackage" value="com.iamberry.app.mapper"></property>
+		<!-- 引用SQLSessionFactoryBean -->
+		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
+	</bean>
+	
+	<!-- 配置SqlSessionFactoryBean -->
+	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
+		<!-- 配置数据源 -->
+		<property name="dataSource" ref="ratfwDataSource" />
+		<property name="configLocation" value="classpath:iamberry-app-service-mybatis.xml" />
+		<property name="mapperLocations" value="classpath:com/iamberry/app/mapper/*.xml" />
+	</bean>
+	
+	<!-- 基于mysql的事物管理,如果是大型项目不建议使用xml配置全部,而是应该使用@Transaction指定方法级别的事务控制 -->
+	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
+		<property name="dataSource" ref="ratfwDataSource" />
+	</bean>
+	<!-- 开启注解事务 -->
+	<tx:annotation-driven transaction-manager="transactionManager"/>
+</beans>

+ 64 - 0
iamberry-app-international/src/main/resources/iamberry-app-api-ioc.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+	xmlns:context="http://www.springframework.org/schema/context"
+	xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"
+	xmlns:cache="http://www.springframework.org/schema/cache"
+	xmlns:tx="http://www.springframework.org/schema/tx"
+	default-autowire="byName"
+	default-lazy-init="true"
+    xmlns:task="http://www.springframework.org/schema/task"
+	xmlns:aop="http://www.springframework.org/schema/aop"
+	xmlns:ehcache-spring="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"
+	xmlns:p="http://www.springframework.org/schema/p"
+	xmlns:websocket="http://www.springframework.org/schema/websocket" 
+	xsi:schemaLocation=
+		"http://www.springframework.org/schema/aop
+		http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
+		http://www.springframework.org/schema/beans
+		http://www.springframework.org/schema/beans/spring-beans.xsd
+		http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring
+		http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd
+		http://www.springframework.org/schema/cache
+		http://www.springframework.org/schema/cache/spring-cache-4.1.xsd
+		http://www.springframework.org/schema/tx 
+		http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
+		http://www.springframework.org/schema/task  
+		http://www.springframework.org/schema/task/spring-task-3.1.xsd  
+		http://www.springframework.org/schema/websocket 
+		http://www.springframework.org/schema/websocket/spring-websocket.xsd
+		http://www.springframework.org/schema/context
+		http://www.springframework.org/schema/context/spring-context-3.2.xsd">
+
+	<context:component-scan base-package="com.iamberry.app.international" />
+	
+	<!-- 配置自动扫描的包:不扫描控制器和异常处理 -->
+	<context:component-scan base-package="com.iamberry">
+		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
+		<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
+	</context:component-scan>
+	
+	<!-- 使用CGLIB动态代理 -->
+    <aop:aspectj-autoproxy proxy-target-class="true"/>
+
+	<!-- 开启这个配置,spring才能识别@Scheduled注解 -->
+	<task:annotation-driven/>
+
+ 	<!-- 配置数据库	-->
+    <import resource="classpath:iamberry-app-api-datasource.xml"/> 
+    
+    <!-- spring监控 -->
+    <bean id="druid-stat-interceptor" class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor">
+	</bean>
+	<bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut" scope="prototype">
+		<property name="patterns">
+			<list>
+				<value>com.iamberry.app.service.*</value>
+				<value>com.iamberry.app.mapper.*</value>
+			</list>
+		</property>
+	</bean>
+	<aop:config proxy-target-class="true">
+		<aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" />
+	</aop:config>
+</beans>

+ 116 - 0
iamberry-app-international/src/main/resources/iamberry-app-api-mvc.xml

@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
+	xmlns:mvc="http://www.springframework.org/schema/mvc"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
+		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
+	
+	<!-- 该异常是SpringMVC在检查上传的文件信息时抛出来的,而且此时还没有进入到Controller方法中   遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/views/msg/ploadToSize.jsp页面 -->  
+    <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
+        <property name="exceptionMappings">  
+            <props>  
+                <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">/msg/ploadToSize</prop>  
+            </props>  
+        </property>  
+    </bean>
+	<!-- 配置自定扫描的包,仅handler和Advice -->
+	<context:component-scan base-package="com.iamberry.app.international" use-default-filters="false">
+		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
+		<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
+	</context:component-scan>
+	
+	<!-- 配置freeMarker视图解析器 -->
+    <bean id="viewResolverFtl" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
+        <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>
+        <property name="contentType" value="text/html; charset=UTF-8"/>
+        <property name="exposeRequestAttributes" value="true" />
+        <property name="exposeSessionAttributes" value="true" />
+        <property name="exposeSpringMacroHelpers" value="true" />
+        <property name="requestContextAttribute" value="request"/>
+        <property name="cache" value="true" />
+        <property name="suffix" value=".ftl" />
+        <property name="order" value="0"/>
+    </bean>
+
+    <!-- 配置FREEMARKER的视图解析器 -->
+    <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
+        <property name="templateLoaderPath" value="/WEB-INF/views/"/>
+        <property name="freemarkerVariables">
+            <map>
+                <entry key="xml_escape" value-ref="fmXmlEscape" />
+            </map>
+        </property>
+        <property name="defaultEncoding" value="UTF-8"/>
+        <property name="freemarkerSettings">
+            <props>
+            	<!-- 指定更新模版文件的间隔时间,相当于多长时间检测一下是否有必要重新加载模版文件,0 表示每次都重新加载,否则为多少毫秒钟检测一下模版是否更改 -->
+                <prop key="template_update_delay">3600</prop>
+                <prop key="locale">zh_CN</prop>
+                <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
+                <prop key="date_format">yyyy-MM-dd</prop>
+                <prop key="number_format">#.##</prop>
+            </props>
+        </property>
+    </bean>
+    <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>
+    
+	<!-- 配置JSP视图解析器: 如何把 handler 方法返回值解析为实际的物理视图 -->
+	<bean id="viewResolverJsp" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
+        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
+        <property name="contentType" value="text/html; charset=UTF-8"/>
+		<property name="prefix" value="/WEB-INF/views/"></property>
+		<property name="suffix" value=".jsp"></property>
+        <property name="order" value="1"/> 
+	</bean>
+	
+	<!-- 解决静态资源,提供两种方法 -->
+	<mvc:default-servlet-handler/>
+	<mvc:resources location="/common/css/" mapping="/common/css/**" />
+	<mvc:resources location="/common/images/" mapping="/common/images/**" />
+	<mvc:resources location="/common/js/" mapping="/common/js/**" />
+	<mvc:resources location="/common/other/" mapping="/common/other/**" />
+
+	<!-- 解决配置mvc:default-servlet-handler后,前台handler方法失效问 -->
+	<mvc:annotation-driven></mvc:annotation-driven>
+	<!-- 配置MultipartResolver -->
+	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
+		<!-- 默认的编码 -->
+		<property name="defaultEncoding" value="UTF-8"></property>
+		<!-- 最大上传大小 -->
+		<property name="maxUploadSize" value="1024000000"></property>
+	</bean>
+	<!--避免IE执行AJAX时,返回JSON出现下载文件 -->  
+    <bean id="mappingJacksonHttpMessageConverter"  
+        class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">  
+        <property name="supportedMediaTypes">  
+            <list>  
+               <value>text/html; charset=UTF-8</value>  
+               <value>application/json;charset=UTF-8</value>  
+            </list>  
+        </property>  
+    </bean>
+    <bean  
+        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
+        <property name="messageConverters">  
+            <list>  
+                <ref bean="mappingJacksonHttpMessageConverter" />
+            </list>  
+        </property>  
+    </bean>
+    
+    <!-- 定义国际化消息-->   
+   <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">   
+     
+	     <!--   其中basename用来指定properties文件的通用名
+	              如实例中的messages_en.properties,messages_ja.properties通用名都是messages
+	      -->
+	     <property name="basename" value="messages"/>
+	     <property name="useCodeAsDefaultMessage" value="true" />
+	     
+	</bean>   
+    
+   <!-- 获取本地 -->  
+   <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/> 
+    
+</beans>

+ 17 - 0
iamberry-app-international/src/main/resources/iamberry-app-service-config.properties

@@ -0,0 +1,17 @@
+SMS_USERNAME=aibeiyuan
+SMS_PASSWORD=aibeiyuan632
+SMS_TEXT=\u3010\u6bd4\u6bd4\u840c\u3011\u60a8\u7684\u9a8c\u8bc1\u7801\u662f\uff1a{0}\uff0c\u5982\u975e\u672c\u4eba\u64cd\u4f5c\uff0c\u8bf7\u5ffd\u7565\u672c\u77ed\u4fe1
+SMS_URL=http://115.29.44.189:8080/sms/smsInterface.do
+SINA_IP_URL=http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip={0}
+APPID=wxe9e992877625202f
+MCH_ID=1316959401
+SECRET=ae12dfeca278d7e4f15047313d453733
+UNIFIED_ORDER_CALLBACK_URL=demo.tronsis.com
+master_secret=ffd6373d25f9e36ba6e9d7c3
+appkey=cef2f16aa36424f2a6d4ca60
+cdnUrl=http://cms.iamberry.com/cdn
+base_url=testtest
+INTER_SMS_URL=https://sms.yunpian.com/v2/sms/single_send.json
+INTER_SMS_TEXT=\u3010simfy\u3011\u60A8\u7684\u9A57\u8B49\u78BC\u662F\uFF1A{0}\uff0c3\u5206\u9418\u5167\u6709\u6548\u3002\u5982\u975e\u672c\u4eba\u64cd\u4f5c\uff0c\u8acb\u5ffd\u7565\u672c\u7c21\u8a0a\u3002
+INTER_SMS_KEY=415754e72ef318ecce825c8ecdd56fae
+\u3010\u7231\u8D1D\u6E90RST\u3011\u60A8\u67091\u4E2A\u5730\u63A8\u8BA2\u5355\u5F85\u53D1\u8D27\uFF0C\u8BF7\u53CA\u65F6\u5904\u7406\u3002

+ 34 - 0
iamberry-app-international/src/main/resources/iamberry-app-service-mybatis.xml

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
+<configuration>
+	<!-- 设置  -->
+	<settings>  
+        <!--set lazy fetching-->  
+        <setting name="lazyLoadingEnabled" value="false" />  
+        <setting name="logImpl" value="LOG4J"/>  
+		<setting name="mapUnderscoreToCamelCase" value="true" />
+		<!-- 允许使用列标签代替列名 -->  
+		<setting name="useColumnLabel" value="true" />  
+		<!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->  
+		<setting name="useGeneratedKeys" value="true" />  
+    </settings>
+    
+    <!-- 配置Entitys -->
+    <typeAliases>
+    	<typeAlias type="com.iamberry.app.core.entity.Machine" alias="Machine"/>
+    	<typeAlias type="com.iamberry.app.core.entity.Message" alias="Message"/>
+    	<typeAlias type="com.iamberry.app.core.entity.MilkImages" alias="MilkImages"/>
+    	<typeAlias type="com.iamberry.app.core.entity.MilkMakingRecord" alias="MilkMakingRecord"/>
+    	<typeAlias type="com.iamberry.app.core.entity.MilkPowderInfo" alias="MilkPowderInfo"/>
+    	<typeAlias type="com.iamberry.app.core.entity.SharedMachine" alias="SharedMachine"/>
+    	<typeAlias type="com.iamberry.app.core.entity.SysConfig" alias="SysConfig"/>
+    	<typeAlias type="com.iamberry.app.core.entity.SysLog" alias="SysLog"/>
+    	<typeAlias type="com.iamberry.app.core.entity.User" alias="User"/>
+    	<typeAlias type="com.iamberry.app.core.entity.UserAvator" alias="UserAvator"/>
+    	
+    	<typeAlias type="com.iamberry.wechat.core.entity.PageBean" alias="PageBean"/>
+    	<typeAlias type="com.iamberry.app.core.serch.SerchParam" alias="SerchParam"/>
+    	<typeAlias type="com.iamberry.app.core.entity.CodeValid" alias="CodeValid"/>
+    	
+    </typeAliases>
+</configuration>

+ 10 - 0
iamberry-app-international/src/main/resources/jdbc.properties

@@ -0,0 +1,10 @@
+jdbc.driver=com.mysql.jdbc.Driver
+jdbc.url=jdbc:mysql://192.168.1.254:3306/iamberry_app?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull
+jdbc.username=root
+jdbc.password=root
+#pool settings
+jdbc.pool.init=1
+jdbc.pool.minIdle=3
+jdbc.pool.maxActive=20
+#jdbc.testSql=SELECT 'x'
+jdbc.testSql=SELECT 'x' FROM DUAL

+ 42 - 0
iamberry-app-international/src/main/resources/log4j.properties

@@ -0,0 +1,42 @@
+#levels: debug, info, warn, error, fatal
+log4j.rootLogger=info,stdout,infoLog,errorLog,dbLog,console
+
+#\u63a7\u5236\u53f0
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %c %x - %m%n
+
+#\u4e3b\u65e5\u5fd7\u6587\u4ef6
+log4j.appender.infoLog=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.infoLog.File=D:/log/iamberry/app-international/iamberry_info.log
+log4j.appender.infoLog.Append=true
+log4j.appender.infoLog.Threshold=INFO
+log4j.appender.infoLog.layout=org.apache.log4j.PatternLayout
+log4j.appender.infoLog.layout.ConversionPattern=%d %p [%c] - %m %n 
+log4j.appender.infoLog.encoding=UTF-8
+
+#\u9519\u8bef\u65e5\u5fd7
+log4j.appender.errorLog=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.errorLog.File=D:/log/iamberry/app-international/iamberry_error.log
+log4j.appender.errorLog.Append=true
+log4j.appender.errorLog.Threshold=ERROR
+log4j.appender.errorLog.layout=org.apache.log4j.PatternLayout
+log4j.appender.errorLog.layout.ConversionPattern=%d %p [%c] - %m %n 
+log4j.appender.errorLog.encoding=UTF-8
+
+#debug\u4fe1\u606f
+log4j.appender.dbLog=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.dbLog.File=D:/log/iamberry/app-international/iamberry_debug.log
+log4j.appender.dbLog.Append=true
+log4j.appender.dbLog.Threshold=DEBUG
+log4j.appender.dbLog.layout=org.apache.log4j.PatternLayout
+log4j.appender.dbLog.layout.ConversionPattern=%d %p [%c] - %m %n 
+log4j.appender.dbLog.encoding=UTF-8
+
+#\u663e\u793aSQL\u8bed\u53e5\u90e8\u5206
+log4j.logger.com.iamberry.app=DEBUG
+log4j.logger.java.sql.ResultSet=INFO
+log4j.logger.java.sql.Connection=DEBUG
+log4j.logger.java.sql.Statement=DEBUG
+log4j.logger.java.sql.PreparedStatement=DEBUG

+ 1 - 0
iamberry-app-international/src/main/resources/messages_EN.properties

@@ -0,0 +1 @@
+username-EN=何秀刚ˆš

+ 2 - 0
iamberry-app-international/src/main/resources/messages_HK.properties

@@ -0,0 +1,2 @@
+username-HK=hexziugang
+

+ 1 - 0
iamberry-app-international/src/main/resources/messages_ZH.properties

@@ -0,0 +1 @@
+username-ZH=何秀剛

+ 0 - 0
iamberry-app-international/src/main/resources/schema.schemaxml


部分文件因文件數量過多而無法顯示