guozhaoshun 5 years ago
parent
commit
0248d4ca1d
100 changed files with 5476 additions and 0 deletions
  1. 109 0
      aid-api-web/pom.xml
  2. 18 0
      aid-api-web/src/main/java/cn/aid/apiweb/ApiWebApplication.java
  3. 175 0
      aid-api-web/src/main/java/cn/aid/apiweb/ApiWebMain.java
  4. 14 0
      aid-api-web/src/main/java/cn/aid/apiweb/assist/resolver/NeedUser.java
  5. 36 0
      aid-api-web/src/main/java/cn/aid/apiweb/assist/resolver/NeedUserResolver.java
  6. 14 0
      aid-api-web/src/main/java/cn/aid/apiweb/assist/resolver/RequestHeader.java
  7. 50 0
      aid-api-web/src/main/java/cn/aid/apiweb/assist/resolver/RequestHeaderResolver.java
  8. 25 0
      aid-api-web/src/main/java/cn/aid/apiweb/code/ApiWebCode.java
  9. 70 0
      aid-api-web/src/main/java/cn/aid/apiweb/configuration/FrontConfiguration.java
  10. 49 0
      aid-api-web/src/main/java/cn/aid/apiweb/configuration/GlobalExceptionHandler.java
  11. 130 0
      aid-api-web/src/main/java/cn/aid/apiweb/configuration/RedisCacheConfig.java
  12. 43 0
      aid-api-web/src/main/java/cn/aid/apiweb/controller/CallbackController.java
  13. 18 0
      aid-api-web/src/main/java/cn/aid/apiweb/controller/HeartBeatController.java
  14. 69 0
      aid-api-web/src/main/java/cn/aid/apiweb/controller/LoginController.java
  15. 37 0
      aid-api-web/src/main/java/cn/aid/apiweb/controller/UserController.java
  16. 23 0
      aid-api-web/src/main/java/cn/aid/apiweb/entity/GlobalHeader.java
  17. 141 0
      aid-api-web/src/main/java/cn/aid/apiweb/intercepter/RequestSignatureInterceptor.java
  18. 18 0
      aid-api-web/src/main/java/cn/aid/apiweb/service/auth/AuthClient.java
  19. 76 0
      aid-api-web/src/main/java/cn/aid/apiweb/service/auth/AuthService.java
  20. 19 0
      aid-api-web/src/main/java/cn/aid/apiweb/service/event/EventClient.java
  21. 22 0
      aid-api-web/src/main/java/cn/aid/apiweb/service/event/EventService.java
  22. 108 0
      aid-api-web/src/main/java/cn/aid/apiweb/service/user/UserClient.java
  23. 376 0
      aid-api-web/src/main/java/cn/aid/apiweb/service/user/UserService.java
  24. 103 0
      aid-api-web/src/main/java/cn/aid/apiweb/utils/DTOConverter.java
  25. 49 0
      aid-api-web/src/main/java/cn/aid/apiweb/utils/RequestHeaderManager.java
  26. 51 0
      aid-api-web/src/main/java/cn/aid/apiweb/utils/SecurityManager.java
  27. 15 0
      aid-api-web/src/main/resources/bootstrap.yml
  28. 16 0
      aid-api-web/src/test/java/cn/aid/apiweb/ApiWebApplicationTests.java
  29. 131 0
      aid-cms-web/pom.xml
  30. 21 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/CmsWebApplication.java
  31. 49 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/assist/aspect/OperationLogAspect.java
  32. 14 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/assist/resolver/NeedUser.java
  33. 34 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/assist/resolver/NeedUserResolver.java
  34. 29 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/code/CmsWebAPICode.java
  35. 60 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/configuration/CmsConfiguration.java
  36. 24 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/configuration/FeignConfiguration.java
  37. 49 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/configuration/GlobalExceptionHandler.java
  38. 130 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/configuration/RedisCacheConfig.java
  39. 287 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/configuration/SecurityConfig.java
  40. 22 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/controller/resource/AliOSSController.java
  41. 46 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/controller/resource/ResourceController.java
  42. 50 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/CampusController.java
  43. 49 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/CmsUserController.java
  44. 50 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/MerchantController.java
  45. 51 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/TerminalDeviceController.java
  46. 88 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/TerminalUserController.java
  47. 15 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/UserController.java
  48. 33 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/UserDeviceController.java
  49. 68 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/WhiteUserController.java
  50. 346 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/entity/UserDetails.java
  51. 45 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/security/CmsAuthenticationProvider.java
  52. 52 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/security/CmsUserDetailsService.java
  53. 129 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/security/JwtAuthenticationTokenFilter.java
  54. 130 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/security/JwtTokenService.java
  55. 35 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/service/resource/ResourceService.java
  56. 36 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/CampusService.java
  57. 32 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/CmsUserService.java
  58. 106 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/MerchantInfoSetService.java
  59. 34 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/MerchantService.java
  60. 14 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/TerminalDeviceService.java
  61. 47 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/TerminalUserService.java
  62. 14 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/UserDeviceService.java
  63. 29 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/WhiteUserService.java
  64. 10 0
      aid-cms-web/src/main/java/cn/aid/cmsweb/utils/DTOConverter.java
  65. 19 0
      aid-cms-web/src/main/resources/bootstrap.yml
  66. 16 0
      aid-cms-web/src/test/java/cn/aid/cmsweb/CmsWebApplicationTests.java
  67. 40 0
      aid-cms-web/src/test/java/cn/aid/cmsweb/service/product/proxy/WareServiceProxyTest.java
  68. 12 0
      aid-cms-web/src/test/java/cn/aid/cmsweb/service/trade/order/OrderClientTest.java
  69. 18 0
      aid-cms-web/src/test/java/cn/aid/cmsweb/service/user/CampusServiceTest.java
  70. 128 0
      aid-common-utils/pom.xml
  71. 43 0
      aid-common-utils/src/main/java/cn/aid/common/utils/Proxy/ProxyWrapper.java
  72. 52 0
      aid-common-utils/src/main/java/cn/aid/common/utils/api/Cache.java
  73. 32 0
      aid-common-utils/src/main/java/cn/aid/common/utils/api/annotation/SerializedField.java
  74. 22 0
      aid-common-utils/src/main/java/cn/aid/common/utils/api/controller/advice/GlobalExceptionHandler.java
  75. 64 0
      aid-common-utils/src/main/java/cn/aid/common/utils/api/model/APICode.java
  76. 95 0
      aid-common-utils/src/main/java/cn/aid/common/utils/api/model/APIResult.java
  77. 35 0
      aid-common-utils/src/main/java/cn/aid/common/utils/api/model/BaseCode.java
  78. 115 0
      aid-common-utils/src/main/java/cn/aid/common/utils/api/page/Page.java
  79. 20 0
      aid-common-utils/src/main/java/cn/aid/common/utils/api/page/Pageable.java
  80. 113 0
      aid-common-utils/src/main/java/cn/aid/common/utils/configuration/RedisConfiguration.java
  81. 41 0
      aid-common-utils/src/main/java/cn/aid/common/utils/constant/Constant.java
  82. 9 0
      aid-common-utils/src/main/java/cn/aid/common/utils/constant/Domain.java
  83. 10 0
      aid-common-utils/src/main/java/cn/aid/common/utils/constant/PlatForm.java
  84. 8 0
      aid-common-utils/src/main/java/cn/aid/common/utils/constant/RedisKey.java
  85. 14 0
      aid-common-utils/src/main/java/cn/aid/common/utils/constant/ResourceType.java
  86. 40 0
      aid-common-utils/src/main/java/cn/aid/common/utils/dto/resource/ResourceDTO.java
  87. 25 0
      aid-common-utils/src/main/java/cn/aid/common/utils/dto/resource/ResourceSearchDTO.java
  88. 25 0
      aid-common-utils/src/main/java/cn/aid/common/utils/dto/search/SearchDTO.java
  89. 22 0
      aid-common-utils/src/main/java/cn/aid/common/utils/enums/BaseOrderEnum.java
  90. 31 0
      aid-common-utils/src/main/java/cn/aid/common/utils/enums/BaseStatusEnum.java
  91. 20 0
      aid-common-utils/src/main/java/cn/aid/common/utils/enums/CourseSubTypeEnum.java
  92. 29 0
      aid-common-utils/src/main/java/cn/aid/common/utils/enums/EventTypeEnum.java
  93. 10 0
      aid-common-utils/src/main/java/cn/aid/common/utils/enums/GenderEnum.java
  94. 20 0
      aid-common-utils/src/main/java/cn/aid/common/utils/enums/LedgerTypeEnum.java
  95. 42 0
      aid-common-utils/src/main/java/cn/aid/common/utils/enums/PlatformTypeEnum.java
  96. 15 0
      aid-common-utils/src/main/java/cn/aid/common/utils/enums/ProductTypeEnum.java
  97. 20 0
      aid-common-utils/src/main/java/cn/aid/common/utils/enums/ReceiptTypeEnum.java
  98. 31 0
      aid-common-utils/src/main/java/cn/aid/common/utils/enums/WareTypeEnum.java
  99. 7 0
      aid-common-utils/src/main/java/cn/aid/common/utils/exception/CommonException.java
  100. 0 0
      aid-common-utils/src/main/java/cn/aid/common/utils/exception/DuplicateValueException.java

+ 109 - 0
aid-api-web/pom.xml

@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+    <groupId>cn.aid</groupId>
+	<artifactId>aid-api-web</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<packaging>jar</packaging>
+
+	<name>${project.artifactId}</name>
+	<description>Api Web For Spring Cloud</description>
+
+    <parent>
+        <groupId>cn.aid</groupId>
+        <artifactId>aid</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+		<java.version>1.8</java.version>
+		<spring-cloud.version>Dalston.SR4</spring-cloud.version>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-config</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-eureka</artifactId>
+		</dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-feign</artifactId>
+        </dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
+		</dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.7.0</version>
+        </dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+        <dependency>
+            <groupId>cn.aid</groupId>
+            <artifactId>aid-common-utils</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.aid</groupId>
+            <artifactId>aid-data-api</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
+
+        <dependency>
+        <groupId>eu.bitwalker</groupId>
+        <artifactId>UserAgentUtils</artifactId>
+        <version>1.21</version>
+         </dependency>
+	</dependencies>
+
+	<dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>org.springframework.cloud</groupId>
+				<artifactId>spring-cloud-dependencies</artifactId>
+				<version>${spring-cloud.version}</version>
+				<type>pom</type>
+				<scope>import</scope>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
+
+    <build>
+        <finalName>${project.name}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <outputDirectory>../target</outputDirectory>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>

+ 18 - 0
aid-api-web/src/main/java/cn/aid/apiweb/ApiWebApplication.java

@@ -0,0 +1,18 @@
+package cn.aid.apiweb;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.netflix.feign.EnableFeignClients;
+
+@EnableFeignClients
+@EnableDiscoveryClient
+@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
+public class ApiWebApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(ApiWebApplication.class, args);
+	}
+}

+ 175 - 0
aid-api-web/src/main/java/cn/aid/apiweb/ApiWebMain.java

@@ -0,0 +1,175 @@
+package cn.aid.apiweb;
+
+
+import eu.bitwalker.useragentutils.Browser;
+import eu.bitwalker.useragentutils.OperatingSystem;
+import eu.bitwalker.useragentutils.UserAgent;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ApiWebMain
+{
+
+    public static void main(String[] args)
+    {
+        try
+        {
+            System.out.print(getMac("47.95.197.36"));
+        }
+        catch (Exception ex)
+        {
+            ex.printStackTrace();
+        }
+    }
+
+    public static void userAgent()
+    {
+        String userAgentStr = "ser-agent=Mozilla/5.0 (Linux; Android 5.0.2; sdk_google_atv_x86 Build/LSY64) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile Safari/537.36";
+        UserAgent userAgent = UserAgent.parseUserAgentString(userAgentStr);
+        //获取浏览器对象
+        Browser browser = userAgent.getBrowser();
+        //获取操作系统对象
+        OperatingSystem operatingSystem = userAgent.getOperatingSystem();
+
+        //操作系统
+        String osName = operatingSystem.getName();
+        //操作系统设备类型
+        System.out.println("操作系统名:" + operatingSystem.getName());
+        System.out.println("访问设备类型:" + operatingSystem.getDeviceType());
+        System.out.println("操作系统家族:" + operatingSystem.getGroup());
+        System.out.println("操作系统生产厂商:" + operatingSystem.getManufacturer());
+
+        String eviceType = operatingSystem.getDeviceType().toString();
+
+        if ("MOBILE".equals(eviceType))
+        {
+            Pattern pattern = Pattern.compile(";\\s?(\\S*?\\s?\\S*?)\\s?(Build)?/");
+            Matcher matcher = pattern.matcher(userAgentStr);
+            String model = null;
+            if (matcher.find())
+            {
+                model = matcher.group(1).trim();
+                System.out.println("操作系统生产厂商:" + model);
+            }
+        }
+        else if ("WINDOWS".equals(eviceType))
+        {
+
+        }
+    }
+
+    /**
+     * 根据IP地址获取mac地址
+     *
+     * @param ipAddress 127.0.0.1
+     * @return
+     * @throws SocketException
+     * @throws UnknownHostException
+     */
+    public static String getLocalMac(String ipAddress) throws SocketException,
+            UnknownHostException
+    {
+        // TODO Auto-generated method stub
+        String str = "";
+        String macAddress = "";
+        final String LOOPBACK_ADDRESS = "127.0.0.1";
+        // 如果为127.0.0.1,则获取本地MAC地址。
+        if (LOOPBACK_ADDRESS.equals(ipAddress))
+        {
+            InetAddress inetAddress = InetAddress.getLocalHost();
+            // 貌似此方法需要JDK1.6。
+            byte[] mac = NetworkInterface.getByInetAddress(inetAddress)
+                    .getHardwareAddress();
+            // 下面代码是把mac地址拼装成String
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < mac.length; i++)
+            {
+                if (i != 0)
+                {
+                    sb.append("-");
+                }
+                // mac[i] & 0xFF 是为了把byte转化为正整数
+                String s = Integer.toHexString(mac[i] & 0xFF);
+                sb.append(s.length() == 1 ? 0 + s : s);
+            }
+            // 把字符串所有小写字母改为大写成为正规的mac地址并返回
+            macAddress = sb.toString().trim().toUpperCase();
+            return macAddress;
+        }
+        else
+        {
+            // 获取非本地IP的MAC地址
+            try
+            {
+                System.out.println(ipAddress);
+                Process p = Runtime.getRuntime().exec("nbtstat -A " + ipAddress);
+                System.out.println("===process==" + p);
+                InputStreamReader ir = new InputStreamReader(p.getInputStream());
+
+                BufferedReader br = new BufferedReader(ir);
+
+                while ((str = br.readLine()) != null)
+                {
+                    if (str.indexOf("MAC") > 1)
+                    {
+                        macAddress = str.substring(str.indexOf("MAC") + 9, str.length());
+                        macAddress = macAddress.trim();
+                        System.out.println("macAddress:" + macAddress);
+                        break;
+                    }
+                }
+                p.destroy();
+                br.close();
+                ir.close();
+            }
+            catch (IOException ex)
+            {
+                ex.printStackTrace();
+            }
+            return macAddress;
+        }
+    }
+
+
+        public static String getMac(String ip) throws IOException {
+            String mac = "not found!";
+            if (ip != null) {
+
+                try {
+                    Process process = Runtime.getRuntime().exec("arp "+ip);
+                    InputStreamReader ir = new InputStreamReader(process.getInputStream());
+                    LineNumberReader input = new LineNumberReader(ir);
+                    String line;
+                    StringBuffer s = new StringBuffer();
+                    while ((line = input.readLine()) != null) {
+                        s.append(line);
+
+                    }
+                    mac = s.toString();
+                    if (mac != null) {
+
+                        mac = mac.substring(mac.indexOf(":") - 2, mac.lastIndexOf(":") + 3);
+
+                    } else {
+                        mac = "not found!";
+                    }
+                    return mac;
+
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+            return mac;
+
+    }
+
+}

+ 14 - 0
aid-api-web/src/main/java/cn/aid/apiweb/assist/resolver/NeedUser.java

@@ -0,0 +1,14 @@
+package cn.aid.apiweb.assist.resolver;
+
+import java.lang.annotation.*;
+
+/**
+ * @author tomas
+ * @date 2017-04-17
+ * @what
+ */
+@Target({ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface NeedUser {
+}

+ 36 - 0
aid-api-web/src/main/java/cn/aid/apiweb/assist/resolver/NeedUserResolver.java

@@ -0,0 +1,36 @@
+package cn.aid.apiweb.assist.resolver;
+
+import cn.aid.data.api.app.vo.DeviceUserVo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.MethodParameter;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.support.WebDataBinderFactory;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.context.request.WebRequest;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.method.support.ModelAndViewContainer;
+
+/**
+ * @author Tomas
+ * @date 2016-07-17
+ * @what
+ */
+@Component
+public class NeedUserResolver implements HandlerMethodArgumentResolver {
+
+    private static final Logger logger = LoggerFactory.getLogger(NeedUserResolver.class);
+
+    public boolean supportsParameter(MethodParameter methodParameter) {
+        return  methodParameter.hasParameterAnnotation(NeedUser.class);
+    }
+
+    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
+        logger.info(String.format("Resolve argument %s.", methodParameter.getParameterName()));
+        if(methodParameter.hasParameterAnnotation(NeedUser.class)){
+            DeviceUserVo deviceUserVo = (DeviceUserVo) nativeWebRequest.getAttribute("aid_DEVICE_USER_INFO", WebRequest.SCOPE_REQUEST);
+            return deviceUserVo;
+        }
+        return null;
+    }
+}

+ 14 - 0
aid-api-web/src/main/java/cn/aid/apiweb/assist/resolver/RequestHeader.java

@@ -0,0 +1,14 @@
+package cn.aid.apiweb.assist.resolver;
+
+import java.lang.annotation.*;
+
+/**
+ * @author tomas
+ * @date 2017-04-17
+ * @what
+ */
+@Target({ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface RequestHeader {
+}

+ 50 - 0
aid-api-web/src/main/java/cn/aid/apiweb/assist/resolver/RequestHeaderResolver.java

@@ -0,0 +1,50 @@
+package cn.aid.apiweb.assist.resolver;
+
+import cn.aid.apiweb.entity.GlobalHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.MethodParameter;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.support.WebDataBinderFactory;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.method.support.ModelAndViewContainer;
+
+import java.util.Optional;
+
+/**
+ * @author Tomas
+ * @date 2016-07-17
+ * @what
+ */
+@Component
+public class RequestHeaderResolver implements HandlerMethodArgumentResolver {
+    private static final Logger logger = LoggerFactory.getLogger(RequestHeaderResolver.class);
+    public boolean supportsParameter(MethodParameter methodParameter) {
+        return  methodParameter.hasParameterAnnotation(RequestHeader.class);
+    }
+
+    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
+        logger.info(String.format("Resolve argument %s.", methodParameter.getParameterName()));
+        if(methodParameter.hasParameterAnnotation(RequestHeader.class)){
+            GlobalHeader globalHeader = new GlobalHeader();
+            globalHeader.setUid(nativeWebRequest.getHeader("uid"));
+            globalHeader.setEid(nativeWebRequest.getHeader("eid"));
+            globalHeader.setRequestId(nativeWebRequest.getHeader("requestId"));
+            globalHeader.setTerminal(nativeWebRequest.getHeader("terminal"));
+
+            //To be compatible with 2.x app version, if sign not exist, use Authenciation
+            String sign = nativeWebRequest.getHeader("sign");
+            if (null != sign && !sign.isEmpty()){
+                globalHeader.setSign(sign);
+            }
+            else{
+                globalHeader.setSign(Optional.ofNullable(nativeWebRequest.getHeader("Authentication")).orElse(""));
+            }
+
+            return globalHeader;
+        }
+        return null;
+    }
+
+}

+ 25 - 0
aid-api-web/src/main/java/cn/aid/apiweb/code/ApiWebCode.java

@@ -0,0 +1,25 @@
+package cn.aid.apiweb.code;
+
+import cn.aid.common.utils.api.model.APICode;
+import cn.aid.common.utils.api.model.BaseCode;
+
+public class ApiWebCode extends APICode {
+
+    public static final int _DEVICE_BOUND_ERROR = 30001;
+    public static final BaseCode DEVICE_BOUND_ERROR = new BaseCode(_DEVICE_BOUND_ERROR, "绑定终端失败");
+
+    public static final int _C_LOGIN_ERROR = 31001;
+    public static final BaseCode LOGIN_ERROR = new BaseCode(_C_LOGIN_ERROR, "登录失败");
+
+    public static final int _C_PASSWORD_ERROR = 31002;
+    public static final BaseCode PASSWORD_ERROR = new BaseCode(_C_PASSWORD_ERROR, "密码错误");
+
+    public static final int _C_TOKEN_EXPIRE = 31003;
+    public static final BaseCode TOKEN_EXPIRE = new BaseCode(_C_TOKEN_EXPIRE, "token过期");
+
+    public static final int _C_LOGOUT_ERROR = 31004;
+    public static final BaseCode LOGOUT_ERROR = new BaseCode(_C_LOGOUT_ERROR, "退出失败");
+
+    public static final int _C_HEADER_ERROR = 32001;
+    public static final BaseCode HEADER_ERROR = new BaseCode(_C_HEADER_ERROR, "请求头错误");
+}

+ 70 - 0
aid-api-web/src/main/java/cn/aid/apiweb/configuration/FrontConfiguration.java

@@ -0,0 +1,70 @@
+package cn.aid.apiweb.configuration;
+
+import cn.aid.apiweb.assist.resolver.NeedUserResolver;
+import cn.aid.apiweb.assist.resolver.RequestHeaderResolver;
+import cn.aid.apiweb.intercepter.RequestSignatureInterceptor;
+import cn.aid.common.utils.web.intercepter.HeaderProcessIntercepter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+import java.util.List;
+
+/**
+ * 类名:WebConfiguration  <br />
+ *
+ * 功能:Web相关配置
+ *
+ * @author tomas <br />
+ * 创建时间:2016年7月27日 下午3:57:19  <br />
+ * @version 2016年7月27日*/
+@Configuration
+@EnableWebMvc
+public class FrontConfiguration extends WebMvcConfigurerAdapter implements EnvironmentAware {
+	// 日志记录器
+	private static final Logger logger = LoggerFactory.getLogger(FrontConfiguration.class);
+
+	@Autowired
+	private RequestSignatureInterceptor requestSignatureInterceptor;
+
+	// 当前的环境对象
+	protected Environment environment;
+
+
+	public void addInterceptors(InterceptorRegistry registry) {
+		registry.addInterceptor(new HeaderProcessIntercepter());
+		registry.addInterceptor(requestSignatureInterceptor).excludePathPatterns("*/favicon.ico");
+	}
+
+	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
+		argumentResolvers.add(new RequestHeaderResolver());
+		argumentResolvers.add(new NeedUserResolver());
+		super.addArgumentResolvers(argumentResolvers);
+	}
+
+	public void addResourceHandlers(ResourceHandlerRegistry registry) {
+		registry.addResourceHandler("swagger-ui.html")
+				.addResourceLocations("classpath:/META-INF/resources/");
+		registry.addResourceHandler("favicon.ico")
+				.addResourceLocations("classpath:/static/favicon.ico");
+		registry.addResourceHandler("/webjars/**")
+				.addResourceLocations("classpath:/META-INF/resources/webjars/");
+	}
+	/**
+	 * Set the {@code Environment} that this object runs in.
+	 *
+	 * @param environment
+	 */
+	@Override
+	public void setEnvironment(Environment environment) {
+		this.environment = environment;
+	}
+}

+ 49 - 0
aid-api-web/src/main/java/cn/aid/apiweb/configuration/GlobalExceptionHandler.java

@@ -0,0 +1,49 @@
+package cn.aid.apiweb.configuration;
+
+import cn.aid.common.utils.api.model.APICode;
+import cn.aid.common.utils.api.model.APIResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
+import org.springframework.web.servlet.NoHandlerFoundException;
+
+import javax.servlet.http.HttpServletRequest;
+import java.nio.file.AccessDeniedException;
+
+@RestController
+@ControllerAdvice
+public class GlobalExceptionHandler {
+    private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
+
+    /**
+     * 系统异常处理,比如:404,500
+     * @param request
+     * @param e
+     * @return
+     * @throws Exception
+     */
+    @ExceptionHandler(value = Exception.class)
+    @ResponseBody
+    public APIResult defaultErrorHandler(HttpServletRequest request, Exception e) throws Exception {
+        logger.error("{}", e);
+
+        APIResult apiResult = new APIResult();
+        apiResult.setMessage(e.getMessage());
+        apiResult.setSuccess(false);
+
+        if (e instanceof NoHandlerFoundException) {
+            apiResult.setCode(APICode._C_NOT_FOUND);
+        }else if (e instanceof AccessDeniedException){
+            apiResult.setCode(APICode._C_ACCESS_DENIED);
+        }else if (e instanceof MethodArgumentTypeMismatchException){
+            apiResult.setCode(400);
+        }else {
+            apiResult.setCode(500);
+        }
+        return apiResult;
+    }
+}

+ 130 - 0
aid-api-web/src/main/java/cn/aid/apiweb/configuration/RedisCacheConfig.java

@@ -0,0 +1,130 @@
+package cn.aid.apiweb.configuration;
+
+import cn.aid.common.utils.service.RedisService;
+import cn.aid.common.utils.service.impl.RedisServiceImpl;
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.interceptor.KeyGenerator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import java.lang.reflect.Method;
+
+@Configuration
+@EnableCaching //加上这个注解是的支持缓存注解
+public class RedisCacheConfig extends CachingConfigurerSupport {
+
+    @Value("${spring.redis.host}")
+    private String host;
+
+    @Value("${spring.redis.port}")
+    private int port;
+
+    @Value("${spring.redis.timeout}")
+    private int timeout;
+
+    @Value("${spring.redis.password}")
+    private String password;
+
+
+    /**
+     * 连接redis的工厂类
+     *
+     * @return
+     */
+    @Bean
+    public JedisConnectionFactory jedisConnectionFactory() {
+        JedisConnectionFactory factory = new JedisConnectionFactory();
+        factory.setHostName(host);
+        factory.setPort(port);
+        factory.setTimeout(timeout);
+        factory.setPassword(password);
+        return factory;
+    }
+
+    /**
+     * 配置RedisTemplate
+     * 设置添加序列化器
+     * key 使用string序列化器
+     * value 使用Json序列化器
+     * 还有一种简答的设置方式,改变defaultSerializer对象的实现。
+     *
+     * @return
+     */
+    @Bean(name = "redisTemplate")
+    public RedisTemplate<Object, Object> redisTemplate() {
+        //StringRedisTemplate的构造方法中默认设置了stringSerializer
+        RedisTemplate<Object, Object> template = new RedisTemplate<>();
+        //设置开启事务
+        template.setEnableTransactionSupport(true);
+        //set key serializer
+        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+        template.setKeySerializer(stringRedisSerializer);
+        template.setHashKeySerializer(stringRedisSerializer);
+        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
+
+        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
+
+        //set value serializer
+//        template.setDefaultSerializer(jackson2JsonRedisSerializer);
+        template.setValueSerializer(jackson2JsonRedisSerializer);
+        template.setHashValueSerializer(jackson2JsonRedisSerializer);
+
+        template.setConnectionFactory(jedisConnectionFactory());
+        template.afterPropertiesSet();
+        return template;
+    }
+
+    /**
+     * 设置RedisCacheManager
+     * 使用cache注解管理redis缓存
+     *
+     * @return
+     */
+    @Bean
+    public RedisCacheManager cacheManager() {
+        RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate());
+        return redisCacheManager;
+    }
+
+    @Bean
+    public RedisService redisService() {
+        RedisServiceImpl redisService = new RedisServiceImpl();
+        redisService.setRedisTemplate(this.redisTemplate());
+        return redisService;
+    }
+
+    /**
+     * 自定义生成redis-key
+     *
+     * @return
+     */
+    @Override
+    public KeyGenerator keyGenerator() {
+        return new KeyGenerator() {
+            @Override
+            public Object generate(Object o, Method method, Object... objects) {
+                StringBuilder sb = new StringBuilder();
+                sb.append(o.getClass().getName()).append(".");
+                sb.append(method.getName()).append(".");
+                for (Object obj : objects) {
+                    sb.append(obj.toString());
+                }
+                System.out.println("keyGenerator=" + sb.toString());
+                return sb.toString();
+            }
+        };
+    }
+}

+ 43 - 0
aid-api-web/src/main/java/cn/aid/apiweb/controller/CallbackController.java

@@ -0,0 +1,43 @@
+package cn.aid.apiweb.controller;
+
+import cn.aid.apiweb.assist.resolver.NeedUser;
+import cn.aid.apiweb.code.ApiWebCode;
+import cn.aid.apiweb.service.event.EventService;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.data.api.app.vo.DeviceUserVo;
+import cn.aid.data.api.user.dto.EventLogDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+
+
+/**
+ * CallbackController
+ * Created by huodongdong on 2017/10/27.
+ */
+@Slf4j
+@RestController
+@RequestMapping(value = "/callback")
+public class CallbackController {
+
+    @Autowired
+    private EventService eventService;
+
+
+
+    @RequestMapping(value = "/event", method = RequestMethod.POST)
+    public APIResult<Boolean> addEvent(@NeedUser DeviceUserVo user, @RequestBody EventLogDTO eventLog) {
+        if (eventLog.getEventType() == null ) {
+            return APIResult.error(ApiWebCode.PARAMETER_ERROR);
+        }
+
+        eventLog.setMerchantId(user.getMerchantId());
+        eventLog.setUserId(user.getUid());
+
+        APIResult<Boolean> result = eventService.addLog(eventLog);
+        return result;
+    }
+
+}
+

+ 18 - 0
aid-api-web/src/main/java/cn/aid/apiweb/controller/HeartBeatController.java

@@ -0,0 +1,18 @@
+package cn.aid.apiweb.controller;
+
+
+import cn.aid.common.utils.api.model.APIResult;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HeartBeatController {
+
+    @RequestMapping(value = "/heartBeat", method = RequestMethod.GET)
+    public APIResult get(){
+        APIResult result = APIResult.ok();
+        result.setMessage("Beng Beng...");
+        return result;
+    }
+}

+ 69 - 0
aid-api-web/src/main/java/cn/aid/apiweb/controller/LoginController.java

@@ -0,0 +1,69 @@
+package cn.aid.apiweb.controller;
+
+import cn.aid.apiweb.assist.resolver.RequestHeader;
+import cn.aid.apiweb.entity.GlobalHeader;
+import cn.aid.apiweb.service.user.UserService;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.util.HttpUtil;
+import cn.aid.data.api.app.dto.DeviceLoginDTO;
+import cn.aid.data.api.app.dto.LoginInfoDTO;
+import cn.aid.data.api.app.vo.UserInfoVo;
+import eu.bitwalker.useragentutils.Browser;
+import eu.bitwalker.useragentutils.OperatingSystem;
+import eu.bitwalker.useragentutils.UserAgent;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Slf4j
+@RestController
+@RequestMapping(value = "/token")
+public class LoginController
+{
+
+    @Autowired
+    private UserService userService;
+
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<UserInfoVo> login(HttpServletRequest request, @Valid @RequestBody LoginInfoDTO loginInfoDTO)
+    {
+
+        String terminal = request.getHeader("terminal");
+        String merchant = request.getHeader("merchant");
+        String userAgent = request.getHeader("User-Agent");
+
+        String ip = HttpUtil.getClientIp(request);
+        loginInfoDTO.setIp(ip);
+        loginInfoDTO.setTerminal(terminal);
+        loginInfoDTO.setMerchant(merchant);
+
+        log.info("login request header : ip={},terminal={},merchant={},user-agent={}", ip, terminal, merchant);
+        return userService.login(loginInfoDTO);
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<UserInfoVo> refresh(HttpServletRequest request, @RequestBody DeviceLoginDTO deviceLoginDTO)
+    {
+        String deviceCode = deviceLoginDTO.getDeviceCode();
+        String merchant = request.getHeader("merchant");
+        log.info("refresh request header : deviceCode={}, merchant={}", deviceCode, merchant);
+        return userService.refresh(deviceCode, merchant, Boolean.TRUE);
+    }
+
+    @RequestMapping(method = RequestMethod.DELETE)
+    public APIResult<Boolean> logout(@RequestHeader GlobalHeader globalHeader)
+    {
+        String userId = globalHeader.getUid();
+        return userService.logout(userId);
+    }
+
+
+}

+ 37 - 0
aid-api-web/src/main/java/cn/aid/apiweb/controller/UserController.java

@@ -0,0 +1,37 @@
+package cn.aid.apiweb.controller;
+
+import cn.aid.apiweb.assist.resolver.NeedUser;
+import cn.aid.apiweb.code.ApiWebCode;
+import cn.aid.apiweb.service.product.ProductService;
+import cn.aid.apiweb.service.user.UserService;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.data.api.app.vo.DeviceUserVo;
+import cn.aid.data.api.app.vo.UserInfoVo;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+
+@RestController
+@RequestMapping(value = "/user")
+@Slf4j
+public class UserController {
+
+    @Autowired
+    private UserService userService;
+
+    @RequestMapping(method = RequestMethod.GET)
+    public APIResult<UserInfoVo> getUserInfo(@NeedUser DeviceUserVo deviceUserVo) {
+        String uid = deviceUserVo.getUid();
+        if (StringUtils.isEmpty(uid)) {
+            return APIResult.error(ApiWebCode.NOT_EXISTS);
+        }
+
+        UserInfoVo userInfoVo = userService.getUserInfo(uid);
+        return APIResult.ok(userInfoVo);
+    }
+
+}

+ 23 - 0
aid-api-web/src/main/java/cn/aid/apiweb/entity/GlobalHeader.java

@@ -0,0 +1,23 @@
+package cn.aid.apiweb.entity;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.io.Serializable;
+
+@Data
+@ToString
+public class GlobalHeader implements Serializable {
+
+    private String uid;
+
+    private String merchant;
+
+    private String eid;
+
+    private String sign;
+
+    private String requestId;
+
+    private String terminal;
+}

+ 141 - 0
aid-api-web/src/main/java/cn/aid/apiweb/intercepter/RequestSignatureInterceptor.java

@@ -0,0 +1,141 @@
+package cn.aid.apiweb.intercepter;
+
+import cn.aid.apiweb.code.ApiWebCode;
+import cn.aid.apiweb.entity.GlobalHeader;
+import cn.aid.apiweb.service.user.UserService;
+import cn.aid.apiweb.utils.RequestHeaderManager;
+import cn.aid.apiweb.utils.SecurityManager;
+import cn.aid.common.utils.constant.RedisKey;
+import cn.aid.common.utils.util.HttpUtil;
+import cn.aid.data.api.app.vo.DeviceUserVo;
+import com.alibaba.fastjson.JSON;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.NamedThreadLocal;
+import org.springframework.http.HttpMethod;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Component
+public class RequestSignatureInterceptor implements HandlerInterceptor {
+
+    private static final Logger logger = LoggerFactory.getLogger(RequestSignatureInterceptor.class);
+
+    private static final String LOGIN_TOKEN_FORMAT_KEY = RedisKey.LOGIN_TOKEN_FORMAT_KEY;
+
+    private static final String ERROR_LOGIN_HEADER = "NO_LOGIN_SIGN";
+
+    private NamedThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<Long>("StopWatch-StartTime");
+
+    // 忽略options请求,默认为true
+    private boolean ignoreOptions = true;
+
+//    @Value("${'${request.header.ignore_path}'.split(',')}")
+    private static List<String> ignorePaths = new ArrayList<>();
+
+    static {
+        ignorePaths.add("/token");
+    }
+
+    @Autowired
+    private UserService userService;
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        //判断 OPTIONS 请求
+        if (ignoreOptions && HttpMethod.OPTIONS.matches(request.getMethod())) {
+            logger.info("OPTIONS 请求 忽略 返回200");
+            request.setAttribute("NO_LOGIN_SIGN", "OPTIONS");
+            writeResponse(request, response, ApiWebCode.OK);
+            return false;
+        }
+
+        //记录开始时间
+        startTimeThreadLocal.set(System.currentTimeMillis());//线程绑定变量(该数据只有当前请求的线程可见)
+
+
+        //登录请求不拦截
+        String path = request.getServletPath();
+
+        if (ignorePaths.contains(path) && (HttpMethod.POST.matches(request.getMethod()) ||
+                HttpMethod.PUT.matches(request.getMethod()))) {
+            logger.info("url: {} do not intercepted!, method={}", path, request.getMethod());
+            return true;
+        }
+        else if(path.endsWith("/heartBeat")){
+            //heartBeat请求不拦截
+            logger.info("url: {} do not intercepted!", path);
+            return true;
+        }
+
+
+        GlobalHeader headers = RequestHeaderManager.parseHeader(request);
+        logger.info("request start, path={}, method={}, headers={}", path, request.getMethod(), JSON.toJSONString(headers));
+
+        String uid = headers.getUid();
+        String sign = headers.getSign();
+        if (StringUtils.isEmpty(uid) || StringUtils.isEmpty(sign)) {
+            writeResponse(request, response, ApiWebCode.HEADER_ERROR);
+            return false;
+        }
+
+        //因为缓存了用户id和设备id
+        DeviceUserVo du = userService.load(uid);
+        if (null == du) {
+            writeResponse(request, response, ApiWebCode.NOT_EXISTS);
+            return false;
+        }
+
+        request.setAttribute("aid_DEVICE_USER_INFO", du);
+//        if (true) {
+//            return true;
+//        }
+
+        if (du.getExpireAt().before(new Date())) {
+            writeResponse(request, response, ApiWebCode.TOKEN_EXPIRE);
+            return false;
+        }
+
+        String token = du.getToken();
+        if (!SecurityManager.validate(headers, path, token)) {
+            writeResponse(request, response, ApiWebCode.INVALID_TOKEN);
+            return false;
+        }
+
+        logger.info("token check success: {}", JSON.toJSONString(du));
+        return true;
+    }
+
+    @Override
+    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
+
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+
+        logger.info("请求结束 url={}", request.getRequestURI());
+        long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量(开始时间)
+        long consumeTime = System.currentTimeMillis() - beginTime;//消耗的时间
+        if (consumeTime > 500) {//此处认为处理时间超过500毫秒的请求为慢请求
+            logger.warn(" 请求: {} consume {} millis", request.getRequestURI(), consumeTime);
+        }
+    }
+
+    public void writeResponse(HttpServletRequest request, HttpServletResponse response, Object object) {
+        HttpUtil.responseOutWithJson(request, response, object);
+    }
+
+    public void setIgnoreOptions(boolean ignoreOptions) {
+        this.ignoreOptions = ignoreOptions;
+    }
+}

+ 18 - 0
aid-api-web/src/main/java/cn/aid/apiweb/service/auth/AuthClient.java

@@ -0,0 +1,18 @@
+package cn.aid.apiweb.service.auth;
+
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.data.api.auth.dto.InnerAuthDTO;
+import cn.aid.data.api.auth.vo.AuthResult;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+@FeignClient(name = "${service.product.name}")
+public interface AuthClient {
+
+    // 鉴权
+    @RequestMapping(value = "/auth", method = RequestMethod.POST)
+    APIResult<AuthResult> auth(@RequestBody InnerAuthDTO authDTO);
+
+}

+ 76 - 0
aid-api-web/src/main/java/cn/aid/apiweb/service/auth/AuthService.java

@@ -0,0 +1,76 @@
+package cn.aid.apiweb.service.auth;
+
+import cn.aid.apiweb.service.user.UserClient;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.model.BaseCode;
+import cn.aid.data.api.auth.dto.InnerAuthDTO;
+import cn.aid.data.api.auth.vo.AuthResult;
+import cn.aid.data.api.user.vo.WhiteUserVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.alibaba.fastjson.JSON;
+
+import java.util.Date;
+
+@Service
+@Slf4j
+public class AuthService{
+
+    @Autowired
+    private UserClient userClient;
+
+    @Autowired
+    private AuthClient authClient;
+
+    public APIResult<AuthResult> authWhiteUser(String userId, String productId) {
+        APIResult<WhiteUserVo> result = userClient.findWhiteUserById(userId);
+        if (!result.getSuccess()) {
+            log.error("user white user auth error, code={}, msg={}", result.getCode(), result.getMessage());
+            return APIResult.error(new BaseCode(result.getCode(), result.getMessage()));
+        }
+        WhiteUserVo whiteUserVo = result.getData();
+
+        AuthResult authResult = new AuthResult();
+        authResult.setUserId(userId);
+        authResult.setPid(productId);
+        Date startTime = whiteUserVo.getStartTime();
+        authResult.setStartTime(startTime.getTime());
+        Date endTime = whiteUserVo.getEndTime();
+        if (endTime != null) {
+            authResult.setEndTime(endTime.getTime());
+        }
+        return APIResult.ok(authResult);
+
+    }
+
+    public APIResult<AuthResult> auth(String userId, String merchantId, String itemId) {
+        log.info("auth start: userId={}, itemId={}", userId, itemId);
+
+        // 如果在白名单里就不再查询鉴权信息
+        APIResult<AuthResult> whiteUserAuthApiResult = this.authWhiteUser(userId, itemId);
+        if (whiteUserAuthApiResult.getSuccess()) {
+            return whiteUserAuthApiResult;
+        }
+
+        InnerAuthDTO authDTO = new InnerAuthDTO();
+        authDTO.setItemId(itemId);
+        authDTO.setUserId(userId);
+        authDTO.setMerchantId(merchantId);
+        APIResult<AuthResult> apiResult = authClient.auth(authDTO);
+        log.info("auth api result: {}", JSON.toJSONString(apiResult));
+        return apiResult;
+    }
+
+    public Boolean isValid(String userId, String merchantId, String itemId) {
+        APIResult<AuthResult> apiResult = this.auth(userId, merchantId, itemId);
+        if (!apiResult.getSuccess()) {
+            return Boolean.FALSE;
+        }
+        AuthResult authResult = apiResult.getData();
+        if (authResult == null) {
+            return Boolean.FALSE;
+        }
+        return authResult.isValid();
+    }
+}

+ 19 - 0
aid-api-web/src/main/java/cn/aid/apiweb/service/event/EventClient.java

@@ -0,0 +1,19 @@
+package cn.aid.apiweb.service.event;
+
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.data.api.user.dto.EventLogDTO;
+import cn.aid.data.api.user.entity.EventLog;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@FeignClient(name = "${service.user.name}")
+public interface EventClient {
+
+    @RequestMapping(value = "/event", method = RequestMethod.POST)
+    APIResult<Boolean> addLog(@RequestBody EventLogDTO eventLogDTO);
+
+    @RequestMapping(value = "/event/{uid}", method = RequestMethod.GET)
+    List<String> getCoursesFromLogs(@RequestParam("uid") String uid);
+}

+ 22 - 0
aid-api-web/src/main/java/cn/aid/apiweb/service/event/EventService.java

@@ -0,0 +1,22 @@
+package cn.aid.apiweb.service.event;
+
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.data.api.user.dto.EventLogDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@Slf4j
+public class EventService {
+
+    @Autowired
+    private EventClient eventClient;
+
+    public APIResult<Boolean> addLog(EventLogDTO eventLogDTO) {
+        return eventClient.addLog(eventLogDTO);
+    }
+
+}

+ 108 - 0
aid-api-web/src/main/java/cn/aid/apiweb/service/user/UserClient.java

@@ -0,0 +1,108 @@
+package cn.aid.apiweb.service.user;
+
+import cn.aid.apiweb.code.ApiWebCode;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.page.Page;
+import cn.aid.data.api.user.dto.TerminalDeviceDTO;
+import cn.aid.data.api.user.dto.UserDeviceDTO;
+import cn.aid.data.api.user.vo.TerminalDeviceVo;
+import cn.aid.data.api.user.vo.TerminalUserVo;
+import cn.aid.data.api.user.vo.WhiteUserVo;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@FeignClient(name = "${service.user.name}", fallback = UserClient.UserServiceHystrix.class)
+public interface UserClient
+{
+
+    @RequestMapping(value = "/user/code/{code}", method = RequestMethod.GET)
+    APIResult<TerminalUserVo> loadUserByEid(@PathVariable("code") String code);
+
+    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
+    APIResult<TerminalUserVo> findUserById(@PathVariable("id") String id);
+
+    @RequestMapping(value = "/device/bind", method = RequestMethod.POST)
+    APIResult<TerminalDeviceVo> deviceBind(@RequestBody TerminalDeviceDTO terminalDeviceDTO);
+
+    @RequestMapping(value = "/device/unbind", method = RequestMethod.DELETE)
+    APIResult<Boolean> deviceUnbind(@RequestParam("userId") String userId);
+
+    @RequestMapping(value = "/device/uid/{uid}", method = RequestMethod.GET)
+    APIResult<TerminalDeviceVo> findDeviceByUid(@PathVariable("userId") String uid);
+
+    @RequestMapping(value = "/device/deviceCode/{deviceCode}", method = RequestMethod.GET)
+    List<TerminalDeviceVo> findByDeviceCode(@PathVariable("deviceCode") String deviceCode);
+
+    @RequestMapping(value = "/white/user/{userId}", method = RequestMethod.GET)
+    APIResult<WhiteUserVo> findWhiteUserById(@PathVariable("userId") String userId);
+
+    @RequestMapping(value = "/device/updatebind", method = RequestMethod.PUT)
+    APIResult updateDeviceBind(TerminalDeviceDTO deviceDTO);
+
+    @RequestMapping(value = "/userDevice/op/{uid}", method = RequestMethod.GET)
+    int opUserDevice(@PathVariable("uid") String uid,
+                     @RequestBody UserDeviceDTO userDeviceDTO);
+
+    @Component
+    class UserServiceHystrix implements UserClient
+    {
+
+        @Override
+        public APIResult loadUserByEid(String code)
+        {
+            return APIResult.error(ApiWebCode.SERVER_ERROR);
+        }
+
+        @Override
+        public APIResult deviceBind(TerminalDeviceDTO terminalDeviceDTO)
+        {
+            return APIResult.error(ApiWebCode.SERVER_ERROR);
+        }
+
+        @Override
+        public APIResult deviceUnbind(String userId)
+        {
+            return APIResult.error(ApiWebCode.SERVER_ERROR);
+        }
+
+        @Override
+        public APIResult findDeviceByUid(String uid)
+        {
+            return APIResult.error(ApiWebCode.SERVER_ERROR);
+        }
+
+        @Override
+        public APIResult findUserById(String id)
+        {
+            return APIResult.error(ApiWebCode.SERVER_ERROR);
+        }
+
+        @Override
+        public List<TerminalDeviceVo> findByDeviceCode(String deviceCode)
+        {
+            return null;
+        }
+
+        @Override
+        public APIResult<WhiteUserVo> findWhiteUserById(String userId)
+        {
+            return APIResult.error(ApiWebCode.SERVER_ERROR);
+        }
+
+        @Override
+        public APIResult updateDeviceBind(TerminalDeviceDTO deviceDTO)
+        {
+            return APIResult.error(ApiWebCode.SERVER_ERROR);
+        }
+
+        @Override
+        public int opUserDevice(String uid, UserDeviceDTO userDeviceDTO)
+        {
+            return 0;
+        }
+
+    }
+}

+ 376 - 0
aid-api-web/src/main/java/cn/aid/apiweb/service/user/UserService.java

@@ -0,0 +1,376 @@
+package cn.aid.apiweb.service.user;
+
+import cn.aid.apiweb.code.ApiWebCode;
+import cn.aid.apiweb.service.product.ProductClient;
+import cn.aid.apiweb.utils.SecurityManager;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.model.BaseCode;
+import cn.aid.common.utils.api.page.Page;
+import cn.aid.common.utils.constant.PlatForm;
+import cn.aid.common.utils.constant.RedisKey;
+import cn.aid.common.utils.service.RedisService;
+import cn.aid.data.api.app.dto.LoginInfoDTO;
+import cn.aid.data.api.app.vo.DeviceUserVo;
+import cn.aid.data.api.app.vo.UserInfoVo;
+import cn.aid.data.api.user.dto.TerminalDeviceDTO;
+import cn.aid.data.api.user.dto.UserDeviceDTO;
+import cn.aid.data.api.user.vo.TerminalDeviceVo;
+import cn.aid.data.api.user.vo.TerminalUserVo;
+import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+
+@Service
+@Slf4j
+public class UserService
+{
+
+    public final static String USER_FORMAT_KEY = RedisKey.USER_FORMAT_KEY;
+
+    @Value(value = "${token.expiration:604800}")
+    private int expiration;
+
+    @Value(value = "${login.web.force.interval:2400}")
+    private int forceLoginInterval;
+
+    @Autowired
+    private UserClient userClient;
+
+    @Autowired
+    private ProductClient productClient;
+
+    @Autowired
+    private RedisService redisService;
+
+    public APIResult<UserInfoVo> login(LoginInfoDTO loginInfoDTO)
+    {
+        String deviceCode = loginInfoDTO.getDeviceCode();
+        String deviceModel = loginInfoDTO.getDeviceModel();
+        String deviceMfrs = loginInfoDTO.getDeviceMfrs();
+        String deviceName = loginInfoDTO.getDeviceName();
+        String deviceType = loginInfoDTO.getDeviceType();
+
+        String merchant = loginInfoDTO.getMerchant();
+        String eid = loginInfoDTO.getEid();
+        String loginPassword = loginInfoDTO.getPassword();
+        log.info("user login start, user={}", JSON.toJSONString(loginInfoDTO));
+
+        APIResult<TerminalUserVo> userVoAPIResult = userClient.loadUserByEid(eid);
+        TerminalUserVo userVo = userVoAPIResult.getData();
+        if (!userVoAPIResult.getSuccess())
+        {
+            log.error("load user api error");
+            return APIResult.error(ApiWebCode.LOGIN_ERROR);
+        }
+
+        //操作用户登录设备信息
+        if (deviceName != null && !"".equals(deviceName.trim()))
+        {
+            String uid = userVo.getId();
+            UserDeviceDTO dto = new UserDeviceDTO();
+            dto.setDeviceCode(deviceCode);
+            dto.setDeviceModel(deviceModel);
+            dto.setDeviceType(deviceType);
+            dto.setDeviceMfrs(deviceMfrs);
+            dto.setDeviceName(deviceName);
+
+            int opRet = userClient.opUserDevice(uid,dto);
+            if (opRet == 0)
+            {
+                log.error("Failed to operated user device with[uid={},deviceCode={},deviceModel={},deviceName={}]", uid, deviceCode, deviceModel, deviceName);
+            }
+            else
+            {
+                log.info("Succeed to operating user device with[uid={},deviceCode={},deviceModel={},deviceName={}]", uid, deviceCode, deviceModel, deviceName);
+            }
+        }
+
+        String storePassword = userVo.getPassword();
+        if (!SecurityManager.validate(loginPassword, storePassword))
+        {
+            log.error("密码校验错误, loginPassword={}, storePassword={}", loginPassword, storePassword);
+            return APIResult.error(ApiWebCode.PASSWORD_ERROR);
+        }
+
+
+/*        if(StringUtils.isNotBlank(merchant) && !merchant.equals(userVo.getMerchantSimple())){
+            log.error("渠道校验错误, requestMerchant={}, userMerchant={}", merchant, userVo.getMerchantSimple());
+            return APIResult.error(ApiWebCode.LOGIN_ERROR);
+        }*/
+
+        String userId = userVo.getId();
+        String ip = loginInfoDTO.getIp();
+        String terminal = loginInfoDTO.getTerminal();
+
+        // 网页端登陆在40分钟后可以踢掉对方网页登陆
+        if (PlatForm.WEB.equals(terminal))
+        {
+            String key = getUserFormatKey(userId);
+            DeviceUserVo deviceUserVo = (DeviceUserVo) redisService.get(key);
+            if (deviceUserVo != null)
+            {
+                Date refreshAt = deviceUserVo.getRefreshAt();
+                String lastTerminal = deviceUserVo.getTerminal();
+                if (DateUtils.addSeconds(refreshAt, forceLoginInterval).before(new Date()) && PlatForm.WEB.equals(lastTerminal))
+                {
+                    log.info("网页端强制登陆, deviceCode={}, eid={}", deviceCode, eid);
+                    APIResult<Boolean> forceLogoutResult = this.logout(userId);
+                    if (!forceLogoutResult.getSuccess())
+                    {
+                        return APIResult.error(new BaseCode(forceLogoutResult.getCode(), forceLogoutResult.getMessage()));
+                    }
+                }
+            }
+        }
+
+        TerminalDeviceVo deviceVo = this.bind(userId, deviceCode, merchant, ip, terminal);
+        if (deviceVo == null)
+        {
+            return APIResult.error(ApiWebCode.DEVICE_BOUND_ERROR);
+        }
+
+        // assembly device and use info
+        DeviceUserVo deviceUserVo = toDeviceUserVo(userVo, deviceVo);
+        // 保存至缓存
+        this.save(deviceUserVo);
+
+        UserInfoVo userInfoVo = toUserInfoVo(deviceUserVo, true);
+        log.info("user={} login success, userInfo={}", eid, JSON.toJSONString(userInfoVo));
+
+        return APIResult.ok(userInfoVo);
+    }
+
+    public APIResult<Boolean> logout(String userId)
+    {
+        APIResult<Boolean> unbindResult = userClient.deviceUnbind(userId);
+        if (!unbindResult.getSuccess())
+        {
+            return APIResult.error(ApiWebCode.LOGOUT_ERROR);
+        }
+
+        String key = getUserFormatKey(userId);
+        redisService.delete(key);
+
+        return APIResult.ok();
+    }
+
+    public TerminalDeviceVo bind(String userId, String deviceCode, String merchant, String ip, String terminal)
+    {
+        TerminalDeviceDTO deviceDTO = new TerminalDeviceDTO();
+        deviceDTO.setUserId(userId);
+        deviceDTO.setDeviceCode(deviceCode);
+        deviceDTO.setMerchant(merchant);
+        deviceDTO.setIp(ip);
+        deviceDTO.setTerminal(terminal);
+        APIResult<TerminalDeviceVo> apiResult = userClient.deviceBind(deviceDTO);
+        if (!apiResult.getSuccess())
+        {
+            log.error("bind user api error");
+            return null;
+        }
+        return apiResult.getData();
+    }
+
+    // load user and device info
+    public DeviceUserVo load(String uid)
+    {
+        String key = getUserFormatKey(uid);
+        DeviceUserVo deviceUserVo = (DeviceUserVo) redisService.get(key);
+        if (deviceUserVo == null)
+        {
+            deviceUserVo = getDeviceUserVo(uid);
+        }
+        if (deviceUserVo != null)
+        {
+            this.save(deviceUserVo);
+        }
+        return deviceUserVo;
+    }
+
+    public UserInfoVo getUserInfo(String uid)
+    {
+        DeviceUserVo deviceUserVo = this.load(uid);
+        return toUserInfoVo(deviceUserVo, false);
+    }
+
+    public DeviceUserVo getDeviceUserVo(String uid)
+    {
+        APIResult<TerminalDeviceVo> deviceAPIResult = userClient.findDeviceByUid(uid);
+        if (!deviceAPIResult.getSuccess())
+        {
+            log.error("load device api error, {}", deviceAPIResult.getMessage());
+            return null;
+        }
+        TerminalDeviceVo deviceVo = deviceAPIResult.getData();
+        // load user info
+        APIResult<TerminalUserVo> userAPIResult = userClient.findUserById(uid);
+        if (!userAPIResult.getSuccess())
+        {
+            log.error("load user api error, {}", userAPIResult.getMessage());
+            return null;
+        }
+        TerminalUserVo userVo = userAPIResult.getData();
+
+        return toDeviceUserVo(userVo, deviceVo);
+    }
+
+    public APIResult<UserInfoVo> refresh(String deviceCode, String merchant, Boolean force)
+    {
+
+        List<TerminalDeviceVo> deviceVoList = userClient.findByDeviceCode(deviceCode);
+        if (CollectionUtils.isEmpty(deviceVoList))
+        {
+            log.error("device code not bind any eid! deviceCode={}", deviceCode);
+            return APIResult.error(ApiWebCode.INVALID_TOKEN);
+        }
+
+        TerminalDeviceVo deviceVo = null;
+
+        for (TerminalDeviceVo dv : deviceVoList)
+        {
+            //判断当前鉴权账号
+            if (StringUtils.isBlank(dv.getMerchant()))
+            {
+                //如果设备渠道code为空,则设置为当前渠道code
+                dv.setMerchant(merchant);
+                try
+                {
+                    //更新数据库
+                    updateDeviceBind(dv);
+                }
+                catch (Exception e)
+                {
+                    return APIResult.error(ApiWebCode.DEVICE_BOUND_ERROR);
+                }
+                deviceVo = dv;
+            }
+            else if (StringUtils.isNotBlank(merchant) && merchant.equals(dv.getMerchant()))
+            {
+                deviceVo = dv;
+            }
+        }
+
+        if (null == deviceVo)
+        {
+            log.error("by device code not find this merchant! deviceCode={},merchant={}", deviceCode, merchant);
+            return APIResult.error(ApiWebCode.INVALID_TOKEN);
+        }
+
+        String uid = deviceVo.getUserId();
+
+        DeviceUserVo deviceUserVo;
+        if (force)
+        {
+            APIResult<TerminalUserVo> userAPIResult = userClient.findUserById(uid);
+            if (!userAPIResult.getSuccess())
+            {
+                log.error("load user api error, {}", userAPIResult.getMessage());
+                return APIResult.error(ApiWebCode.INVALID_TOKEN);
+            }
+            TerminalUserVo userVo = userAPIResult.getData();
+            deviceUserVo = toDeviceUserVo(userVo, deviceVo);
+        }
+        else
+        {
+            String key = getUserFormatKey(uid);
+            deviceUserVo = (DeviceUserVo) redisService.get(key);
+        }
+
+        // 无论怎样都能成功刷新
+        if (deviceUserVo == null)
+        {
+            deviceUserVo = getDeviceUserVo(uid);
+        }
+
+        refreshToken(deviceUserVo);
+        save(deviceUserVo);
+
+        UserInfoVo userInfoVo = toUserInfoVo(deviceUserVo, true);
+        return APIResult.ok(userInfoVo);
+    }
+
+    private void updateDeviceBind(TerminalDeviceVo terminalDeviceVo)
+    {
+        TerminalDeviceDTO deviceDTO = new TerminalDeviceDTO();
+        deviceDTO.setId(terminalDeviceVo.getId());
+        deviceDTO.setMerchant(terminalDeviceVo.getMerchant());
+        deviceDTO.setDeviceCode(terminalDeviceVo.getDeviceCode());
+        deviceDTO.setUserId(terminalDeviceVo.getUserId());
+        APIResult apiResult = userClient.updateDeviceBind(deviceDTO);
+        if (!apiResult.getSuccess())
+        {
+            log.error("update bind user api error");
+            throw new RuntimeException("update bind user api error");
+        }
+    }
+
+    // cache user and device info
+    public void save(DeviceUserVo deviceUserVo)
+    {
+        String key = getUserFormatKey(deviceUserVo.getUid());
+        redisService.set(key, deviceUserVo);
+    }
+
+    public static String getUserFormatKey(String uid)
+    {
+        return String.format(USER_FORMAT_KEY, uid);
+    }
+
+    public static UserInfoVo toUserInfoVo(DeviceUserVo deviceUserVo, Boolean withToken)
+    {
+        UserInfoVo userInfoVo = new UserInfoVo();
+        userInfoVo.setUid(deviceUserVo.getUid());
+        userInfoVo.setEid(deviceUserVo.getEid());
+        userInfoVo.setName(deviceUserVo.getName());
+        userInfoVo.setMerchantName(deviceUserVo.getMerchantName());
+        userInfoVo.setMerchantContactName(deviceUserVo.getMerchantContactName());
+        userInfoVo.setMerchantContactMobile(deviceUserVo.getMerchantContactMobile());
+        if (withToken)
+        {
+            userInfoVo.setToken(deviceUserVo.getToken());
+        }
+        return userInfoVo;
+    }
+
+    public DeviceUserVo toDeviceUserVo(TerminalUserVo userVo, TerminalDeviceVo deviceVo)
+    {
+        DeviceUserVo deviceUserVo = new DeviceUserVo();
+        deviceUserVo.setUid(userVo.getId());
+        deviceUserVo.setEid(userVo.getCode());
+        deviceUserVo.setPassword(userVo.getPassword());
+        deviceUserVo.setName(userVo.getCityName() + userVo.getZoneName() + userVo.getName());
+        deviceUserVo.setDeviceCode(deviceVo.getDeviceCode());
+        deviceUserVo.setMerchantId(userVo.getMerchantId());
+        deviceUserVo.setMerchantName(userVo.getMerchantName());
+        deviceUserVo.setMerchantContactName(userVo.getMerchantContactName());
+        deviceUserVo.setMerchantContactMobile(userVo.getMerchantContactMobile());
+        deviceUserVo.setTerminal(deviceVo.getTerminal());
+        refreshToken(deviceUserVo);
+        return deviceUserVo;
+    }
+
+    public void refreshToken(DeviceUserVo deviceUserVo)
+    {
+        String token = SecurityManager.generateToken(deviceUserVo.getPassword());
+        log.info("token ======================= ,{}", token);
+        Date nowTime = new Date();
+        Date expireAt = DateUtils.addSeconds(nowTime, this.expiration);
+        deviceUserVo.setToken(token);
+        deviceUserVo.setExpireAt(expireAt);
+        deviceUserVo.setRefreshAt(nowTime);
+    }
+
+
+}

+ 103 - 0
aid-api-web/src/main/java/cn/aid/apiweb/utils/DTOConverter.java

@@ -0,0 +1,103 @@
+package cn.aid.apiweb.utils;
+
+import cn.aid.data.api.app.vo.*;
+import org.springframework.beans.BeanUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DTOConverter {
+
+    public static RecommendVo convert(Recommend recommend) {
+        RecommendVo recommendVo = new RecommendVo();
+        recommendVo.setId(recommend.getPid());
+        recommendVo.setCode(recommend.getCode());
+        recommendVo.setTitle(recommend.getTitle());
+        recommendVo.setSubTitle(recommend.getSubTitle());
+        recommendVo.setBreadCrumb(recommend.getBreadCrumb());
+        recommendVo.setCoverUrl(recommend.getCoverUrl());
+        return recommendVo;
+    }
+
+    public static TagGroupVo convert(TagGroup tagGroup) {
+        TagGroupVo tagGroupVo = new TagGroupVo();
+        tagGroupVo.setName(tagGroup.getName());
+        List<TagVo> tagVoList = new ArrayList<>();
+        List<Tag> tagList = tagGroup.getTagList();
+        if (CollectionUtils.isEmpty(tagList)) {
+            return tagGroupVo;
+        }
+        for (Tag tag : tagList) {
+            TagVo tagVo = new TagVo();
+            tagVo.setId(tag.getId());
+            tagVo.setName(tag.getName());
+            tagVoList.add(tagVo);
+        }
+        tagGroupVo.setList(tagVoList);
+        return tagGroupVo;
+    }
+
+    public static TagTypeVo convert(TagType tagType) {
+        TagTypeVo tagTypeVo = new TagTypeVo();
+        tagTypeVo.setName(tagType.getName());
+        List<TagVo> tagVoList = new ArrayList<>();
+        List<Tag> tagList = tagType.getTagList();
+        if (CollectionUtils.isEmpty(tagList)) {
+            return tagTypeVo;
+        }
+        for (Tag tag : tagList) {
+            TagVo tagVo = new TagVo();
+            tagVo.setId(tag.getId());
+            tagVo.setName(tag.getName());
+            tagVoList.add(tagVo);
+        }
+        tagTypeVo.setList(tagVoList);
+        return tagTypeVo;
+    }
+
+
+    public static CourseVo convert(Course course) {
+        CourseVo courseVo = new CourseVo();
+        courseVo.setBreadCrumb(course.getBreadCrumb());
+        courseVo.setBgUrl(course.getBgUrl());
+        courseVo.setTitle(course.getTitle());
+        List<CourseSubItemVo> subItemVoList = course.getSubItemList();
+        if (subItemVoList == null) {
+            return courseVo;
+        }
+        List<LessonVo> lessonVoList = new ArrayList<>();
+        for (CourseSubItemVo courseSubItemVo : subItemVoList) {
+            LessonVo lessonVo = new LessonVo();
+            lessonVo.setId(courseSubItemVo.getId());
+            lessonVo.setTitle(courseSubItemVo.getTitle());
+            lessonVo.setCode(courseSubItemVo.getCode());
+            lessonVoList.add(lessonVo);
+        }
+        courseVo.setList(lessonVoList);
+        return courseVo;
+    }
+
+    public static CourseDetailVo convert(CourseItemVo courseItemVo) {
+        CourseDetailVo courseDetailVo = new CourseDetailVo();
+        BeanUtils.copyProperties(courseItemVo, courseDetailVo);
+        return courseDetailVo;
+    }
+
+    public static LessonVo convert(Lesson lesson) {
+        LessonVo lessonVo = new LessonVo();
+        lessonVo.setId(lesson.getId());
+        lessonVo.setCode(lesson.getCode());
+        lessonVo.setTitle(lesson.getTitle());
+        return lessonVo;
+    }
+
+    public static CourseWareVo convert(CourseWare courseWare) {
+        CourseWareVo courseWareVo = new CourseWareVo();
+        courseWareVo.setId(courseWare.getId());
+        courseWareVo.setCode(courseWare.getCode());
+        courseWareVo.setTitle(courseWare.getTitle());
+        courseWareVo.setCategory(courseWare.getCategory());
+        return courseWareVo;
+    }
+}

+ 49 - 0
aid-api-web/src/main/java/cn/aid/apiweb/utils/RequestHeaderManager.java

@@ -0,0 +1,49 @@
+package cn.aid.apiweb.utils;
+
+import cn.aid.apiweb.entity.GlobalHeader;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Optional;
+
+public class RequestHeaderManager {
+
+    public static GlobalHeader parseHeader(HttpServletRequest request) {
+        GlobalHeader globalHeader = new GlobalHeader();
+        globalHeader.setUid(Optional.ofNullable(getRequestParameter(request, "uid")).orElse(""));
+        globalHeader.setEid(Optional.ofNullable(getRequestParameter(request, "eid")).orElse(""));
+        globalHeader.setRequestId(Optional.ofNullable(getRequestParameter(request, "requestId")).orElse(""));
+        globalHeader.setTerminal(Optional.ofNullable(getRequestParameter(request, "terminal")).orElse("").toLowerCase());
+
+        //To be compatible with android app 2.x version, if sign not exist, use Authentication
+        String sign = getRequestParameter(request, "sign");
+        if(null != sign && !sign.isEmpty()){
+            globalHeader.setSign(getRequestParameter(request, "sign"));
+        }
+        else{
+            globalHeader.setSign(Optional.ofNullable(getRequestParameter(request, "Authentication")).orElse(""));
+        }
+
+
+        return globalHeader;
+    }
+
+    /**
+     * First get target parameter in header, if not exist, then get it in queryString or request body
+     * @param request
+     * @param key
+     * @return
+     */
+    public static String getRequestParameter(HttpServletRequest request, String key){
+        //first check header
+        /*
+        if (null != request.getHeader(key)){
+            return request.getHeader(key);
+        }
+        return request.getParameter(key);
+        */
+
+        //use Header directly
+        return request.getHeader(key);
+    }
+
+
+}

+ 51 - 0
aid-api-web/src/main/java/cn/aid/apiweb/utils/SecurityManager.java

@@ -0,0 +1,51 @@
+package cn.aid.apiweb.utils;
+
+import cn.aid.apiweb.entity.GlobalHeader;
+import cn.aid.common.utils.util.SecurityUtil;
+import cn.aid.common.utils.util.UUIDUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
+
+public class SecurityManager {
+
+    private static final Logger log = LoggerFactory.getLogger(SecurityManager.class);
+
+    // 校验密码是否正确
+    public static boolean validate(String password, String key) {
+        if (StringUtils.isEmpty(password)) {
+            log.error("password is empty");
+            return false;
+        }
+
+//        String pwdMd5 = SecurityUtil.MD5(password);
+//        if (pwdMd5.equals(key)) {
+//            return true;
+//        }
+        if (password.equals(key)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    // 生成token
+    public static String generateToken(String str) {
+        String uuid = UUIDUtil.getUUID();
+        return SecurityUtil.MD5(uuid + str);
+    }
+
+    public static Boolean validate(GlobalHeader globalHeader, String path, String token) {
+        String sign = globalHeader.getSign();
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("path=" + path + "&");
+        sb.append("uid=" + globalHeader.getUid() + "&");
+        sb.append("eid=" + globalHeader.getEid() + "&");
+        String computeSign = SecurityUtil.MD5(sb.toString(), token);
+
+        log.info("--------------sb.toString()={},token={}",sb.toString(),token  );
+        log.info("computeSign  sign ,computeSign={},sign={}",computeSign,sign);
+        return computeSign.equals(sign);
+    }
+}

+ 15 - 0
aid-api-web/src/main/resources/bootstrap.yml

@@ -0,0 +1,15 @@
+spring:
+  application:
+    name: api-web
+  cloud:
+    config:
+      uri: http://127.0.0.1:8921
+      label: master
+      profile: ${profile:local}
+
+ribbon:
+  ReadTimeout: 6000
+  ConnectTimeout: 6000
+
+server:
+  port: 8600

+ 16 - 0
aid-api-web/src/test/java/cn/aid/apiweb/ApiWebApplicationTests.java

@@ -0,0 +1,16 @@
+package cn.aid.apiweb;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ApiWebApplicationTests {
+
+	@Test
+	public void contextLoads() {
+	}
+
+}

+ 131 - 0
aid-cms-web/pom.xml

@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>cn.aid</groupId>
+	<artifactId>aid-cms-web</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<packaging>jar</packaging>
+
+	<name>aid-cms-web</name>
+	<description>Cms Web For Spring Cloud</description>
+
+	<parent>
+        <groupId>cn.aid</groupId>
+        <artifactId>aid</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+	</parent>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+		<java.version>1.8</java.version>
+		<spring-cloud.version>Dalston.SR4</spring-cloud.version>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-config</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-eureka</artifactId>
+		</dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-feign</artifactId>
+        </dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
+		</dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.session</groupId>
+            <artifactId>spring-session-data-redis</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.16.16</version>
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.7.0</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.aid</groupId>
+            <artifactId>aid-common-utils</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.aid</groupId>
+            <artifactId>aid-data-api</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+        <!--httpClient-->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.3</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.netflix.feign</groupId>
+            <artifactId>feign-httpclient</artifactId>
+            <version>RELEASE</version>
+        </dependency>
+    </dependencies>
+
+	<dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>org.springframework.cloud</groupId>
+				<artifactId>spring-cloud-dependencies</artifactId>
+				<version>${spring-cloud.version}</version>
+				<type>pom</type>
+				<scope>import</scope>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
+
+    <build>
+        <finalName>${project.name}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <outputDirectory>../target</outputDirectory>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>

+ 21 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/CmsWebApplication.java

@@ -0,0 +1,21 @@
+package cn.aid.cmsweb;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.netflix.feign.EnableFeignClients;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+
+@EnableFeignClients
+@EnableRedisHttpSession
+@EnableDiscoveryClient
+@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
+public class CmsWebApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(CmsWebApplication.class, args);
+	}
+}

+ 49 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/assist/aspect/OperationLogAspect.java

@@ -0,0 +1,49 @@
+package cn.aid.cmsweb.assist.aspect;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.annotation.Order;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+
+@Aspect
+@Component
+@Order(-100)
+public class OperationLogAspect {
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+//    @Autowired
+//    AsyncOperationLogHandler asyncOperationLogHandler;
+//
+//    @Before("execution(* cn.efunbox.cms.controller..*.*Controller.*(..))")
+//    public void doBefore(JoinPoint joinPoint) throws Throwable {
+//        // 接收到请求,记录请求内容
+//        try {
+//            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+//            HttpServletRequest request=attributes.getRequest();
+//            if(request.getRequestURL().indexOf("/upload")!=-1){
+//                logger.debug("上传文件 忽略!");
+//                return;
+//            }
+//            //如果是 增删改 才记录入库
+//            if(request.getMethod().equals("POST")|| request.getMethod().equals("PUT")|| request.getMethod().equals("DELETE")|| request.getMethod().equals("TRACE")|| request.getMethod().equals("PATCH")){
+//                UserDetails userDetails = (UserDetails) request.getSession().getAttribute("SPRING_SECURITY_CONTEXT_DETAILS");
+//                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null);
+//                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+//                asyncOperationLogHandler.asyncHandleLog(joinPoint,request,authentication);
+//            }
+//        } catch (Exception e) {
+//            logger.error("日志记录出错!", e);
+//        }
+//    }
+
+}

+ 14 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/assist/resolver/NeedUser.java

@@ -0,0 +1,14 @@
+package cn.aid.cmsweb.assist.resolver;
+
+import java.lang.annotation.*;
+
+/**
+ * @author tomas
+ * @date 2017-04-17
+ * @what
+ */
+@Target({ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface NeedUser {
+}

+ 34 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/assist/resolver/NeedUserResolver.java

@@ -0,0 +1,34 @@
+package cn.aid.cmsweb.assist.resolver;
+
+import cn.aid.cmsweb.entity.UserDetails;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.MethodParameter;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.support.WebDataBinderFactory;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.context.request.WebRequest;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.method.support.ModelAndViewContainer;
+
+/**
+ * @author Tomas
+ * @date 2016-07-17
+ * @what
+ */
+@Component
+public class NeedUserResolver implements HandlerMethodArgumentResolver {
+    private static final Logger logger = LoggerFactory.getLogger(NeedUserResolver.class);
+    public boolean supportsParameter(MethodParameter methodParameter) {
+        return  methodParameter.hasParameterAnnotation(NeedUser.class);
+    }
+
+    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
+        logger.info(String.format("Resolve argument %s.", methodParameter.getParameterName()));
+        if(methodParameter.hasParameterAnnotation(NeedUser.class)){
+            UserDetails userDetails = (UserDetails) nativeWebRequest.getAttribute("SPRING_SECURITY_CONTEXT_DETAILS", WebRequest.SCOPE_SESSION);
+            return  userDetails;
+        }
+        return null;
+    }
+}

+ 29 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/code/CmsWebAPICode.java

@@ -0,0 +1,29 @@
+package cn.aid.cmsweb.code;
+
+import cn.aid.common.utils.api.model.APICode;
+import cn.aid.common.utils.api.model.BaseCode;
+
+/**
+ * Created by tomas on 2017/5/24.
+ */
+public class CmsWebAPICode extends APICode {
+
+    public final static int _C_USERNAME_PASSWORD_ERROR = 10001;
+    public final static BaseCode USERNAME_PASSWORD_ERROR = new BaseCode(_C_USERNAME_PASSWORD_ERROR, "用户名错误");
+
+    public final static int _C_PASSWORD_ERROR = 10002;
+    public final static BaseCode PASSWORD_ERROR = new BaseCode(_C_PASSWORD_ERROR, "密码错误");
+
+    public final static int _C_INVALID_TOKEN = 10003;
+    public final static BaseCode INVALID_TOKEN = new BaseCode(_C_INVALID_TOKEN, "Token失效");
+
+    public final static int _C_AUTHORIZED_FAILD = 10004;
+    public final static BaseCode AUTHORIZED_FAILD    = new BaseCode(_C_AUTHORIZED_FAILD, "Token认证失败");
+
+    public final static int _C_AUTHORIZED_EXPIRE = 10005;
+    public final static BaseCode AUTHORIZED_EXPIRE = new BaseCode(_C_AUTHORIZED_EXPIRE, "Token失效");
+
+    public final static int _C_MAX_COUNT_SESSION_ERROR = 10006;
+    public final static BaseCode MAX_COUNT_SESSION_ERROR = new BaseCode(_C_MAX_COUNT_SESSION_ERROR, "达到同时最大登录限制");
+
+}

+ 60 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/configuration/CmsConfiguration.java

@@ -0,0 +1,60 @@
+package cn.aid.cmsweb.configuration;
+
+
+import cn.aid.cmsweb.assist.resolver.NeedUserResolver;
+import cn.aid.common.utils.web.intercepter.HeaderProcessIntercepter;
+import cn.aid.common.utils.web.intercepter.IgnoreOptionsInterceptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+import java.util.List;
+
+/**
+ * 类名:WebConfiguration  <br />
+ *
+ * 功能:Web相关配置
+ *
+ * @author tomas <br />
+ * 创建时间:2016年7月27日 下午3:57:19  <br />
+ * @version 2016年7月27日*/
+@EnableWebMvc
+@Configuration
+public class CmsConfiguration extends WebMvcConfigurerAdapter implements EnvironmentAware {
+	// 日志记录器
+	private static final Logger logger = LoggerFactory.getLogger(CmsConfiguration.class);
+
+	@Autowired
+	private NeedUserResolver needUserResolver;
+
+	// 当前的环境对象
+	protected Environment environment;
+
+	public void addInterceptors(InterceptorRegistry registry) {
+		registry.addInterceptor(new HeaderProcessIntercepter());
+     	registry.addInterceptor(new IgnoreOptionsInterceptor());
+	}
+	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
+		// 请求体参数解析器
+//		argumentResolvers.add(new RequestBodyMappingArgumentResolver());
+		argumentResolvers.add(needUserResolver);
+		super.addArgumentResolvers(argumentResolvers);
+	}
+	/**
+	 * Set the {@code Environment} that this object runs in.
+	 *
+	 * @param environment
+	 */
+	@Override
+	public void setEnvironment(Environment environment) {
+		this.environment = environment;
+	}
+
+}

+ 24 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/configuration/FeignConfiguration.java

@@ -0,0 +1,24 @@
+package cn.aid.cmsweb.configuration;
+
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Slf4j
+@Configuration
+public class FeignConfiguration {
+
+    public static class ContentTypeInterceptor implements RequestInterceptor {
+        @Override
+        public void apply(RequestTemplate template) {
+            template.header("Content-Type", "application/json");
+        }
+    }
+
+    @Bean
+    public ContentTypeInterceptor contentTypeInterceptor() {
+        return new ContentTypeInterceptor();
+    }
+}

+ 49 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/configuration/GlobalExceptionHandler.java

@@ -0,0 +1,49 @@
+package cn.aid.cmsweb.configuration;
+
+import cn.aid.common.utils.api.model.APICode;
+import cn.aid.common.utils.api.model.APIResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
+import org.springframework.web.servlet.NoHandlerFoundException;
+
+import javax.servlet.http.HttpServletRequest;
+import java.nio.file.AccessDeniedException;
+
+@RestController
+@ControllerAdvice
+public class GlobalExceptionHandler {
+    private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
+
+    /**
+     * 系统异常处理,比如:404,500
+     * @param request
+     * @param e
+     * @return
+     * @throws Exception
+     */
+    @ExceptionHandler(value = Exception.class)
+    @ResponseBody
+    public APIResult defaultErrorHandler(HttpServletRequest request, Exception e) throws Exception {
+        logger.error("{}", e);
+
+        APIResult apiResult = new APIResult();
+        apiResult.setMessage(e.getMessage());
+        apiResult.setSuccess(false);
+
+        if (e instanceof NoHandlerFoundException) {
+            apiResult.setCode(APICode._C_NOT_FOUND);
+        }else if (e instanceof AccessDeniedException){
+            apiResult.setCode(APICode._C_ACCESS_DENIED);
+        }else if (e instanceof MethodArgumentTypeMismatchException){
+            apiResult.setCode(400);
+        }else {
+            apiResult.setCode(500);
+        }
+        return apiResult;
+    }
+}

+ 130 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/configuration/RedisCacheConfig.java

@@ -0,0 +1,130 @@
+package cn.aid.cmsweb.configuration;
+
+import cn.aid.common.utils.service.RedisService;
+import cn.aid.common.utils.service.impl.RedisServiceImpl;
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.interceptor.KeyGenerator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import java.lang.reflect.Method;
+
+@Configuration
+@EnableCaching //加上这个注解是的支持缓存注解
+public class RedisCacheConfig extends CachingConfigurerSupport {
+
+    @Value("${spring.redis.host}")
+    private String host;
+
+    @Value("${spring.redis.port}")
+    private int port;
+
+    @Value("${spring.redis.timeout}")
+    private int timeout;
+
+    @Value("${spring.redis.password}")
+    private String password;
+
+
+    /**
+     * 连接redis的工厂类
+     *
+     * @return
+     */
+    @Bean
+    public JedisConnectionFactory jedisConnectionFactory() {
+        JedisConnectionFactory factory = new JedisConnectionFactory();
+        factory.setHostName(host);
+        factory.setPort(port);
+        factory.setTimeout(timeout);
+        factory.setPassword(password);
+        return factory;
+    }
+
+    /**
+     * 配置RedisTemplate
+     * 设置添加序列化器
+     * key 使用string序列化器
+     * value 使用Json序列化器
+     * 还有一种简答的设置方式,改变defaultSerializer对象的实现。
+     *
+     * @return
+     */
+    @Bean(name = "redisTemplate")
+    public RedisTemplate<Object, Object> redisTemplate() {
+        //StringRedisTemplate的构造方法中默认设置了stringSerializer
+        RedisTemplate<Object, Object> template = new RedisTemplate<>();
+        //设置开启事务
+        template.setEnableTransactionSupport(true);
+        //set key serializer
+        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+        template.setKeySerializer(stringRedisSerializer);
+        template.setHashKeySerializer(stringRedisSerializer);
+        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
+
+        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
+
+        //set value serializer
+//        template.setDefaultSerializer(jackson2JsonRedisSerializer);
+        template.setValueSerializer(jackson2JsonRedisSerializer);
+        template.setHashValueSerializer(jackson2JsonRedisSerializer);
+
+        template.setConnectionFactory(jedisConnectionFactory());
+        template.afterPropertiesSet();
+        return template;
+    }
+
+    /**
+     * 设置RedisCacheManager
+     * 使用cache注解管理redis缓存
+     *
+     * @return
+     */
+    @Bean
+    public RedisCacheManager cacheManager() {
+        RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate());
+        return redisCacheManager;
+    }
+
+    @Bean
+    public RedisService redisService() {
+        RedisServiceImpl redisService = new RedisServiceImpl();
+        redisService.setRedisTemplate(this.redisTemplate());
+        return redisService;
+    }
+
+    /**
+     * 自定义生成redis-key
+     *
+     * @return
+     */
+    @Override
+    public KeyGenerator keyGenerator() {
+        return new KeyGenerator() {
+            @Override
+            public Object generate(Object o, Method method, Object... objects) {
+                StringBuilder sb = new StringBuilder();
+                sb.append(o.getClass().getName()).append(".");
+                sb.append(method.getName()).append(".");
+                for (Object obj : objects) {
+                    sb.append(obj.toString());
+                }
+                System.out.println("keyGenerator=" + sb.toString());
+                return sb.toString();
+            }
+        };
+    }
+}

+ 287 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/configuration/SecurityConfig.java

@@ -0,0 +1,287 @@
+package cn.aid.cmsweb.configuration;
+
+import cn.aid.cmsweb.code.CmsWebAPICode;
+import cn.aid.cmsweb.entity.UserDetails;
+import cn.aid.cmsweb.security.CmsAuthenticationProvider;
+import cn.aid.cmsweb.security.CmsUserDetailsService;
+import cn.aid.cmsweb.security.JwtAuthenticationTokenFilter;
+import cn.aid.cmsweb.security.JwtTokenService;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.util.HttpUtil;
+import com.google.common.collect.ImmutableList;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.security.SecurityProperties;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.data.redis.core.RedisOperations;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
+import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
+import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
+import org.springframework.security.web.authentication.session.SessionAuthenticationException;
+import org.springframework.security.web.header.Header;
+import org.springframework.security.web.header.HeaderWriter;
+import org.springframework.security.web.session.SessionManagementFilter;
+import org.springframework.session.data.redis.RedisOperationsSessionRepository;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 安全配置中心
+ *
+ * @author by tomas
+ * @date 2017-06-06 15:30:00
+ */
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true)//允许进入页面方法前检验
+@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+    private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
+
+    @Value("${jwt.header:X-Token}")
+    private String tokenHeader;
+
+    @Value("${jwt.cookie:X-Cookie}")
+    private String cookieName;
+
+    @Value("${jwt.expiration:604800}")
+    private Integer expiration;
+
+    @Autowired
+    private JwtTokenService jwtTokenService;
+
+    @Autowired
+    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
+
+    public static class StaticHeadersWriter implements HeaderWriter {
+
+        private final static List<Header> headers = new ArrayList<>();
+
+        static {
+            headers.add(new Header("Access-Control-Allow-Origin", "*"));
+            headers.add(new Header("Access-Control-Allow-Methods", "GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE, PATCH"));
+            headers.add(new Header("Access-Control-Allow-Headers", "Origin, X-Token, Authentication, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization, Cache-control "));
+            headers.add(new Header("Access-Control-Allow-Credentials", "true"));
+        }
+
+        @Override
+        public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
+            for (Header header : headers) {
+                for (String value : header.getValues()) {
+                    response.addHeader(header.getName(), value);
+                }
+            }
+
+            String origin = request.getHeader("Origin");
+            if (!StringUtils.isEmpty(origin)) {
+                response.setHeader("Access-Control-Allow-Origin", origin);
+            }
+        }
+    }
+
+
+    /**
+     * 用户查询服务
+     *
+     * @return
+     */
+    @Bean
+    public UserDetailsService userDetailsService() {
+        return new CmsUserDetailsService();
+    }
+
+    /**
+     * 用户认证 provider
+     *
+     * @return
+     */
+    @Bean
+    public CmsAuthenticationProvider cmsAuthenticationProvider() {
+        return new CmsAuthenticationProvider();
+    }
+
+    /**
+     * 设置那些 URL 忽略权限
+     *
+     * @param web
+     * @throws Exception
+     */
+    @Override
+    public void configure(WebSecurity web) throws Exception {
+        HttpUtil.antMatchers(HttpMethod.OPTIONS);
+        HttpUtil.antMatchers(HttpMethod.GET, "/error", "/login/**", "/logout", "/favicon.ico");
+        web.ignoring().requestMatchers(HttpUtil.getMatchersArray());
+    }
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+
+        // 禁用缓存
+        http.
+                headers().cacheControl();
+//                .and().addHeaderWriter(new StaticHeadersWriter());
+
+        http
+                // 分权限验证
+                .authorizeRequests()
+                .anyRequest().authenticated()
+                .and().csrf().disable()
+                .authorizeRequests().antMatchers("/login", "/logout", "/favicon.ico", "/error", "/file/**").permitAll()
+                .and().addFilterBefore(jwtAuthenticationTokenFilter, SessionManagementFilter.class);
+
+        http
+                .formLogin().successHandler(new RestAuthenticationSuccessHandler())
+                .failureHandler(new RestAuthenticationFailureHandler())
+                .permitAll()
+                .and()
+                .logout().logoutSuccessHandler(new RestLogoutSuccessHandler())
+                .deleteCookies("JSESSIONID", "JWT_TOKEN")
+                .permitAll();
+        //session 管理
+        http.sessionManagement().maximumSessions(5);
+
+        http.exceptionHandling().authenticationEntryPoint(new RestAuthenticationEntryPoint());
+
+    }
+
+    /**
+     * 自定义 认证密码 和 获取用户 服务
+     *
+     * @param auth
+     * @throws Exception
+     */
+    @Autowired
+    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
+        auth
+                .authenticationProvider(cmsAuthenticationProvider())
+                .userDetailsService(userDetailsService());
+    }
+
+    @Bean
+    public AuthenticationManager authenticationManagerBean() throws Exception {
+        return super.authenticationManagerBean();
+    }
+
+    /**
+     * Rest 登陆成功后的处理
+     */
+    public class RestAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
+        @Override
+        public void onAuthenticationSuccess(HttpServletRequest request,
+                                            HttpServletResponse response, Authentication authentication)
+                throws ServletException, IOException {
+
+            if (null != authentication.getPrincipal()) {
+                UserDetails userDetails = (UserDetails) authentication.getPrincipal();
+                //兼容 cookie 和 header x-token 验证两种方式
+                Cookie cookie = new Cookie(cookieName, jwtTokenService.generateToken(userDetails.getUsername()));
+                cookie.setPath("/");
+                cookie.setMaxAge(expiration);
+                cookie.isHttpOnly();
+                response.addCookie(cookie);
+                response.addHeader(tokenHeader, jwtTokenService.generateToken(userDetails.getUsername()));
+                //redisService.set(String.format(LOGIN_TOKEN_FORMAT_KEY,userDetails.getUsername()),userDetails,expiration, TimeUnit.SECONDS);
+                HttpUtil.responseOutWithJson(request, response, APIResult.ok(userDetails));
+                clearAuthenticationAttributes(request);
+            }
+
+        }
+    }
+
+    /**
+     * Rest 登录认证失败后的处理
+     */
+
+    public class RestAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
+        @Override
+        public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
+                throws ServletException, IOException {
+
+            logger.error("登录失败 exception={}", exception);
+            saveException(request, exception);
+
+            //密码错误
+            if (exception instanceof BadCredentialsException) {
+                HttpUtil.error(request, response, CmsWebAPICode.PASSWORD_ERROR);
+            }
+            //查询用户出错
+            else if (exception instanceof UsernameNotFoundException) {
+                HttpUtil.error(request, response, CmsWebAPICode.USERNAME_PASSWORD_ERROR);
+            }
+            //查询用户出错
+            else if (exception instanceof SessionAuthenticationException) {
+                HttpUtil.error(request, response, CmsWebAPICode.MAX_COUNT_SESSION_ERROR);
+            } else {
+                HttpUtil.error(request, response, CmsWebAPICode.AUTHORIZED_FAILD);
+            }
+        }
+    }
+
+    /**
+     * Rest 登出成功后的处理
+     */
+
+    public class RestLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
+        @Override
+        public void onLogoutSuccess(HttpServletRequest request,
+                                    HttpServletResponse response, Authentication authentication)
+                throws IOException, ServletException {
+
+            logger.info("登出成功! ");
+            HttpUtil.delCookies(request, response, "JSESSIONID", cookieName);
+            HttpUtil.ok(request, response);
+
+        }
+    }
+
+    /**
+     * Rest 权限不通过的处理
+     */
+    public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
+        @Override
+        public void commence(HttpServletRequest request,
+                             HttpServletResponse response,
+                             AuthenticationException authException) throws IOException {
+            //原生返回 response.sendError(HttpServletResponse.SC_UNAUTHORIZED,"Authentication Failed: " + authException.getMessage());
+            //cookie失效
+            HttpUtil.error(request, response, CmsWebAPICode.AUTHORIZED_FAILD);
+        }
+    }
+
+    @Bean
+    public RedisOperationsSessionRepository sessionRepository(@Qualifier("sessionRedisTemplate") RedisOperations<Object, Object> sessionRedisTemplate,
+                                                              ApplicationEventPublisher applicationEventPublisher) {
+        RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(sessionRedisTemplate);
+        sessionRepository.setApplicationEventPublisher(applicationEventPublisher);
+        sessionRepository.setDefaultMaxInactiveInterval(expiration);
+        return sessionRepository;
+    }
+}

+ 22 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/controller/resource/AliOSSController.java

@@ -0,0 +1,22 @@
+package cn.aid.cmsweb.controller.resource;
+
+import cn.aid.cmsweb.service.resource.ResourceService;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.data.api.resource.vo.OSSSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+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.RestController;
+
+@RestController
+public class AliOSSController {
+
+    @Autowired
+    private ResourceService resourceService;
+
+    @RequestMapping(value = "/oss/signature", method = RequestMethod.GET)
+    public APIResult<OSSSignature> getSign(@RequestParam("fileName") String fileName) {
+        return resourceService.getSign(fileName);
+    }
+}

+ 46 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/controller/resource/ResourceController.java

@@ -0,0 +1,46 @@
+package cn.aid.cmsweb.controller.resource;
+
+import cn.aid.cmsweb.code.CmsWebAPICode;
+import cn.aid.cmsweb.service.resource.ResourceService;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.page.Page;
+import cn.aid.common.utils.dto.resource.ResourceDTO;
+import cn.aid.common.utils.dto.resource.ResourceSearchDTO;
+import cn.aid.common.utils.util.BeanUtil;
+import cn.aid.common.utils.vo.resource.ResourceVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(value = "/resource")
+@Slf4j
+public class ResourceController {
+
+    @Autowired
+    private ResourceService resourceService;
+
+    @RequestMapping(value = "/list")
+    public APIResult<Page<ResourceVo>> search(ResourceSearchDTO resourceSearchDTO) {
+        return resourceService.search(BeanUtil.convertToMap(resourceSearchDTO));
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<ResourceVo> create(@RequestBody ResourceDTO resourceDTO) {
+        return resourceService.create(resourceDTO);
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<ResourceVo> update(@RequestBody ResourceDTO resourceDTO) {
+        String id = resourceDTO.getId();
+        if (null == id || id.isEmpty()){
+            log.error("id Is Null");
+            return APIResult.error(CmsWebAPICode.PARAMETER_ERROR);
+        }
+        return resourceService.update(id,resourceDTO);
+    }
+
+}

+ 50 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/CampusController.java

@@ -0,0 +1,50 @@
+package cn.aid.cmsweb.controller.user;
+
+import cn.aid.cmsweb.assist.resolver.NeedUser;
+import cn.aid.cmsweb.entity.UserDetails;
+import cn.aid.cmsweb.service.user.CampusService;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.page.Page;
+import cn.aid.common.utils.util.BeanUtil;
+import cn.aid.data.api.user.dto.CampusDTO;
+import cn.aid.data.api.user.dto.CampusSearchDTO;
+import cn.aid.data.api.user.vo.CampusVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping(value = "/campus")
+public class CampusController {
+
+    @Autowired
+    private CampusService campusService;
+
+    @RequestMapping(value = {"/list", "/"}, method = RequestMethod.GET)
+    public APIResult<Page<CampusVo>> search(@NeedUser UserDetails user, CampusSearchDTO campusSearchDTO) {
+        if (!user.isPlatForm()) {
+            String merchantId = user.getMerchantId();
+            campusSearchDTO.setMerchantId(merchantId);
+        }
+        return campusService.search(BeanUtil.convertToMap(campusSearchDTO));
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<CampusVo> create(@RequestBody CampusDTO campusDTO) {
+        return campusService.create(campusDTO);
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<CampusVo> update(@RequestBody CampusDTO campusDTO) {
+        return campusService.update(campusDTO);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public APIResult<Boolean> delete(@PathVariable("id") String id) {
+        return campusService.delete(id);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public APIResult<CampusVo> getCampus(@PathVariable("id") String id) {
+        return campusService.getCampus(id);
+    }
+}

+ 49 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/CmsUserController.java

@@ -0,0 +1,49 @@
+package cn.aid.cmsweb.controller.user;
+
+import cn.aid.cmsweb.assist.resolver.NeedUser;
+import cn.aid.cmsweb.entity.UserDetails;
+import cn.aid.cmsweb.service.user.CmsUserService;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.page.Page;
+import cn.aid.data.api.user.dto.CmsUserDTO;
+import cn.aid.data.api.user.dto.CmsUserSearchDTO;
+import cn.aid.common.utils.util.BeanUtil;
+import cn.aid.data.api.user.vo.CmsUserVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+
+@Slf4j
+@RestController
+@RequestMapping(value = "/cms/user")
+public class CmsUserController {
+
+    @Autowired
+    private CmsUserService cmsUserService;
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<Page<CmsUserVo>> search(@NeedUser UserDetails user, CmsUserSearchDTO searchDTO) {
+        if (!user.isPlatForm()) {
+            String merchantId = user.getMerchantId();
+            searchDTO.setMerchantId(merchantId);
+        }
+        return cmsUserService.search(BeanUtil.convertToMap(searchDTO));
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<CmsUserVo> create(@RequestBody CmsUserDTO userDTO) {
+        return cmsUserService.create(userDTO);
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<CmsUserVo> update(@RequestBody CmsUserDTO userDTO) {
+        return cmsUserService.update(userDTO);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public APIResult<Boolean> delete(@PathVariable("id") String id) {
+        return cmsUserService.delete(id);
+    }
+
+}

+ 50 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/MerchantController.java

@@ -0,0 +1,50 @@
+package cn.aid.cmsweb.controller.user;
+
+
+import cn.aid.cmsweb.service.user.MerchantService;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.page.Page;
+import cn.aid.data.api.user.dto.MerchantDTO;
+import cn.aid.data.api.user.dto.MerchantSearchDTO;
+import cn.aid.common.utils.util.BeanUtil;
+import cn.aid.data.api.user.vo.MerchantVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping(value = "/merchant")
+public class MerchantController {
+
+    @Autowired
+    private MerchantService merchantService;
+
+
+
+    @RequestMapping(value = {"", "/list"}, method = RequestMethod.GET)
+    public APIResult<Page<MerchantVo>> getPage(MerchantSearchDTO searchDTO) {
+        return merchantService.search(BeanUtil.convertToMap(searchDTO));
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<MerchantVo> create(@RequestBody @Valid MerchantDTO merchantDTO) {
+        return merchantService.create(merchantDTO);
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<MerchantVo> update(@RequestBody MerchantDTO merchantDTO) {
+        return merchantService.update(merchantDTO);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public APIResult<Boolean> delete(@PathVariable String id) {
+        return merchantService.delete(id);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public APIResult<MerchantVo> getMerchant(@PathVariable String id) {
+        return merchantService.getMerchant(id);
+    }
+
+}

+ 51 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/TerminalDeviceController.java

@@ -0,0 +1,51 @@
+package cn.aid.cmsweb.controller.user;
+
+import cn.aid.cmsweb.service.user.TerminalDeviceService;
+import cn.aid.cmsweb.service.user.TerminalUserService;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.model.BaseCode;
+import cn.aid.common.utils.constant.RedisKey;
+import cn.aid.common.utils.service.RedisService;
+import cn.aid.data.api.user.vo.TerminalUserVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(value = "/device")
+public class TerminalDeviceController {
+
+    public final static String USER_FORMAT_KEY = RedisKey.USER_FORMAT_KEY;
+
+    @Autowired
+    private TerminalUserService terminalUserService;
+
+    @Autowired
+    private TerminalDeviceService terminalDeviceService;
+
+    @Autowired
+    private RedisService redisService;
+
+    public static String getUserFormatKey(String uid) {
+        return String.format(USER_FORMAT_KEY, uid);
+    }
+
+    public Boolean deleteCacheUser(String userId) {
+        String key = getUserFormatKey(userId);
+        redisService.delete(key);
+        return Boolean.TRUE;
+    }
+
+    @RequestMapping(value = "/unbind/{userId}", method = RequestMethod.DELETE)
+    public APIResult<Boolean> deviceUnbind(@PathVariable String userId) {
+        APIResult<TerminalUserVo> userApiResult = terminalUserService.getUser(userId);
+        if (!userApiResult.getSuccess()) {
+            return APIResult.error(new BaseCode(userApiResult.getCode(), userApiResult.getMessage()));
+        }
+        // 清空缓存
+        deleteCacheUser(userId);
+        return terminalDeviceService.deviceUnbind(userId);
+    }
+}

+ 88 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/TerminalUserController.java

@@ -0,0 +1,88 @@
+package cn.aid.cmsweb.controller.user;
+
+import cn.aid.cmsweb.assist.resolver.NeedUser;
+import cn.aid.cmsweb.entity.UserDetails;
+import cn.aid.cmsweb.service.user.TerminalUserService;
+import cn.aid.common.utils.api.model.APICode;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.page.Page;
+import cn.aid.data.api.auth.dto.AuthDTO;
+import cn.aid.data.api.user.dto.TerminalUserDTO;
+import cn.aid.data.api.user.dto.TerminalUserSearchDTO;
+import cn.aid.common.utils.util.BeanUtil;
+import cn.aid.data.api.user.vo.TerminalUserAuthVo;
+import cn.aid.data.api.user.vo.TerminalUserVo;
+import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping(value = "/user")
+public class TerminalUserController {
+
+    @Autowired
+    private TerminalUserService terminalUserService;
+
+
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<Page<TerminalUserVo>> search(@NeedUser UserDetails user, TerminalUserSearchDTO searchDTO) {
+        log.info("/list request params ,params = {}",JSON.toJSONString(searchDTO));
+
+        if (!user.isPlatForm()) {
+            String merchantId = user.getMerchantId();
+            searchDTO.setMerchantId(merchantId);
+        }
+
+        return terminalUserService.search(BeanUtil.convertToMap(searchDTO));
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<TerminalUserVo> create(@RequestBody TerminalUserDTO terminalUserDTO) {
+        return terminalUserService.create(terminalUserDTO);
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<TerminalUserVo> update(@RequestBody TerminalUserDTO terminalUserDTO) {
+        return terminalUserService.update(terminalUserDTO);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public APIResult<Boolean> delete(@PathVariable("id") String id) {
+        return terminalUserService.delete(id);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public APIResult<TerminalUserVo> getUser(@PathVariable("id") String id) {
+        return terminalUserService.getUser(id);
+    }
+
+    @RequestMapping(value = "/auth", method = RequestMethod.POST)
+    public APIResult updateAuth(@RequestBody AuthDTO dto) {
+        if(StringUtils.isBlank(dto.getId())){
+            log.info("update Auth error ! id is empty");
+            return APIResult.error(APICode.PARAMETER_ERROR);
+        }
+        return terminalUserService.saveOrUpdateAuth(dto);
+    }
+
+    @RequestMapping(value = "/auth/list", method = RequestMethod.GET)
+    public APIResult<Page<TerminalUserAuthVo>> findAuthList(TerminalUserSearchDTO searchDTO) {
+        log.info("/auth/list request params ,params = {}",JSON.toJSONString(searchDTO));
+
+
+        Page<TerminalUserAuthVo> authVoPage = terminalUserService.findAuthList(BeanUtil.convertToMap(searchDTO));
+
+        List<TerminalUserAuthVo> terminalUserAuthVos = authVoPage.getList();
+
+        return APIResult.ok(authVoPage);
+    }
+
+
+
+}

+ 15 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/UserController.java

@@ -0,0 +1,15 @@
+package cn.aid.cmsweb.controller.user;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@Slf4j
+@RestController
+@RequestMapping(value = "/user")
+public class UserController {
+
+
+
+}

+ 33 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/UserDeviceController.java

@@ -0,0 +1,33 @@
+package cn.aid.cmsweb.controller.user;
+
+
+import cn.aid.cmsweb.service.user.UserDeviceService;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.data.api.user.entity.UserDevice;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+
+/**
+ * The controller of user device
+ */
+@Slf4j
+@RestController
+@RequestMapping(value = "/userDevice")
+public class UserDeviceController
+{
+    @Autowired
+    private UserDeviceService userDeviceService;
+
+    @RequestMapping(value = "/list/{uid}", method = RequestMethod.GET)
+    public APIResult<List<UserDevice>> findByUserId(@PathVariable("uid") String uid)
+    {
+        List<UserDevice> list = userDeviceService.findByCondition(uid);
+
+        return APIResult.ok(list);
+    }
+}
+

+ 68 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/controller/user/WhiteUserController.java

@@ -0,0 +1,68 @@
+package cn.aid.cmsweb.controller.user;
+
+import cn.aid.cmsweb.assist.resolver.NeedUser;
+import cn.aid.cmsweb.code.CmsWebAPICode;
+import cn.aid.cmsweb.entity.UserDetails;
+import cn.aid.cmsweb.service.user.WhiteUserService;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.page.Page;
+import cn.aid.data.api.user.dto.WhiteUserDTO;
+import cn.aid.data.api.user.dto.WhiteUserSearchDTO;
+import cn.aid.data.api.user.vo.WhiteUserVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.propertyeditors.CustomDateEditor;
+import org.springframework.web.bind.ServletRequestDataBinder;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+
+@RestController
+@RequestMapping(value = "/white/user")
+public class WhiteUserController {
+
+    @InitBinder
+    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
+        binder.registerCustomEditor(Date.class,
+                new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true));
+    }
+
+    @Autowired
+    private WhiteUserService whiteUserService;
+
+    @RequestMapping(value = "/{userId}", method = RequestMethod.GET)
+    public APIResult<WhiteUserVo> getWhiteUser(@PathVariable String userId) {
+        return whiteUserService.findUserByUserId(userId);
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<WhiteUserVo> create(@NeedUser UserDetails user, @RequestBody WhiteUserDTO whiteUserDTO) {
+        if (!user.isPlatForm()) {
+            return APIResult.error(CmsWebAPICode.ACCESS_DENIED);
+        }
+        return whiteUserService.addWhiteUser(whiteUserDTO);
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<WhiteUserVo> update(@NeedUser UserDetails user, @RequestBody WhiteUserDTO whiteUserDTO) {
+        if (!user.isPlatForm()) {
+            return APIResult.error(CmsWebAPICode.ACCESS_DENIED);
+        }
+        return whiteUserService.updateWhiteUser(whiteUserDTO);
+    }
+
+    @RequestMapping(method = RequestMethod.DELETE)
+    public APIResult<Boolean> delete(@NeedUser UserDetails user, @RequestBody WhiteUserDTO whiteUserDTO) {
+        if (!user.isPlatForm()) {
+            return APIResult.error(CmsWebAPICode.ACCESS_DENIED);
+        }
+        return whiteUserService.deleteWhiteUser(whiteUserDTO);
+    }
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<Page<WhiteUserVo>> search(WhiteUserSearchDTO searchDTO) {
+        return whiteUserService.search(searchDTO);
+    }
+}

+ 346 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/entity/UserDetails.java

@@ -0,0 +1,346 @@
+package cn.aid.cmsweb.entity;
+
+import cn.aid.common.utils.constant.Domain;
+import com.alibaba.fastjson.annotation.JSONField;
+import org.springframework.security.core.CredentialsContainer;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.SpringSecurityCoreVersion;
+import org.springframework.util.Assert;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * @author Dreampie
+ * @date 2015-09-18
+ * @what
+ */
+public class UserDetails implements org.springframework.security.core.userdetails.UserDetails, CredentialsContainer {
+
+    private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
+
+    private Set<GrantedAuthority> authorities;
+
+    private boolean accountNonExpired;
+
+    private boolean accountNonLocked;
+
+    private boolean credentialsNonExpired;
+
+    private boolean enabled;
+
+    private String id;
+
+    private String avatar;
+
+    private Date birthday;
+
+    private String code;
+
+    private Integer domain;
+
+    private String merchantId;
+
+    private String merchantName;
+
+    private String mobileNo;
+
+    private String username;
+
+    private String nickName;
+
+    private String password;
+
+    private Boolean isAdmin;
+
+    public UserDetails() {
+        super();
+    }
+
+    /**
+     * Calls the more complex constructor with all boolean arguments set to {@code true}.
+     */
+    public UserDetails(String username, String password, Collection<? extends GrantedAuthority> authorities) {
+        this(username, password, true, true, true, true, authorities);
+    }
+
+    public UserDetails(String username, String password, boolean enabled,
+                       boolean accountNonExpired, boolean credentialsNonExpired,
+                       boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
+
+        if (((username == null) || "".equals(username)) || (password == null)) {
+            throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
+        }
+
+        this.username = username;
+        this.password = password;
+        this.enabled = enabled;
+        this.accountNonExpired = accountNonExpired;
+        this.credentialsNonExpired = credentialsNonExpired;
+        this.accountNonLocked = accountNonLocked;
+        this.authorities = Collections.unmodifiableSet(sortAuthorities(authorities));
+    }
+
+    public UserDetails(Set<GrantedAuthority> authorities, boolean accountNonExpired, boolean accountNonLocked, boolean credentialsNonExpired, boolean enabled, String id, String username, String avatar, Date birthday, String code, Integer domain, String merchantId, String merchantName, String mobileNo, String nickName, String password, Boolean isAdmin) {
+
+        if (((username == null) || "".equals(username)) || (password == null)) {
+            throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
+        }
+        this.authorities = authorities;
+        this.accountNonExpired = accountNonExpired;
+        this.accountNonLocked = accountNonLocked;
+        this.credentialsNonExpired = credentialsNonExpired;
+        this.enabled = enabled;
+        this.id = id;
+        this.username = username;
+        this.avatar = avatar;
+        this.birthday = birthday;
+        this.code = code;
+        this.domain = domain;
+        this.merchantId = merchantId;
+        this.merchantName=merchantName;
+        this.mobileNo = mobileNo;
+        this.nickName = nickName;
+        this.password = password;
+        this.isAdmin = isAdmin;
+    }
+
+
+    // ~ Methods
+    // ========================================================================================================
+
+    private static SortedSet<GrantedAuthority> sortAuthorities(
+            Collection<? extends GrantedAuthority> authorities) {
+        Assert.notNull(authorities, "Cannot pass a null GrantedAuthority collection");
+        // Ensure array iteration order is predictable (as per
+        // UserDetails.getAuthorities() contract and SEC-717)
+        SortedSet<GrantedAuthority> sortedAuthorities = new TreeSet<GrantedAuthority>(
+                new AuthorityComparator());
+
+        for (GrantedAuthority grantedAuthority : authorities) {
+            Assert.notNull(grantedAuthority,
+                    "GrantedAuthority list cannot contain any null elements");
+            sortedAuthorities.add(grantedAuthority);
+        }
+
+        return sortedAuthorities;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getAvatar() {
+        return avatar;
+    }
+
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
+
+    public Date getBirthday() {
+        return birthday;
+    }
+
+    public void setBirthday(Date birthday) {
+        this.birthday = birthday;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public Integer getDomain() {
+        return domain;
+    }
+
+    public void setDomain(Integer domain) {
+        this.domain = domain;
+    }
+
+    public String getMerchantId() {
+        return merchantId;
+    }
+
+    public void setMerchantId(String merchantId) {
+        this.merchantId = merchantId;
+    }
+
+    public String getMerchantName() {
+        return merchantName;
+    }
+
+    public void setMerchantName(String merchantName) {
+        this.merchantName = merchantName;
+    }
+
+    public String getMobileNo() {
+        return mobileNo;
+    }
+
+    public void setMobileNo(String mobileNo) {
+        this.mobileNo = mobileNo;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getNickName() {
+        return nickName;
+    }
+
+    public void setNickName(String nickName) {
+        this.nickName = nickName;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public Boolean getAdmin() {
+        return isAdmin;
+    }
+
+    public void setAdmin(Boolean admin) {
+        isAdmin = admin;
+    }
+
+    @JSONField(serialize = false)
+    public Collection<GrantedAuthority> getAuthorities() {
+        return authorities;
+    }
+
+    @JSONField(serialize = false)
+    public String getPassword() {
+        return password;
+    }
+
+    @JSONField(serialize = false)
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    @JSONField(serialize = false)
+    public boolean isAccountNonExpired() {
+        return accountNonExpired;
+    }
+
+    @JSONField(serialize = false)
+    public boolean isAccountNonLocked() {
+        return accountNonLocked;
+    }
+
+    @JSONField(serialize = false)
+    public boolean isCredentialsNonExpired() {
+        return credentialsNonExpired;
+    }
+
+    public void eraseCredentials() {
+        password = null;
+    }
+
+
+    /**
+     * Returns {@code true} if the supplied object is a {@code UserDetails} instance with the
+     * same {@code username} value.
+     * <p>
+     * In other words, the objects are equal if they have the same username, representing
+     * the same principal.
+     */
+
+    public boolean equals(Object rhs) {
+        if (rhs instanceof UserDetails) {
+            return username.equals(((UserDetails) rhs).username);
+        }
+        return false;
+    }
+
+    /**
+     * Returns the hashcode of the {@code username}.
+     */
+    @Override
+    public int hashCode() {
+        return username.hashCode();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(super.toString()).append(": ");
+        sb.append("Username: ").append(this.username).append("; ");
+        sb.append("Password: [PROTECTED]; ");
+        sb.append("Enabled: ").append(this.enabled).append("; ");
+        sb.append("AccountNonExpired: ").append(this.accountNonExpired).append("; ");
+        sb.append("credentialsNonExpired: ").append(this.credentialsNonExpired)
+                .append("; ");
+        sb.append("AccountNonLocked: ").append(this.accountNonLocked).append("; ");
+
+        if (!authorities.isEmpty()) {
+            sb.append("Granted Authorities: ");
+
+            boolean first = true;
+            for (GrantedAuthority auth : authorities) {
+                if (!first) {
+                    sb.append(",");
+                }
+                first = false;
+
+                sb.append(auth);
+            }
+        } else {
+            sb.append("Not granted any authorities");
+        }
+
+        return sb.toString();
+    }
+
+    public boolean isPlatForm() {
+        if (domain == null) {
+            return false;
+        }
+        return domain.equals(Domain.PLATFORM);
+    }
+
+    public boolean isMerchant() {
+        if (domain == null) {
+            return false;
+        }
+        return domain.equals(Domain.MERCHANT);
+    }
+
+    public boolean isCp() {
+        if (domain == null) {
+            return false;
+        }
+        return domain.equals(Domain.CP);
+    }
+
+    private static class AuthorityComparator implements Comparator<GrantedAuthority>,
+            Serializable {
+        private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
+
+        public int compare(GrantedAuthority g1, GrantedAuthority g2) {
+            if (g2.getAuthority() == null) {
+                return -1;
+            }
+
+            if (g1.getAuthority() == null) {
+                return 1;
+            }
+
+            return g1.getAuthority().compareTo(g2.getAuthority());
+        }
+    }
+}

+ 45 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/security/CmsAuthenticationProvider.java

@@ -0,0 +1,45 @@
+package cn.aid.cmsweb.security;
+
+import cn.aid.common.utils.util.SecurityUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Component;
+
+import java.util.Collection;
+
+@Component
+public class CmsAuthenticationProvider implements AuthenticationProvider {
+
+    protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Autowired
+    private CmsUserDetailsService cmsUserDetailsService;
+
+    @Override
+    public Authentication authenticate(Authentication authentication)
+                                                throws AuthenticationException {
+        String username = authentication.getName();
+        String password = (String) authentication.getCredentials();
+        UserDetails user = cmsUserDetailsService.loadUserByUsername(username);
+        logger.info("password={}, needPassword={}", password, user.getPassword());
+        //密码匹配验证
+        if (SecurityUtil.MD5(password).equals(user.getPassword())) {
+            Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
+            return new UsernamePasswordAuthenticationToken(user, password, authorities);
+        }
+        throw new BadCredentialsException("Wrong password.");
+    }
+
+    @Override
+    public boolean supports(Class<?> aClass) {
+        return true;
+    }
+}

+ 52 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/security/CmsUserDetailsService.java

@@ -0,0 +1,52 @@
+package cn.aid.cmsweb.security;
+
+import cn.aid.cmsweb.entity.UserDetails;
+import cn.aid.cmsweb.service.user.CmsUserService;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.data.api.user.vo.CmsUserVo;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Component;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@Component
+public class CmsUserDetailsService implements UserDetailsService {
+
+    protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Autowired
+    private CmsUserService cmsUserService;
+
+    @Override
+    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+        logger.info("loadUserByUsername: {}", username);
+        //TODO: 将来加入权限验证
+        Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
+
+        APIResult<CmsUserVo> cmsUserApiResult = cmsUserService.findCmsUserByName(username);
+        if (cmsUserApiResult == null || !cmsUserApiResult.getSuccess() || cmsUserApiResult.getData() == null) {
+            throw new UsernameNotFoundException("用户不存在");
+        }
+
+        CmsUserVo cmsUser = cmsUserApiResult.getData();
+        if (null != cmsUser.getResources()) {
+            cmsUser.getResources().forEach(resouce -> {
+                if (!StringUtils.isEmpty(resouce)) {
+                    GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(resouce.toUpperCase());
+                    grantedAuthorities.add(grantedAuthority);
+                }
+            });
+        }
+        logger.info("grantedAuthorities --> {}", grantedAuthorities);
+        return new UserDetails(grantedAuthorities,true,true,true,true,
+                cmsUser.getId(), cmsUser.getName(), cmsUser.getAvatar(), cmsUser.getBirthday(), null, cmsUser.getDomain(), cmsUser.getMerchantId(), cmsUser.getMerchantName(), cmsUser.getMobile(), cmsUser.getNickName(), cmsUser.getPassword(), cmsUser.getIsAdmin());
+    }
+}

+ 129 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/security/JwtAuthenticationTokenFilter.java

@@ -0,0 +1,129 @@
+package cn.aid.cmsweb.security;
+
+import cn.aid.cmsweb.code.CmsWebAPICode;
+import cn.aid.cmsweb.entity.UserDetails;
+import cn.aid.common.utils.util.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.NamedThreadLocal;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.web.util.matcher.RequestMatcher;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.filter.OncePerRequestFilter;
+import org.springframework.web.util.WebUtils;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@Component
+public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
+
+    private final Logger logger = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class);
+
+    @Autowired
+    private JwtTokenService jwtTokenService;
+
+    @Autowired
+    private CmsUserDetailsService cmsUserDetailsService;
+
+    @Value("${jwt.header:X-Token}")
+    private String tokenHeader;
+
+    @Value("${jwt.cookie:X-Cookie}")
+    private String cookieName;
+
+    @Value("${jwt.expiration:604800}")
+    private Integer expiration;
+
+    private NamedThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<Long>("StopWatch-StartTime");
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
+        startTimeThreadLocal.set(System.currentTimeMillis());//线程绑定变量(该数据只有当前请求的线程可见)
+        logger.info("进入JwtAuthenticationTokenFilter开始 url={} method={}", request.getRequestURI(), request.getMethod());
+        if (HttpMethod.OPTIONS.matches(request.getMethod()) || request.getRequestURL().indexOf("favicon.ico")!=-1) {
+            logger.debug("OPTIONS 请求 忽略 返回200");
+            response.setStatus(HttpStatus.OK.value());
+            HttpUtil.ok(request,response);
+            return;
+        }
+        //如果不想走过滤的url  忽略掉
+        if (HttpUtil.ignoreRequest.size()>0){
+            logger.debug("HttpUtil.ignoreRequest" , JSON.toJSONString(HttpUtil.ignoreRequest));
+            for(RequestMatcher matcher: HttpUtil.ignoreRequest){
+                logger.debug("matcher {}  isM {}" , JSON.toJSONString(matcher),matcher.matches(request));
+                if (matcher.matches(request)){
+                    chain.doFilter(request, response);
+                    return;
+                }
+            }
+        }
+
+
+        String authToken = null;
+        Cookie cookie = WebUtils.getCookie(request, this.cookieName);
+        if (cookie != null && !StringUtils.isEmpty(cookie.getValue())) {
+            authToken = cookie.getValue();
+        }else if(!StringUtils.isEmpty(request.getHeader(this.tokenHeader))){
+            authToken = request.getHeader(this.tokenHeader);
+        }else {
+            HttpUtil.error(request, response, CmsWebAPICode.AUTHORIZED_FAILD);
+            return;
+        }
+
+        //判断先解析 出 username
+        logger.debug("checking authentication for cookie {} authToken {} ", JSON.toJSONString(cookie), authToken);
+        String username = jwtTokenService.getUsernameFromToken(authToken);
+        logger.debug("checking authentication for vo " + username);
+        // 如果解析 username 为空 则重新登录
+        if (username != null) {
+            UserDetails userDetails = null;
+            if (request.getSession().getAttribute("SPRING_SECURITY_CONTEXT_DETAILS") instanceof UserDetails ){
+                userDetails=(UserDetails)request.getSession().getAttribute("SPRING_SECURITY_CONTEXT_DETAILS");
+                request.getSession().setMaxInactiveInterval(expiration);
+            }else {
+                userDetails = this.cmsUserDetailsService.loadUserByUsername(username);
+                request.getSession().setMaxInactiveInterval(expiration);
+                request.getSession().setAttribute("SPRING_SECURITY_CONTEXT_DETAILS",userDetails);
+            }
+            //验证 用户名和 token 的有效性
+            if (jwtTokenService.validateToken(authToken, userDetails) ) {
+                //默认 cookie 一小时有效 但是我半小时 会更新一次 cookie 信息
+                if((System.currentTimeMillis()+expiration*1000/2)>jwtTokenService.getExpirationDateFromToken(authToken).getTime()){
+                    authToken =  jwtTokenService.generateToken(userDetails.getUsername());
+                    cookie = new Cookie(cookieName,authToken);
+                    cookie.setPath("/");
+                    cookie.setMaxAge(expiration);
+                    cookie.isHttpOnly();
+                    response.addCookie(cookie);
+                    //redisTemplate.opsForValue().set(String.format(LOGIN_TOKEN_FORMAT_KEY,username),userDetails,expiration, TimeUnit.SECONDS);
+                }
+                //正确的情况下 认证成功!
+                chain.doFilter(request, response);
+                logger.info("进入JwtAuthenticationTokenFilter结束 url={}",request.getRequestURI());
+                long endTime = System.currentTimeMillis();
+                long consumeTime = endTime - startTimeThreadLocal.get();
+                if(consumeTime > 500) {
+                    logger.info(" 请求: {} consume {} millis", request.getRequestURI(), consumeTime);
+                }
+                return;
+            }else{
+                HttpUtil.error(request, response, CmsWebAPICode.INVALID_TOKEN);
+                return;
+            }
+        }else {
+            HttpUtil.error(request, response, CmsWebAPICode.INVALID_TOKEN);
+            return;
+        }
+
+    }
+}

+ 130 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/security/JwtTokenService.java

@@ -0,0 +1,130 @@
+package cn.aid.cmsweb.security;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Component;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Jonsy
+ *
+ */
+@Component
+public class JwtTokenService implements Serializable {
+
+    private static final long serialVersionUID = -3301605591108950415L;
+
+    static final String CLAIM_KEY_USERNAME = "sub";
+    static final String CLAIM_KEY_CREATED = "created";
+
+    @Value("${jwt.secret:ohq3TGwT}")
+    private String secret;
+
+    @Value("${jwt.expiration:604800}")
+    private Long expiration;
+
+    public String getUsernameFromToken(String token) {
+        String username;
+        try {
+            final Claims claims = getClaimsFromToken(token);
+            username = claims.getSubject();
+        } catch (Exception e) {
+            username = null;
+        }
+        return username;
+    }
+
+
+    public Date getExpirationDateFromToken(String token) {
+        Date expiration;
+        try {
+            final Claims claims = getClaimsFromToken(token);
+            expiration = claims.getExpiration();
+        } catch (Exception e) {
+            expiration = null;
+        }
+        return expiration;
+    }
+
+
+    private Claims getClaimsFromToken(String token) {
+        Claims claims;
+        try {
+            claims = Jwts.parser()
+                    .setSigningKey(secret)
+                    .parseClaimsJws(token)
+                    .getBody();
+        } catch (Exception e) {
+            claims = null;
+        }
+        return claims;
+    }
+
+    private Date generateExpirationDate() {
+        return new Date(System.currentTimeMillis() + expiration * 1000);
+    }
+
+    private Boolean isTokenExpired(String token) {
+        final Date expiration = getExpirationDateFromToken(token);
+        return expiration.before(new Date());
+    }
+
+    public String generateToken(String userName) {
+        Map<String, Object> claims = new HashMap<>();
+        claims.put(CLAIM_KEY_USERNAME, userName);
+        claims.put(CLAIM_KEY_CREATED, new Date());
+        return generateToken(claims);
+    }
+
+    private String generateToken(Map<String, Object> claims) {
+        return Jwts.builder()
+                .setClaims(claims)
+                .setExpiration(generateExpirationDate())
+                .signWith(SignatureAlgorithm.HS512, secret)
+                .compact();
+    }
+
+    public String refreshToken(String token) {
+        String refreshedToken;
+        try {
+            final Claims claims = getClaimsFromToken(token);
+            claims.put(CLAIM_KEY_CREATED, new Date());
+            refreshedToken = generateToken(claims);
+        } catch (Exception e) {
+            refreshedToken = null;
+        }
+        return refreshedToken;
+    }
+
+    public Boolean validateToken(String token, UserDetails userDetails) {
+        final String username = getUsernameFromToken(token);
+        return (username.equals(userDetails.getUsername())&& !isTokenExpired(token));
+    }
+
+
+    public static void main(String[] args){
+        //String zhaoshunToken = new JwtTokenService().generateToken("zhaoshun");
+
+
+        Map<String, Object> claims = new HashMap<>();
+        claims.put(CLAIM_KEY_USERNAME, "zhaoshun");
+        claims.put(CLAIM_KEY_CREATED, new Date());
+        //String s = new JwtTokenService().generateToken(claims);
+
+
+        String compact = Jwts.builder()
+                .setClaims(claims)
+                .setExpiration(new Date(System.currentTimeMillis() + 604800 * 1000))
+                .signWith(SignatureAlgorithm.HS512, "ohq3TGwT")
+                .compact();
+        System.out.println(compact);
+
+    }
+}

+ 35 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/service/resource/ResourceService.java

@@ -0,0 +1,35 @@
+package cn.aid.cmsweb.service.resource;
+
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.page.Page;
+import cn.aid.common.utils.dto.resource.ResourceDTO;
+import cn.aid.common.utils.vo.resource.ResourceVo;
+import cn.aid.data.api.resource.vo.OSSSignature;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@FeignClient(value = "${service.resource.name}")
+public interface ResourceService {
+
+    @RequestMapping(value = "/resource/list")
+    APIResult<Page<ResourceVo>> search(@RequestParam Map<String, Object> searchDTO);
+
+    @RequestMapping(value = "/resource", method = RequestMethod.POST)
+    APIResult<ResourceVo> create(@RequestBody ResourceDTO resourceDTO);
+
+    @RequestMapping(value = "/resource/batch", method = RequestMethod.GET)
+    APIResult<Map<String, ResourceVo>> getBatch(@RequestParam("id") List<String> ids);
+
+    @RequestMapping(value = "/oss/signature", method = RequestMethod.GET)
+    APIResult<OSSSignature> getSign(@RequestParam("fileName") String fileName);
+
+    @RequestMapping(value = "/resource/{id}", method = RequestMethod.PUT)
+    APIResult<ResourceVo> update(@PathVariable("id") String id, @RequestBody ResourceDTO resourceDTO);
+
+    @RequestMapping(value = "/resource/audioImg/batch", method = RequestMethod.GET)
+    Map<String, ResourceVo> getAudioImgBatch(@RequestParam("ids") List<String> ids);
+}
+

+ 36 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/CampusService.java

@@ -0,0 +1,36 @@
+package cn.aid.cmsweb.service.user;
+
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.page.Page;
+import cn.aid.data.api.user.dto.CampusDTO;
+import cn.aid.data.api.user.vo.CampusVo;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@FeignClient(name = "${service.user.name}")
+public interface CampusService {
+
+    @RequestMapping(value = "/campus/list", method = RequestMethod.GET)
+    APIResult<Page<CampusVo>> search(@RequestParam Map<String, Object> searchDTO);
+
+    @RequestMapping(value = "/campus", method = RequestMethod.GET)
+    APIResult<List<CampusVo>> findByCondition(@RequestParam Map<String, Object> params);
+
+    @RequestMapping(value = "/campus", method = RequestMethod.POST)//, consumes = MediaType.APPLICATION_JSON_VALUE)//, consumes = "application/json")
+    APIResult<CampusVo> create(@RequestBody CampusDTO campusDTO);
+
+    @RequestMapping(value = "/campus", method = RequestMethod.PUT)
+    APIResult<CampusVo> update(@RequestBody CampusDTO campusDTO);
+
+    @RequestMapping(value = "/campus/{id}", method = RequestMethod.DELETE)
+    APIResult<Boolean> delete(@PathVariable("id") String id);
+
+    @RequestMapping(value = "/campus/{id}", method = RequestMethod.GET)
+    APIResult<CampusVo> getCampus(@PathVariable("id") String id);
+
+    @RequestMapping(value = "/campus/ids", method = RequestMethod.GET)
+    APIResult<Map<String, CampusVo>> findByIds(@RequestParam("id") List<String> ids);
+}

+ 32 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/CmsUserService.java

@@ -0,0 +1,32 @@
+package cn.aid.cmsweb.service.user;
+
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.page.Page;
+import cn.aid.data.api.user.dto.CmsUserDTO;
+import cn.aid.data.api.user.vo.CmsUserVo;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+
+@FeignClient(name = "${service.user.name}")
+public interface CmsUserService {
+
+    @RequestMapping(value = "cms/user", method = RequestMethod.GET)
+    APIResult<CmsUserVo> findCmsUserByName(@RequestParam("name") String userName);
+
+    @RequestMapping(value = "cms/user/list", method = RequestMethod.GET)
+    APIResult<Page<CmsUserVo>> search(@RequestParam Map<String, Object> searchDTO);
+
+    @RequestMapping(value = "cms/user", method = RequestMethod.POST)
+    APIResult<CmsUserVo> create(@RequestBody CmsUserDTO userDTO);
+
+    @RequestMapping(value = "cms/user", method = RequestMethod.PUT)
+    APIResult<CmsUserVo> update(@RequestBody CmsUserDTO userDTO);
+
+    @RequestMapping(value = "cms/user/{id}", method = RequestMethod.DELETE)
+    APIResult<Boolean> delete(@PathVariable("id") String id);
+
+}
+

+ 106 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/MerchantInfoSetService.java

@@ -0,0 +1,106 @@
+package cn.aid.cmsweb.service.user;
+
+import cn.aid.cmsweb.service.user.MerchantService;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.data.api.user.vo.MerchantVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class MerchantInfoSetService<V> {
+
+    @Autowired
+    private MerchantService merchantService;
+
+    public Map<String, MerchantVo> findByIds(List<String> idList) {
+        if (CollectionUtils.isEmpty(idList)) {
+            log.error("merchant idList is empty!");
+            return new HashMap<>();
+        }
+
+        APIResult<Map<String, MerchantVo>> merchantAPIResult = merchantService.findByIds(idList);
+        if (!merchantAPIResult.getSuccess()) {
+            log.error("api error: {}", merchantAPIResult.getMessage());
+            return new HashMap<>();
+        }
+
+        return merchantAPIResult.getData();
+    }
+
+    public MerchantVo findById(String merchantId) {
+        APIResult<MerchantVo> merchantVoAPIResult = merchantService.getMerchant(merchantId);
+        if (!merchantVoAPIResult.getSuccess()) {
+            log.error("api error: {}", merchantVoAPIResult.getMessage());
+            return null;
+        }
+        return merchantVoAPIResult.getData();
+    }
+
+    public void setMerchantInfo(V v) {
+        try {
+            Class clazz = v.getClass();
+            Field idField = clazz.getDeclaredField("merchantId");
+            idField.setAccessible(true);
+            String merchantId = (String) idField.get(v);
+            idField.setAccessible(false);
+
+            Field nameField = clazz.getDeclaredField("merchantName");
+            nameField.setAccessible(true);
+            MerchantVo merchantVo = findById(merchantId);
+            nameField.set(v, merchantVo.getName());
+            nameField.setAccessible(false);
+
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    public void setMerchantInfo(List<V> list) {
+        if (CollectionUtils.isEmpty(list)) return;
+
+        List<String> merchantIdList = new ArrayList<>();
+        for (V v : list) {
+            try {
+                Class clazz = v.getClass();
+                Field idField = clazz.getDeclaredField("merchantId");
+                idField.setAccessible(true);
+                String merchantId = (String) idField.get(v);
+                idField.setAccessible(false);
+                merchantIdList.add(merchantId);
+            } catch (Exception e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+
+        Map<String, MerchantVo> merchantVoMap = findByIds(merchantIdList);
+        for (V v : list) {
+            try {
+                Class clazz = v.getClass();
+                Field idField = clazz.getDeclaredField("merchantId");
+                idField.setAccessible(true);
+                String merchantId = (String) idField.get(v);
+                idField.setAccessible(false);
+
+                MerchantVo merchantVo = merchantVoMap.get(merchantId);
+                Field nameField = clazz.getDeclaredField("merchantName");
+                nameField.setAccessible(true);
+                nameField.set(v, merchantVo.getName());
+                nameField.setAccessible(false);
+            } catch (Exception e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+    }
+}

+ 34 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/MerchantService.java

@@ -0,0 +1,34 @@
+package cn.aid.cmsweb.service.user;
+
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.page.Page;
+import cn.aid.data.api.user.dto.MerchantDTO;
+import cn.aid.data.api.user.vo.MerchantVo;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@FeignClient(name = "${service.user.name}")
+public interface MerchantService {
+
+    @RequestMapping(value = "/merchant/list", method = RequestMethod.GET)
+    APIResult<Page<MerchantVo>> search(@RequestParam Map<String, Object> searchDTO);
+
+    @RequestMapping(value = "/merchant", method = RequestMethod.POST)
+    APIResult<MerchantVo> create(@RequestBody MerchantDTO merchantDTO);
+
+    @RequestMapping(value = "/merchant", method = RequestMethod.PUT)
+    APIResult<MerchantVo> update(@RequestBody MerchantDTO merchantDTO);
+
+    @RequestMapping(value = "/merchant/{id}", method = RequestMethod.DELETE)
+    APIResult<Boolean> delete(@PathVariable("id") String id);
+
+    @RequestMapping(value = "/merchant/{id}", method = RequestMethod.GET)
+    APIResult<MerchantVo> getMerchant(@PathVariable("id") String id);
+
+    @RequestMapping(value = "/merchant/ids", method = RequestMethod.GET)
+    APIResult<Map<String, MerchantVo>> findByIds(@RequestParam("id") List<String> ids);
+
+}

+ 14 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/TerminalDeviceService.java

@@ -0,0 +1,14 @@
+package cn.aid.cmsweb.service.user;
+
+import cn.aid.common.utils.api.model.APIResult;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@FeignClient(name = "${service.user.name}")
+public interface TerminalDeviceService {
+
+    @RequestMapping(value = "/device/unbind", method = RequestMethod.DELETE)
+    APIResult<Boolean> deviceUnbind(@RequestParam("userId") String userId);
+}

+ 47 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/TerminalUserService.java

@@ -0,0 +1,47 @@
+package cn.aid.cmsweb.service.user;
+
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.page.Page;
+import cn.aid.data.api.auth.dto.AuthDTO;
+import cn.aid.data.api.user.dto.TerminalUserDTO;
+import cn.aid.data.api.user.vo.TerminalUserAuthVo;
+import cn.aid.data.api.user.vo.TerminalUserVo;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@FeignClient(name = "${service.user.name}")
+public interface TerminalUserService {
+
+    @RequestMapping(value = "/user/list", method = RequestMethod.GET)
+    APIResult<Page<TerminalUserVo>> search(@RequestParam Map<String, Object> searchDTO);
+
+    @RequestMapping(value = "/user", method = RequestMethod.POST)
+    APIResult<TerminalUserVo> create(@RequestBody TerminalUserDTO userDTO);
+
+    @RequestMapping(value = "/user", method = RequestMethod.PUT)
+    APIResult<TerminalUserVo> update(@RequestBody TerminalUserDTO userDTO);
+
+    @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
+    APIResult<Boolean> delete(@PathVariable("id") String id);
+
+    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
+    APIResult<TerminalUserVo> getUser(@PathVariable("id") String id);
+
+    @RequestMapping(value = "/user", method = RequestMethod.GET)
+    APIResult<List<TerminalUserVo>> findByCondition(@RequestParam Map<String, Object> searchDTO);
+
+    @RequestMapping(value = "/campus/ids", method = RequestMethod.GET)
+    APIResult<List<TerminalUserVo>> findByCampusIds(@RequestParam("id") List<String> ids);
+
+    @RequestMapping(value = "/user/ids", method = RequestMethod.GET)
+    APIResult<List<TerminalUserVo>> findByIds(@RequestParam("id") List<String> ids);
+
+    @RequestMapping(value = "/user/auth/list", method = RequestMethod.GET)
+    Page<TerminalUserAuthVo> findAuthList(@RequestParam Map<String,Object> searchDTO);
+
+    @RequestMapping(value = "/user/auth", method = RequestMethod.POST)
+    APIResult saveOrUpdateAuth(@RequestBody AuthDTO dto);
+}

+ 14 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/UserDeviceService.java

@@ -0,0 +1,14 @@
+package cn.aid.cmsweb.service.user;
+
+import cn.aid.data.api.user.entity.UserDevice;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@FeignClient(name = "${service.user.name}")
+public interface UserDeviceService
+{
+    @RequestMapping(value = "/userDevice/list/{uid}", method = RequestMethod.GET)
+    List<UserDevice> findByCondition(@PathVariable("uid") String uid);
+}

+ 29 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/service/user/WhiteUserService.java

@@ -0,0 +1,29 @@
+package cn.aid.cmsweb.service.user;
+
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.page.Page;
+import cn.aid.data.api.user.dto.WhiteUserDTO;
+import cn.aid.data.api.user.dto.WhiteUserSearchDTO;
+import cn.aid.data.api.user.vo.WhiteUserVo;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+@FeignClient(name = "${service.user.name}")
+public interface WhiteUserService {
+
+    @RequestMapping(value = "/white/user/{userId}", method = RequestMethod.GET)
+    APIResult<WhiteUserVo> findUserByUserId(@PathVariable("userId") String userId);
+
+    @RequestMapping(value = "/white/user", method = RequestMethod.POST)
+    APIResult<WhiteUserVo> addWhiteUser(@RequestBody WhiteUserDTO whiteUserDTO);
+
+    @RequestMapping(value = "/white/user", method = RequestMethod.PUT)
+    APIResult<WhiteUserVo> updateWhiteUser(@RequestBody WhiteUserDTO whiteUserDTO);
+
+    @RequestMapping(value = "/white/user", method = RequestMethod.DELETE)
+    APIResult<Boolean> deleteWhiteUser(@RequestBody WhiteUserDTO whiteUserDTO);
+
+    @RequestMapping(value = "/white/user/list", method = RequestMethod.POST)
+    APIResult<Page<WhiteUserVo>> search(@RequestBody WhiteUserSearchDTO searchDTO);
+
+}

+ 10 - 0
aid-cms-web/src/main/java/cn/aid/cmsweb/utils/DTOConverter.java

@@ -0,0 +1,10 @@
+package cn.aid.cmsweb.utils;
+
+
+
+public class DTOConverter {
+
+
+
+
+}

+ 19 - 0
aid-cms-web/src/main/resources/bootstrap.yml

@@ -0,0 +1,19 @@
+spring:
+  application:
+    name: cms-web
+  cloud:
+    config:
+      uri: http://127.0.0.1:8921
+      label: master
+      profile: ${profile:local}
+
+feign:
+  httpclient:
+    enabled: true
+
+server:
+  port: 8500
+
+#logging:
+#  level:
+#    root: debug

+ 16 - 0
aid-cms-web/src/test/java/cn/aid/cmsweb/CmsWebApplicationTests.java

@@ -0,0 +1,16 @@
+package cn.aid.cmsweb;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class CmsWebApplicationTests {
+
+	@Test
+	public void contextLoads() {
+	}
+
+}

+ 40 - 0
aid-cms-web/src/test/java/cn/aid/cmsweb/service/product/proxy/WareServiceProxyTest.java

@@ -0,0 +1,40 @@
+package cn.aid.cmsweb.service.product.proxy;
+
+import cn.aid.cmsweb.CmsWebApplication;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@Slf4j
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = CmsWebApplication.class)
+public class WareServiceProxyTest {
+
+//    @Autowired
+//    private WareServiceProxy wareService;
+    @Test
+    public void search() throws Exception {
+//        SearchDTO searchDTO = new SearchDTO();
+//        APIResult<Page<WareVo>> result = wareService.search(searchDTO);
+//        log.info(JSON.toJSONString(result));
+    }
+
+    @Test
+    public void create() throws Exception {
+    }
+
+    @Test
+    public void update() throws Exception {
+    }
+
+    @Test
+    public void delete() throws Exception {
+    }
+
+    @Test
+    public void getWare() throws Exception {
+    }
+
+}

+ 12 - 0
aid-cms-web/src/test/java/cn/aid/cmsweb/service/trade/order/OrderClientTest.java

@@ -0,0 +1,12 @@
+package cn.aid.cmsweb.service.trade.order;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class OrderClientTest {
+    @Test
+    public void pay() throws Exception {
+    }
+
+}

+ 18 - 0
aid-cms-web/src/test/java/cn/aid/cmsweb/service/user/CampusServiceTest.java

@@ -0,0 +1,18 @@
+package cn.aid.cmsweb.service.user;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import static org.junit.Assert.*;
+
+public class CampusServiceTest {
+
+    @Autowired
+    private TerminalUserService terminalUserService;
+
+    @Test
+    public void create() throws Exception {
+
+    }
+
+}

+ 128 - 0
aid-common-utils/pom.xml

@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>cn.aid</groupId>
+	<artifactId>aid-common-utils</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<packaging>jar</packaging>
+
+	<name>${project.artifactId}</name>
+	<description>Common Utils for Spring Boot</description>
+
+    <parent>
+        <groupId>cn.aid</groupId>
+        <artifactId>aid</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+		<java.version>1.8</java.version>
+	</properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+        </dependency>
+        <!-- aop 切面 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+        <!-- redis 组件 -->
+        <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-redis</artifactId>
+            <version>1.8.3.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.38</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.25</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.16.16</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <version>4.3.12.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>3.1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-web</artifactId>
+            <version>4.2.2.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.8.10</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.4</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>2.4</version>
+                <configuration>
+                    <attach>true</attach>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>compile</phase>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.3</version>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                    <encoding>UTF-8</encoding>
+                    <showWarnings>true</showWarnings>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 43 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/Proxy/ProxyWrapper.java

@@ -0,0 +1,43 @@
+package cn.aid.common.utils.Proxy;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+
+class ProxyWrapper implements InvocationHandler {
+    //被代理类的对象
+    private Object target;
+
+    //绑定被代理对象
+    public Object bind(Object target){
+        this.target = target;
+        //返回实现了被代理类所实现的所有接口的Object对象,即动态代理,需要强制转型
+        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
+                target.getClass().getInterfaces(), this);
+    }
+
+    //日志记录方法
+    private void log(String method){
+        return;
+    }
+
+    /**
+     * <p>Discription:覆盖InvocationHandler接口中的invoke()方法</p>
+     * @param proxy 需要代理的对象
+     * @param method 真实主体要调用的执行方法
+     * @param args 调用方法时传递的参数
+     * @return
+     * @throws Throwable
+     * @author       : lcma
+     * @update       : 2016年10月9日下午2:46:29
+     */
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        //使用反射中的invoke()对方法进行动态调用
+        Object obj = method.invoke(this.target, args);
+        return obj;
+    }
+
+}
+

+ 52 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/api/Cache.java

@@ -0,0 +1,52 @@
+package cn.aid.common.utils.api;
+
+public class Cache {
+
+    private String key; //缓存ID
+    private Object value; //缓存数据
+    private long validTime; //有效时间
+    private long timeOut; //是否终止
+
+    public Cache() {
+        super();
+    }
+
+    public Cache(String key, Object value, long validTime) {
+        this.key = key;
+        this.value = value;
+        this.timeOut = System.currentTimeMillis() + validTime;
+        this.validTime = validTime;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    public void setValue(Object value) {
+        this.value = value;
+    }
+
+    public long getTimeOut() {
+        return timeOut;
+    }
+
+    public void setTimeOut(long timeOut) {
+        this.timeOut = timeOut;
+    }
+
+    public long getValidTime() {
+        return validTime;
+    }
+
+    public void setValidTime(long validTime) {
+        this.validTime = validTime;
+    }
+}

+ 32 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/api/annotation/SerializedField.java

@@ -0,0 +1,32 @@
+package cn.aid.common.utils.api.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/*
+    Filetered Json Annotation
+ */
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface SerializedField {
+    /**
+     * 需要返回的字段
+     * @return
+     */
+    String[] includes() default {};
+
+    /**
+     * 需要去除的字段
+     * @return
+     */
+    String[] excludes() default {};
+
+    /**
+     * 数据是否需要加密
+     * @return
+     */
+    boolean encode() default true;
+}

+ 22 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/api/controller/advice/GlobalExceptionHandler.java

@@ -0,0 +1,22 @@
+package cn.aid.common.utils.api.controller.advice;
+
+import cn.aid.common.utils.api.model.APICode;
+import cn.aid.common.utils.api.model.APIResult;
+import cn.aid.common.utils.api.model.BaseCode;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+    @ExceptionHandler({Exception.class})
+    @ResponseBody
+    public APIResult handleException(HttpServletRequest request, Exception e){
+        e.printStackTrace();
+        return APIResult.error(new BaseCode(APICode._C_SERVER_ERROR, e.getMessage()));
+    }
+}
+

+ 64 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/api/model/APICode.java

@@ -0,0 +1,64 @@
+package cn.aid.common.utils.api.model;
+
+public class APICode {
+
+    public final static int _C_OK = 200 ;
+    public final static BaseCode OK = new BaseCode(_C_OK, null);
+
+    public final static int _C_ACCESS_DENIED = 403;
+    public final static BaseCode ACCESS_DENIED  = new BaseCode(_C_ACCESS_DENIED, "访问被拒绝");
+
+    public final static int _C_NOT_FOUND = 404 ;
+    public final static BaseCode NOT_FOUND = new BaseCode(_C_NOT_FOUND, "资源不存在");
+
+    public final static int _C_SERVER_ERROR = 500;
+    public final static BaseCode SERVER_ERROR = new BaseCode(_C_SERVER_ERROR, "请求处理异常");
+
+    public final static int _C_PARAMETER_ERROR = 400;
+    public final static BaseCode PARAMETER_ERROR = new BaseCode(_C_PARAMETER_ERROR, "参数错误");
+
+    public final static int _C_UNAUTHORIZED = 401;
+    public final static BaseCode UNAUTHORIZED = new BaseCode(_C_UNAUTHORIZED, "未认证");
+
+    public final static int _C_INVALID_TOKEN = 402;
+    public final static BaseCode INVALID_TOKEN = new BaseCode(_C_INVALID_TOKEN, "无效的Token");
+
+    public final static int _C_REMOTE_SERVER_ERROR = 600;
+    public final static BaseCode REMOTE_SERVER_ERROR = new BaseCode(_C_REMOTE_SERVER_ERROR, "远程服务器错误");
+
+    public final static int _C_ALREADY_EXISTS = 700;
+    public final static BaseCode ALREADY_EXISTS = new BaseCode(_C_ALREADY_EXISTS, "数据已存在");
+
+    public final static int _C_NOT_EXISTS = 800;
+    public final static BaseCode NOT_EXISTS = new BaseCode(_C_NOT_EXISTS, "数据不存在 ");
+
+    public final static int _C_OPERATE_ERROR = 1001;
+    public final static BaseCode OPERATE_ERROR = new BaseCode(_C_OPERATE_ERROR, "操作失败");
+
+    public final static int _C_CAN_NOT_DEL = 1002;
+    public final static BaseCode CAN_NOT_DEL = new BaseCode(_C_CAN_NOT_DEL, "无法删除");
+
+    // cms flag code
+    public final static int _CMS_WEB_FLAG = 10000;
+
+    // vo flag code
+    public final static int _USER_SERVICE_FLAG = 20000;
+
+    // api flag code
+    public final static int _API_WEB_FLAG = 30000;
+
+    // product flag code
+    public final static int _PRODUCT_SERVICE_FLAG = 40000;
+
+    // trade flag code
+    public final static int _TRADE_SERVICE_FLAG = 50000;
+
+    public static BaseCode ok(String message) {
+        return new BaseCode(_C_OK, message);
+    }
+
+    public static BaseCode error(String message) {
+        return new BaseCode(_C_PARAMETER_ERROR, message);
+    }
+
+}

+ 95 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/api/model/APIResult.java

@@ -0,0 +1,95 @@
+package cn.aid.common.utils.api.model;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.io.Serializable;
+
+public class APIResult<T> implements Serializable {
+
+    private int code;
+
+    private boolean success = false;
+
+    private String message;
+
+    private T data;
+
+    public APIResult() {
+    }
+
+    public APIResult(BaseCode baseCode) {
+        this.message = baseCode.getMessage();
+
+        int code = baseCode.getCode();
+        this.code = code;
+
+        if (code == 200) {
+            this.success = true;
+        }
+    }
+
+    private APIResult(BaseCode baseCode, T data) {
+        this(baseCode);
+        this.data = data;
+    }
+
+    public static APIResult ok() {
+        return new APIResult(APICode.OK);
+    }
+
+    public static APIResult ok(Object value) {
+        return new APIResult(APICode.OK, value);
+    }
+
+    public static APIResult ok(String name, Object value) {
+        return new APIResult(APICode.OK, toMap(name, value));
+    }
+
+    public static APIResult ok(Map<String, Object> data) {
+        return new APIResult(APICode.OK, data);
+    }
+
+    public static APIResult error(BaseCode baseCode) {
+        return new APIResult(baseCode);
+    }
+
+    public boolean getSuccess() {
+        return success;
+    }
+
+    public void setSuccess(boolean success) {
+        this.success = success;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    public static <K, V> Map<K, V> toMap(final K k, final V v) {
+        return new HashMap<K, V>() {
+            {
+                this.put(k, v);
+            }
+        };
+    }
+}

+ 35 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/api/model/BaseCode.java

@@ -0,0 +1,35 @@
+package cn.aid.common.utils.api.model;
+
+import com.alibaba.fastjson.JSON;
+
+public class BaseCode {
+
+    protected int code;
+
+    protected String message;
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public BaseCode() {}
+
+    public BaseCode(int code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public static void main(String[] args) {
+        BaseCode example = new BaseCode(200, "success");
+        System.out.print(JSON.toJSONString(example));
+    }
+
+}

+ 115 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/api/page/Page.java

@@ -0,0 +1,115 @@
+package cn.aid.common.utils.api.page;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+
+public class Page<E> implements Pageable<List<E>> ,Serializable {
+
+	// 当前页
+	private int pageNo = 1;
+	
+	// 当前页大小
+	private int pageSize = 10;
+	
+	// 总条数
+	private long totalSize = 0;
+
+	// 数据内容
+	private List<E> list;
+
+	public Page() {
+		// 默认构造方法
+	}
+	
+	public Page(Long totalSize) {
+	    this(totalSize, null, null);
+	}
+	
+	public Page(Long totalSize, Integer pageNo) {
+	    this(totalSize, pageNo, null);
+	}
+	
+	public Page(Long totalSize, Integer pageNo, Integer pageSize) {
+	    if (totalSize != null && totalSize >= 0) {
+	        this.totalSize = totalSize;
+        }
+
+        if (pageNo != null && pageNo > 0) {
+	        this.pageNo = pageNo;
+        }
+
+        if (pageSize != null && pageSize > 0) {
+	        this.pageSize = pageSize;
+        }
+    }
+
+	@Override
+	public int getTotalNo() {
+		if (totalSize == 0 || pageSize == 0) {
+		    return 1;
+        }else {
+		    return (int) ((totalSize / pageSize) + (totalSize % pageSize == 0 ? 0 : 1));
+        }
+	}
+
+	@Override
+	public long getTotalSize() {
+		return totalSize;
+	}
+
+	@Override
+	public int getPageNo() {
+		return pageNo > getTotalNo() ? getTotalNo() : pageNo;
+	}
+
+	@Override
+	public int getPageSize() {
+		return pageSize;
+	}
+
+	@Override
+    @JSONField(name = "hasNext")
+	public boolean hasNext() {
+		return getPageNo() < getTotalNo();
+	}
+
+	@Override
+    @JSONField(name = "hasPrevious")
+	public boolean hasPrevious() {
+		return getPageNo() > 1;
+	}
+
+	public void setPageNo(int pageNo) {
+		this.pageNo = pageNo;
+	}
+
+	public void setPageSize(int pageSize) {
+		this.pageSize = pageSize;
+	}
+
+	public void setTotalSize(int totalSize) {
+		this.totalSize = totalSize;
+	}
+
+	@Override
+	public List<E> getList() {
+		return null == list ? Collections.emptyList() : list;
+	}
+
+	public void setList(List<E> list) {
+	    this.list = list;
+    }
+
+	@Override
+	public long getStart() {
+		return (getPageNo() - 1) * getPageSize();
+	}
+
+//	public static void main(String[] args) {
+//	    Page<Integer> page = new Page(100L, 1, 20);
+//	    System.out.print(JSON.toJSONString(page));
+//    }
+}

+ 20 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/api/page/Pageable.java

@@ -0,0 +1,20 @@
+package cn.aid.common.utils.api.page;
+
+public interface Pageable<E> {
+	
+	E getList();
+
+	int getTotalNo();
+	
+	long getTotalSize();
+
+	int getPageNo();
+	
+	int getPageSize();
+	
+	long getStart();
+	
+	boolean hasNext();
+	
+	boolean hasPrevious();
+}

+ 113 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/configuration/RedisConfiguration.java

@@ -0,0 +1,113 @@
+/**
+ * 文件名:@RedisConfiguration.java <br/>
+ * 包名: configuration <br/>
+ * @author tomas <br/>
+*/
+
+
+package cn.aid.common.utils.configuration;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.interceptor.KeyGenerator;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.data.redis.cache.DefaultRedisCachePrefix;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import java.lang.reflect.Method;
+
+/**
+ * 类名:RedisConfiguration  <br />
+ *
+ * 功能:redis相关配置
+ *
+ * @author tomas <br />
+ * 创建时间:2016年8月16日 上午10:00:53  <br />
+ * @version 2016年8月16日
+*/
+@Configuration
+@EnableCaching
+public class RedisConfiguration extends CachingConfigurerSupport implements EnvironmentAware {
+
+	// 应用环境信息
+	protected Environment environment;
+
+	@Bean
+	public KeyGenerator keyGenerator() {
+		return new KeyGenerator() {
+			@Override
+			public Object generate(Object target, Method method, Object... params) {
+				StringBuilder sb = new StringBuilder();
+				sb.append(target.getClass().getName());
+				sb.append(method.getName());
+				for (Object obj : params) {
+					sb.append(obj.toString());
+				}
+				return sb.toString();
+			}
+		};
+	}
+
+	@Bean
+	public CacheManager cacheManager(RedisTemplate redisTemplate) {
+		RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
+		rcm.setCachePrefix(new DefaultRedisCachePrefix());
+		//设置缓存过期时间 30天
+		rcm.setDefaultExpiration(2592000);//秒
+		return rcm;
+	}
+
+	@Bean(name="redisTemplate")
+	public RedisTemplate<?, ?> redisTemplate(JedisConnectionFactory factory){
+		RedisTemplate<?, ?> template = new RedisTemplate<>();
+		template.setConnectionFactory(factory);
+		factory.setDatabase(2);
+
+		//初始化序列化框架(StringRedisSerializer)
+		/*StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+		JdkSerializationRedisSerializer redisSerializer = new JdkSerializationRedisSerializer();
+
+		template.setDefaultSerializer(redisSerializer);
+		//设置key的序列化方式
+		template.setKeySerializer(stringRedisSerializer);
+		//设置value的序列化方式
+		template.setValueSerializer(redisSerializer);
+		//设置hash key的序列化方式
+		template.setHashKeySerializer(stringRedisSerializer);
+		//设置hash value的序列化方式
+		template.setHashValueSerializer(redisSerializer);
+
+		template.afterPropertiesSet();
+		return template;*/
+
+		Jackson2JsonRedisSerializer jackson2JsonRedisSerializer=new Jackson2JsonRedisSerializer(Object.class);
+		ObjectMapper om=new ObjectMapper();
+		om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+		om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
+		jackson2JsonRedisSerializer.setObjectMapper(om);
+		template.setKeySerializer(new StringRedisSerializer());
+		template.setValueSerializer(jackson2JsonRedisSerializer);
+		template.setDefaultSerializer(jackson2JsonRedisSerializer);
+		template.setHashValueSerializer(jackson2JsonRedisSerializer);
+		template.setHashKeySerializer(new StringRedisSerializer());
+		template.afterPropertiesSet();
+		return template;
+
+	}
+	@Override
+	public void setEnvironment(Environment environment) {
+		this.environment = environment;
+	}
+
+}

+ 41 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/constant/Constant.java

@@ -0,0 +1,41 @@
+package cn.aid.common.utils.constant;
+
+public class Constant {
+
+    public final static String ROOT_ID = "1";
+
+    public final static String APP_CODE = "1001";
+
+    public final static String BIZ_CODE = "1001";
+
+    public final static String MRegEx = "^\\d{4}$";
+
+    public final static String PLAT_MERCHANT_ID = "1";
+
+
+    // 序列号表的配置
+    public final static String ORDER_MODULE = "order-service";
+
+    public final static String MASTER_ORDER_CODE = "1";
+
+    public final static String SLAVE_ORDER_CODE = "2";
+
+
+    public final static class EntryType {
+        // {0,1,2} eid, mobile, wechatid
+        public final static int EID = 0;
+
+        public final static int MOBILE = 1;
+
+        public final static int WECHAT = 2;
+    }
+
+    public final static class ProductType {
+
+        public final static int VIP = 0;
+
+        public final static int PKG = 1;
+
+        public final static int COURSE = 2;
+    }
+}

+ 9 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/constant/Domain.java

@@ -0,0 +1,9 @@
+package cn.aid.common.utils.constant;
+
+public final class Domain {
+
+    public static final int CP = 1010;
+    public static final int PLATFORM = 2010;
+    public static final int MERCHANT = 3010;
+
+}

+ 10 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/constant/PlatForm.java

@@ -0,0 +1,10 @@
+package cn.aid.common.utils.constant;
+
+import java.io.Serializable;
+
+public class PlatForm implements Serializable{
+
+    public final static String TV = "tv";
+
+    public final static String WEB = "web";
+}

+ 8 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/constant/RedisKey.java

@@ -0,0 +1,8 @@
+package cn.aid.common.utils.constant;
+
+public class RedisKey {
+
+    public static final String LOGIN_TOKEN_FORMAT_KEY = "api:web:token:%s";
+
+    public static final String USER_FORMAT_KEY = "api:web:user:%s";
+}

+ 14 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/constant/ResourceType.java

@@ -0,0 +1,14 @@
+package cn.aid.common.utils.constant;
+
+public class ResourceType {
+
+    public final static int VIDEO = 0;
+
+    public final static int AUDIO = 1;
+
+    public final static int LIVE = 2;
+
+    public final static int IMG = 3;
+
+    public final static int AUDIO_IMG = 4;
+}

+ 40 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/dto/resource/ResourceDTO.java

@@ -0,0 +1,40 @@
+package cn.aid.common.utils.dto.resource;
+
+import cn.aid.common.utils.enums.BaseStatusEnum;
+import lombok.Data;
+import lombok.ToString;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@ToString
+public class ResourceDTO implements Serializable {
+
+    private String id;
+
+    private String rid;
+
+    private String code;
+
+    private String name;
+
+    private Integer type;
+
+    private String format;
+
+    private String quality;
+
+    private Long size;
+
+    private String path;
+
+    private BaseStatusEnum status;
+
+    private Date gmtCreated;
+
+    private Date gmtModified;
+
+    private String url;
+
+}

+ 25 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/dto/resource/ResourceSearchDTO.java

@@ -0,0 +1,25 @@
+package cn.aid.common.utils.dto.resource;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ResourceSearchDTO implements Serializable {
+
+    private String code;
+
+    private String name;
+
+    private Integer type;
+
+    private String sort;
+
+    private Integer by;
+
+    private Integer pageNo = 1;
+
+    private Integer pageSize = 10;
+
+}
+

+ 25 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/dto/search/SearchDTO.java

@@ -0,0 +1,25 @@
+package cn.aid.common.utils.dto.search;
+
+import cn.aid.common.utils.enums.BaseStatusEnum;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class SearchDTO implements Serializable {
+
+    private String code;
+
+    private String name;
+
+    private BaseStatusEnum status;
+
+    private String sort;
+
+    private Integer by;
+
+    private Integer pageNo = 1;
+
+    private Integer pageSize = 10;
+
+}

+ 22 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/enums/BaseOrderEnum.java

@@ -0,0 +1,22 @@
+package cn.aid.common.utils.enums;
+
+public enum BaseOrderEnum {
+
+    DESC("降序"), ASC("升序");
+
+    private String name;
+
+    BaseOrderEnum(String name) {
+        this.name = name;  
+    }
+      
+    public String getName() {  
+        return name;  
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
+
+}  

+ 31 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/enums/BaseStatusEnum.java

@@ -0,0 +1,31 @@
+package cn.aid.common.utils.enums;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public enum BaseStatusEnum {
+
+    NORMAL("正常"),DEL("已删除"),DISABLE("禁用");
+
+    public static Set<BaseStatusEnum>  show = new HashSet<>();
+
+    static {
+        show.add(BaseStatusEnum.NORMAL);
+    }
+
+    String name;
+
+    BaseStatusEnum( String name) {
+        this.name = name;  
+    }
+      
+    public String getName() {  
+        return name;  
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
+
+}  

+ 20 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/enums/CourseSubTypeEnum.java

@@ -0,0 +1,20 @@
+package cn.aid.common.utils.enums;
+
+public enum CourseSubTypeEnum {
+    UNIT("单元"), LESSON("课");
+
+    String name;
+
+    CourseSubTypeEnum(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
+}

+ 29 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/enums/EventTypeEnum.java

@@ -0,0 +1,29 @@
+package cn.aid.common.utils.enums;
+
+public enum EventTypeEnum {
+
+    DOWNLOAD("DOWNLOAD"), DELETE("DELETE"), UPDATE("UPDATE");
+
+    private String desc;
+
+    EventTypeEnum(String desc) {
+        this.desc = desc;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public static EventTypeEnum getByName(String name) {
+        if (name == null) {
+            return null;
+        }
+        for (EventTypeEnum favoritesType : values()) {
+            if (favoritesType.name().equals(name)) {
+                return favoritesType;
+            }
+        }
+        return null;
+    }
+}
+

+ 10 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/enums/GenderEnum.java

@@ -0,0 +1,10 @@
+package cn.aid.common.utils.enums;
+
+public enum GenderEnum {
+    MALE, FEMALE;
+
+    @Override
+    public String toString() {
+        return this.name();
+    }
+}

+ 20 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/enums/LedgerTypeEnum.java

@@ -0,0 +1,20 @@
+package cn.aid.common.utils.enums;
+
+public enum LedgerTypeEnum {
+    COURSE("购买课程"), CHARGE("充值");
+
+    String name;
+
+    LedgerTypeEnum(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
+}

+ 42 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/enums/PlatformTypeEnum.java

@@ -0,0 +1,42 @@
+package cn.aid.common.utils.enums;
+
+public enum PlatformTypeEnum {
+
+    APP("app"), TV("TV"), WEIXIN("微信"), WINDOWS("windows");
+
+    private String desc;
+
+    PlatformTypeEnum(String desc) {
+        this.desc = desc;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public static PlatformTypeEnum getByName(String name) {
+        if (name == null) {
+            return null;
+        }
+        for (PlatformTypeEnum favoritesType : values()) {
+            if (favoritesType.name().equals(name)) {
+                return favoritesType;
+            }
+        }
+        return null;
+    }
+
+    public static PlatformTypeEnum getByNameWithDefault(String name) {
+        if (name == null) {
+            return TV;
+        }
+        for (PlatformTypeEnum favoritesType : values()) {
+            if (favoritesType.name().equals(name)) {
+                return favoritesType;
+            }
+        }
+        return TV;
+    }
+
+}
+

+ 15 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/enums/ProductTypeEnum.java

@@ -0,0 +1,15 @@
+package cn.aid.common.utils.enums;
+
+public enum ProductTypeEnum {
+    COURSE("课程"), SUPPORT("周边"), PACKAGE("课程包"), TRAINING("师训");
+
+    private String name;
+
+    ProductTypeEnum(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+}

+ 20 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/enums/ReceiptTypeEnum.java

@@ -0,0 +1,20 @@
+package cn.aid.common.utils.enums;
+
+public enum ReceiptTypeEnum {
+    COMMON("普通"), SPECIAL("专用");
+
+    String name;
+
+    ReceiptTypeEnum(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
+}

+ 31 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/enums/WareTypeEnum.java

@@ -0,0 +1,31 @@
+package cn.aid.common.utils.enums;
+
+public enum WareTypeEnum {
+
+    SINGLE("单图"), MULTI("多图"), VIDEO("视频");
+
+    public static boolean contains(WareTypeEnum type) {
+        for (WareTypeEnum typeEnum : values()) {
+            if (typeEnum.equals(type)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    String name;
+
+    WareTypeEnum(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
+
+}

+ 7 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/exception/CommonException.java

@@ -0,0 +1,7 @@
+package cn.aid.common.utils.exception;
+
+public class CommonException extends ServiceException {
+    public CommonException (int code , String message){
+        super(message);
+    }
+}

+ 0 - 0
aid-common-utils/src/main/java/cn/aid/common/utils/exception/DuplicateValueException.java


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