Browse Source

初始导入

yingp 7 years ago
commit
7d4842feeb
100 changed files with 3925 additions and 0 deletions
  1. 54 0
      README.md
  2. 16 0
      applications/document/pom.xml
  3. 16 0
      applications/money/pom.xml
  4. 25 0
      applications/pom.xml
  5. 15 0
      applications/product/pom.xml
  6. 16 0
      applications/purchase/pom.xml
  7. 16 0
      applications/sale/pom.xml
  8. 16 0
      applications/storage/pom.xml
  9. 30 0
      base-servers/account/account-api/pom.xml
  10. 33 0
      base-servers/account/account-api/src/main/java/com/usoftchina/saas/account/api/AccountApi.java
  11. 23 0
      base-servers/account/account-dto/pom.xml
  12. 91 0
      base-servers/account/account-dto/src/main/java/com/usoftchina/saas/account/dto/AccountDTO.java
  13. 92 0
      base-servers/account/account-dto/src/main/java/com/usoftchina/saas/account/dto/AccountRegDTO.java
  14. 68 0
      base-servers/account/account-dto/src/main/java/com/usoftchina/saas/account/dto/CompanyDTO.java
  15. 52 0
      base-servers/account/account-server/pom.xml
  16. 19 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/AccountApplication.java
  17. 105 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/AccountController.java
  18. 98 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/CompanyController.java
  19. 8 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/ResourceController.java
  20. 8 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/RoleController.java
  21. 35 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/AccountMapper.java
  22. 11 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/AccountRoleMapper.java
  23. 49 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/CompanyMapper.java
  24. 11 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/ResourcesMapper.java
  25. 11 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/RoleMapper.java
  26. 11 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/RoleResourceMapper.java
  27. 80 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/po/Account.java
  28. 32 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/po/AccountRole.java
  29. 103 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/po/Company.java
  30. 130 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/po/Resources.java
  31. 50 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/po/Role.java
  32. 32 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/po/RoleResource.java
  33. 54 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/AccountService.java
  34. 41 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/CompanyService.java
  35. 47 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/impl/AccountServiceImpl.java
  36. 47 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/impl/CompanyServiceImpl.java
  37. 40 0
      base-servers/account/account-server/src/main/resources/application.yml
  38. 15 0
      base-servers/account/account-server/src/main/resources/banner.txt
  39. 64 0
      base-servers/account/account-server/src/main/resources/logback-spring.xml
  40. 116 0
      base-servers/account/account-server/src/main/resources/mapper/AccountMapper.xml
  41. 4 0
      base-servers/account/account-server/src/main/resources/mapper/AccountRoleMapper.xml
  42. 89 0
      base-servers/account/account-server/src/main/resources/mapper/CompanyMapper.xml
  43. 4 0
      base-servers/account/account-server/src/main/resources/mapper/ResourcesMapper.xml
  44. 4 0
      base-servers/account/account-server/src/main/resources/mapper/RoleMapper.xml
  45. 4 0
      base-servers/account/account-server/src/main/resources/mapper/RoleResourceMapper.xml
  46. 22 0
      base-servers/account/pom.xml
  47. 46 0
      base-servers/admin-server/pom.xml
  48. 25 0
      base-servers/admin-server/src/main/java/com/usoftchina/saas/admin/AdminApplication.java
  49. 42 0
      base-servers/admin-server/src/main/java/com/usoftchina/saas/admin/config/WebSecurityConfig.java
  50. 29 0
      base-servers/admin-server/src/main/resources/application.yml
  51. 15 0
      base-servers/admin-server/src/main/resources/banner.txt
  52. 64 0
      base-servers/admin-server/src/main/resources/logback-spring.xml
  53. 34 0
      base-servers/auth/auth-api/pom.xml
  54. 24 0
      base-servers/auth/auth-api/src/main/java/com/usoftchina/saas/auth/api/AuthApi.java
  55. 23 0
      base-servers/auth/auth-api/src/main/java/com/usoftchina/saas/auth/api/TokenApi.java
  56. 44 0
      base-servers/auth/auth-api/src/main/java/com/usoftchina/saas/auth/cache/TokenCache.java
  57. 43 0
      base-servers/auth/auth-client/pom.xml
  58. 20 0
      base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/EnableAuthClient.java
  59. 17 0
      base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/annotation/IgnoreAuth.java
  60. 28 0
      base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/configuration/AuthAutoConfiguration.java
  61. 40 0
      base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/configuration/AuthConfig.java
  62. 53 0
      base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/interceptor/AuthRestInterceptor.java
  63. 28 0
      base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/interceptor/ServiceFeignInterceptor.java
  64. 43 0
      base-servers/auth/auth-common/pom.xml
  65. 30 0
      base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/event/AuthRemoteEvent.java
  66. 101 0
      base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/jwt/JwtHelper.java
  67. 43 0
      base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/jwt/JwtInfo.java
  68. 59 0
      base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/jwt/TokenVO.java
  69. 22 0
      base-servers/auth/auth-dto/pom.xml
  70. 71 0
      base-servers/auth/auth-dto/src/main/java/com/usoftchina/saas/auth/dto/TokenDTO.java
  71. 88 0
      base-servers/auth/auth-server/pom.xml
  72. 17 0
      base-servers/auth/auth-server/src/main/java/com/usoftchina/saas/auth/AuthApplication.java
  73. 51 0
      base-servers/auth/auth-server/src/main/java/com/usoftchina/saas/auth/controller/AuthController.java
  74. 42 0
      base-servers/auth/auth-server/src/main/resources/application.yml
  75. BIN
      base-servers/auth/auth-server/src/main/resources/auth/pri.key
  76. 15 0
      base-servers/auth/auth-server/src/main/resources/banner.txt
  77. 64 0
      base-servers/auth/auth-server/src/main/resources/logback-spring.xml
  78. 4 0
      base-servers/auth/auth-server/src/main/resources/mapper/AccountMapper.xml
  79. 4 0
      base-servers/auth/auth-server/src/main/resources/mapper/AccountRoleMapper.xml
  80. 4 0
      base-servers/auth/auth-server/src/main/resources/mapper/ResourcesMapper.xml
  81. 4 0
      base-servers/auth/auth-server/src/main/resources/mapper/RoleMapper.xml
  82. 4 0
      base-servers/auth/auth-server/src/main/resources/mapper/RoleResourceMapper.xml
  83. 23 0
      base-servers/auth/pom.xml
  84. 38 0
      base-servers/eureka-server/pom.xml
  85. 17 0
      base-servers/eureka-server/src/main/java/com/usoftchina/saas/eureka/EurekaApplication.java
  86. 19 0
      base-servers/eureka-server/src/main/java/com/usoftchina/saas/eureka/config/WebSecurityConfig.java
  87. 33 0
      base-servers/eureka-server/src/main/resources/application.yml
  88. 15 0
      base-servers/eureka-server/src/main/resources/banner.txt
  89. 64 0
      base-servers/eureka-server/src/main/resources/logback-spring.xml
  90. 46 0
      base-servers/file/file-api/pom.xml
  91. 62 0
      base-servers/file/file-api/src/main/java/com/usoftchina/saas/file/api/FileApi.java
  92. 23 0
      base-servers/file/file-dto/pom.xml
  93. 60 0
      base-servers/file/file-dto/src/main/java/com/usoftchina/saas/file/dto/BaseFolder.java
  94. 179 0
      base-servers/file/file-dto/src/main/java/com/usoftchina/saas/file/dto/FileDTO.java
  95. 31 0
      base-servers/file/file-dto/src/main/java/com/usoftchina/saas/file/dto/FileListDTO.java
  96. 32 0
      base-servers/file/file-dto/src/main/java/com/usoftchina/saas/file/dto/FolderDTO.java
  97. 18 0
      base-servers/file/file-dto/src/main/java/com/usoftchina/saas/file/dto/FolderToSaveDTO.java
  98. 59 0
      base-servers/file/file-server/pom.xml
  99. 21 0
      base-servers/file/file-server/src/main/java/com/usoftchina/saas/file/FileApplication.java
  100. 37 0
      base-servers/file/file-server/src/main/java/com/usoftchina/saas/file/controller/FileController.java

+ 54 - 0
README.md

@@ -0,0 +1,54 @@
+## 项目结构:
+
+```
+├─saas-platform
+│  │  
+│  ├─applications-----------------------------业务应用
+│  |  ├─document------------------------------基础资料
+│  |  ├─money---------------------------------资金
+│  |  ├─product-------------------------------物料
+│  |  ├─purchase------------------------------采购
+│  |  ├─sale----------------------------------销售
+│  |  ├─storage-------------------------------库存
+│  │ 
+│  ├─base-servers-----------------------------基础服务
+│  |  ├─admin-server--------------------------spring-boot-admin监控中心
+│  |  ├─account-------------------------------账户中心
+│  |  |  |─account-api------------------------账户中心api
+│  |  |  |─account-dto------------------------账户中心数据传输对象
+│  |  |  |─account-server---------------------账户中心服务
+│  |  ├─auth----------------------------------鉴权中心
+│  |  |  |─auth-api---------------------------鉴权中心api
+│  |  |  |─auth-client------------------------鉴权中心客户端
+│  |  |  |─auth-common------------------------鉴权中心公共包
+│  |  |  |─auth-dto---------------------------鉴权中心数据传输对象
+│  |  |  |─auth-server------------------------鉴权中心服务
+│  |  ├─eureka-server-------------------------服务注册中心
+│  |  ├─file----------------------------------文件服务
+│  |  |  |─file-api---------------------------文件服务api
+│  |  |  |─file-dto---------------------------文件服务数据传输对象
+│  |  |  |─file-server------------------------文件服务
+│  |  ├─gateway-server------------------------统一网关
+│  |  ├─mail----------------------------------邮件服务
+│  |  |  |─mail-api---------------------------邮件服务api
+│  |  |  |─mail-dto---------------------------邮件服务数据传输对象
+│  |  |  |─mail-server------------------------邮件服务
+│  |  ├─sms-----------------------------------短信服务
+│  |  |  |─sms-api----------------------------短信服务api
+│  |  |  |─sms-dto----------------------------短信服务数据传输对象
+│  |  |  |─sms-server-------------------------短信服务
+│  |  ├─zipkin-server-------------------------zipkin分布式服务链路跟踪
+│  │ 
+│  ├─doc--------------------------------------项目文档
+│  │
+│  ├─framework--------------------------------框架部分
+│  |  ├─core----------------------------------框架基础
+│  │
+│  ├─frontend---------------------------------前端
+│  |  ├─web-----------------------------------web前端
+│  │ 
+│  ├─script-----------------------------------脚本
+│  |  ├─mysql---------------------------------mysql脚本
+│  |  |  |─init-------------------------------mysql数据库初始化脚本
+│  │
+```

+ 16 - 0
applications/document/pom.xml

@@ -0,0 +1,16 @@
+<?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">
+    <parent>
+        <artifactId>applications</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>document</artifactId>
+    <description>base document server</description>
+
+
+</project>

+ 16 - 0
applications/money/pom.xml

@@ -0,0 +1,16 @@
+<?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">
+    <parent>
+        <artifactId>applications</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>money</artifactId>
+    <description>money server</description>
+
+
+</project>

+ 25 - 0
applications/pom.xml

@@ -0,0 +1,25 @@
+<?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">
+    <parent>
+        <artifactId>saas-platform</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>applications</artifactId>
+    <packaging>pom</packaging>
+    <description>applications</description>
+    <modules>
+        <module>product</module>
+        <module>purchase</module>
+        <module>sale</module>
+        <module>storage</module>
+        <module>money</module>
+        <module>document</module>
+    </modules>
+
+
+</project>

+ 15 - 0
applications/product/pom.xml

@@ -0,0 +1,15 @@
+<?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">
+    <parent>
+        <artifactId>applications</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>product</artifactId>
+    <description>product server</description>
+
+</project>

+ 16 - 0
applications/purchase/pom.xml

@@ -0,0 +1,16 @@
+<?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">
+    <parent>
+        <artifactId>applications</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>purchase</artifactId>
+    <description>purchase server</description>
+
+
+</project>

+ 16 - 0
applications/sale/pom.xml

@@ -0,0 +1,16 @@
+<?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">
+    <parent>
+        <artifactId>applications</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>sale</artifactId>
+    <description>sale server</description>
+
+
+</project>

+ 16 - 0
applications/storage/pom.xml

@@ -0,0 +1,16 @@
+<?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">
+    <parent>
+        <artifactId>applications</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>storage</artifactId>
+    <description>storage server</description>
+
+
+</project>

+ 30 - 0
base-servers/account/account-api/pom.xml

@@ -0,0 +1,30 @@
+<?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">
+    <parent>
+        <artifactId>account</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>account-api</artifactId>
+    <description>account api</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>account-dto</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>core</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 33 - 0
base-servers/account/account-api/src/main/java/com/usoftchina/saas/account/api/AccountApi.java

@@ -0,0 +1,33 @@
+package com.usoftchina.saas.account.api;
+
+import com.usoftchina.saas.account.dto.AccountDTO;
+import com.usoftchina.saas.base.Result;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * @author yingp
+ * @date 2018/10/6
+ */
+@FeignClient(name = "account-server")
+public interface AccountApi {
+    /**
+     * 校验用户和密码
+     *
+     * @param username 登录名
+     * @param password 明文密码
+     * @return
+     */
+    @GetMapping(value = "/api/account/pwd/check")
+    Result<AccountDTO> validByUsernameAndPwd(@RequestParam(value = "username") String username, @RequestParam(value = "password") String password);
+
+    /**
+     * 按用户名查找账户
+     *
+     * @param username
+     * @return
+     */
+    @GetMapping(value = "/api/account")
+    Result<AccountDTO> getAccount(@RequestParam(value = "username") String username);
+}

+ 23 - 0
base-servers/account/account-dto/pom.xml

@@ -0,0 +1,23 @@
+<?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">
+    <parent>
+        <artifactId>account</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>account-dto</artifactId>
+    <description>account data transfer object</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+</project>

+ 91 - 0
base-servers/account/account-dto/src/main/java/com/usoftchina/saas/account/dto/AccountDTO.java

@@ -0,0 +1,91 @@
+package com.usoftchina.saas.account.dto;
+
+import io.swagger.annotations.ApiModel;
+
+import java.io.Serializable;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+@ApiModel(value = "Account", description = "账户信息")
+public class AccountDTO implements Serializable {
+    private Long id;
+    private String username;
+    private String realname;
+    private String email;
+    private String mobile;
+    /**
+     * 账号类型 0 - 管理员
+     */
+    private Integer type;
+    private long companyId;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getRealname() {
+        return realname;
+    }
+
+    public void setRealname(String realname) {
+        this.realname = realname;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getMobile() {
+        return mobile;
+    }
+
+    public void setMobile(String mobile) {
+        this.mobile = mobile;
+    }
+
+    public Integer getType() {
+        return type;
+    }
+
+    public void setType(Integer type) {
+        this.type = type;
+    }
+
+    public long getCompanyId() {
+        return companyId;
+    }
+
+    public void setCompanyId(long companyId) {
+        this.companyId = companyId;
+    }
+
+    @Override
+    public String toString() {
+        return "AccountDTO{" +
+                "username='" + username + '\'' +
+                ", realname='" + realname + '\'' +
+                ", email='" + email + '\'' +
+                ", mobile='" + mobile + '\'' +
+                ", type=" + type +
+                ", companyId=" + companyId +
+                '}';
+    }
+}

+ 92 - 0
base-servers/account/account-dto/src/main/java/com/usoftchina/saas/account/dto/AccountRegDTO.java

@@ -0,0 +1,92 @@
+package com.usoftchina.saas.account.dto;
+
+import io.swagger.annotations.ApiModel;
+
+import java.io.Serializable;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+@ApiModel(value = "AccountReg", description = "账户注册信息")
+public class AccountRegDTO implements Serializable {
+    private String username;
+    private String password;
+    private String realname;
+    private String email;
+    private String mobile;
+    /**
+     * 账号类型 0 - 管理员
+     */
+    private Integer type;
+    private long companyId;
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getRealname() {
+        return realname;
+    }
+
+    public void setRealname(String realname) {
+        this.realname = realname;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getMobile() {
+        return mobile;
+    }
+
+    public void setMobile(String mobile) {
+        this.mobile = mobile;
+    }
+
+    public Integer getType() {
+        return type;
+    }
+
+    public void setType(Integer type) {
+        this.type = type;
+    }
+
+    public long getCompanyId() {
+        return companyId;
+    }
+
+    public void setCompanyId(long companyId) {
+        this.companyId = companyId;
+    }
+
+    @Override
+    public String toString() {
+        return "AccountRegDTO{" +
+                "username='" + username + '\'' +
+                ", password='" + password + '\'' +
+                ", realname='" + realname + '\'' +
+                ", email='" + email + '\'' +
+                ", mobile='" + mobile + '\'' +
+                ", type=" + type +
+                ", companyId=" + companyId +
+                '}';
+    }
+}

+ 68 - 0
base-servers/account/account-dto/src/main/java/com/usoftchina/saas/account/dto/CompanyDTO.java

@@ -0,0 +1,68 @@
+package com.usoftchina.saas.account.dto;
+
+import io.swagger.annotations.ApiModel;
+
+import java.io.Serializable;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+@ApiModel(value = "Company", description = "公司信息")
+public class CompanyDTO implements Serializable{
+    /**
+     * 唯一名称
+     */
+    private String name;
+    /**
+     * 商业登记证号
+     */
+    private String businessCode;
+    private String address;
+    /**
+     * 二级域名
+     */
+    private String domain;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getBusinessCode() {
+        return businessCode;
+    }
+
+    public void setBusinessCode(String businessCode) {
+        this.businessCode = businessCode;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    @Override
+    public String toString() {
+        return "CompanyDTO{" +
+                "name='" + name + '\'' +
+                ", businessCode='" + businessCode + '\'' +
+                ", address='" + address + '\'' +
+                ", domain='" + domain + '\'' +
+                '}';
+    }
+}

+ 52 - 0
base-servers/account/account-server/pom.xml

@@ -0,0 +1,52 @@
+<?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">
+    <parent>
+        <artifactId>account</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>account-server</artifactId>
+    <description>account server</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>account-dto</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <!-- db -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+        </dependency>
+        <!-- sleuth -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.amqp</groupId>
+            <artifactId>spring-rabbit</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 19 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/AccountApplication.java

@@ -0,0 +1,19 @@
+package com.usoftchina.saas.account;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+@SpringBootApplication
+@EnableEurekaClient
+@EnableTransactionManagement
+public class AccountApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(AccountApplication.class, args);
+    }
+}

+ 105 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/AccountController.java

@@ -0,0 +1,105 @@
+package com.usoftchina.saas.account.controller;
+
+import com.usoftchina.saas.account.dto.AccountDTO;
+import com.usoftchina.saas.account.dto.AccountRegDTO;
+import com.usoftchina.saas.account.po.Account;
+import com.usoftchina.saas.account.service.AccountService;
+import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.exception.ExceptionCode;
+import com.usoftchina.saas.utils.BeanMapper;
+import com.usoftchina.saas.utils.RegexpUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+@RestController
+@RequestMapping("/api/account")
+public class AccountController {
+
+    @Autowired
+    private AccountService accountService;
+
+    /**
+     * 注册
+     *
+     * @param accountRegDTO
+     * @return
+     */
+    @PostMapping("/register")
+    public Result register(@RequestBody AccountRegDTO accountRegDTO) {
+        // 判断是否已注册
+        Account account = accountService.findByUsername(accountRegDTO.getUsername());
+        if (null != account) {
+            return Result.error(ExceptionCode.USER_NAME_EXIST);
+        }
+        account = accountService.findByMobile(accountRegDTO.getMobile());
+        if (null != account) {
+            return Result.error(ExceptionCode.USER_MOBILE_EXIST);
+        }
+        account = accountService.findByEmail(accountRegDTO.getEmail());
+        if (null != account) {
+            return Result.error(ExceptionCode.USER_EMAIL_EXIST);
+        }
+
+        account = BeanMapper.map(accountRegDTO, Account.class);
+        account.setSalt(account.getMobile());
+        account.setPassword(accountService.getEncryptedPassword(account.getPassword(), account.getSalt()));
+        accountService.save(account);
+
+        return Result.success();
+    }
+
+    /**
+     * 校验用户和密码
+     *
+     * @param username 登录名
+     * @param password 明文密码
+     * @return
+     */
+    @GetMapping(value = "/pwd/check")
+    public Result<AccountDTO> validByUsernameAndPwd(@RequestParam(value = "username") String username, @RequestParam(value = "password") String password) {
+        Account account = getAccountByUsername(username);
+        if (null == account) {
+            return Result.error(ExceptionCode.USER_NOT_EXIST);
+        }
+
+        boolean checked = accountService.checkPwd(account, password);
+        if (!checked) {
+            return Result.error(ExceptionCode.USER_PWD_ERROR);
+        }
+
+        return Result.success();
+    }
+
+    private Account getAccountByUsername(String username) {
+        Account account;
+        if (RegexpUtils.isMobile(username)) {
+            account = accountService.findByMobile(username);
+        } else if (RegexpUtils.isEmail(username)) {
+            account = accountService.findByEmail(username);
+        } else {
+            account = accountService.findByUsername(username);
+        }
+        return account;
+    }
+
+    /**
+     * 按用户名查找账户
+     *
+     * @param username
+     * @return
+     */
+    @GetMapping
+    public Result<AccountDTO> getAccount(@RequestParam(value = "username") String username) {
+        Account account = getAccountByUsername(username);
+        if (null == account) {
+            return Result.error(ExceptionCode.USER_NOT_EXIST);
+        }
+
+        AccountDTO accountDTO = BeanMapper.map(account, AccountDTO.class);
+        return Result.success(accountDTO);
+    }
+}

+ 98 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/CompanyController.java

@@ -0,0 +1,98 @@
+package com.usoftchina.saas.account.controller;
+
+import com.usoftchina.saas.account.dto.CompanyDTO;
+import com.usoftchina.saas.account.po.Company;
+import com.usoftchina.saas.account.service.CompanyService;
+import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.exception.ExceptionCode;
+import com.usoftchina.saas.utils.BeanMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+@RestController
+@RequestMapping("/api/account/company")
+public class CompanyController {
+
+    @Autowired
+    private CompanyService companyService;
+
+    /**
+     * 注册
+     *
+     * @param companyDTO
+     * @return
+     */
+    @PostMapping("/register")
+    public Result register(@RequestBody CompanyDTO companyDTO) {
+        // 判断是否已注册
+        Company company = companyService.findByName(companyDTO.getName());
+        if (null != company) {
+            return Result.error(ExceptionCode.COMPANY_NAME_EXIST);
+        }
+        company = companyService.findByBusinessCode(companyDTO.getBusinessCode());
+        if (null != company) {
+            return Result.error(ExceptionCode.COMPANY_CODE_EXIST);
+        }
+        company = companyService.findByDomain(companyDTO.getDomain());
+        if (null != company) {
+            return Result.error(ExceptionCode.COMPANY_DOMAIN_EXIST);
+        }
+
+        company = BeanMapper.map(companyDTO, Company.class);
+        companyService.save(company);
+
+        return Result.success();
+    }
+
+    /**
+     * 按名称查找
+     *
+     * @param name
+     * @return
+     */
+    @GetMapping(params = "name")
+    public Result<CompanyDTO> getByName(@RequestParam String name) {
+        Company company = companyService.findByName(name);
+        if (null != company) {
+            CompanyDTO companyDTO = BeanMapper.map(company, CompanyDTO.class);
+            return Result.success(companyDTO);
+        }
+        return Result.error(ExceptionCode.COMPANY_NOT_EXIST);
+    }
+
+    /**
+     * 按商业登记证号查找
+     *
+     * @param businessCode
+     * @return
+     */
+    @GetMapping(params = "businessCode")
+    public Result<CompanyDTO> getByBusinessCode(@RequestParam String businessCode) {
+        Company company = companyService.findByBusinessCode(businessCode);
+        if (null != company) {
+            CompanyDTO companyDTO = BeanMapper.map(company, CompanyDTO.class);
+            return Result.success(companyDTO);
+        }
+        return Result.error(ExceptionCode.COMPANY_NOT_EXIST);
+    }
+
+    /**
+     * 按二级域名查找
+     *
+     * @param domain
+     * @return
+     */
+    @GetMapping(params = "domain")
+    public Result<CompanyDTO> getByDomain(@RequestParam String domain) {
+        Company company = companyService.findByDomain(domain);
+        if (null != company) {
+            CompanyDTO companyDTO = BeanMapper.map(company, CompanyDTO.class);
+            return Result.success(companyDTO);
+        }
+        return Result.error(ExceptionCode.COMPANY_NOT_EXIST);
+    }
+}

+ 8 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/ResourceController.java

@@ -0,0 +1,8 @@
+package com.usoftchina.saas.account.controller;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class ResourceController {
+}

+ 8 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/RoleController.java

@@ -0,0 +1,8 @@
+package com.usoftchina.saas.account.controller;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class RoleController {
+}

+ 35 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/AccountMapper.java

@@ -0,0 +1,35 @@
+package com.usoftchina.saas.account.mapper;
+
+import com.usoftchina.saas.account.po.Account;
+import com.usoftchina.saas.base.mapper.CommonBaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public interface AccountMapper extends CommonBaseMapper<Account> {
+    /**
+     * 按用户名查找
+     *
+     * @param username
+     * @return
+     */
+    Account selectByUsername(@Param("username") String username);
+
+    /**
+     * 按手机号查找
+     *
+     * @param mobile
+     * @return
+     */
+    Account selectByMobile(@Param("mobile") String mobile);
+
+    /**
+     * 按邮箱查找
+     *
+     * @param email
+     * @return
+     */
+    Account selectByEmail(@Param("email") String email);
+}

+ 11 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/AccountRoleMapper.java

@@ -0,0 +1,11 @@
+package com.usoftchina.saas.account.mapper;
+
+import com.usoftchina.saas.account.po.AccountRole;
+import com.usoftchina.saas.base.mapper.CommonBaseMapper;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public interface AccountRoleMapper extends CommonBaseMapper<AccountRole> {
+}

+ 49 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/CompanyMapper.java

@@ -0,0 +1,49 @@
+package com.usoftchina.saas.account.mapper;
+
+import com.usoftchina.saas.account.po.Company;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public interface CompanyMapper {
+    /**
+     * 新增
+     *
+     * @param record
+     * @return
+     */
+    int insert(Company record);
+
+    /**
+     * 有选择(不为null)的新增
+     *
+     * @param record
+     * @return
+     */
+    int insertSelective(Company record);
+    /**
+     * 按名称查询
+     *
+     * @param name
+     * @return
+     */
+    Company selectByName(@Param("name") String name);
+
+    /**
+     * 按商业登记证号查询
+     *
+     * @param businessCode
+     * @return
+     */
+    Company selectByBusinessCode(@Param("businessCode") String businessCode);
+
+    /**
+     * 按二级域名查找
+     *
+     * @param domain
+     * @return
+     */
+    Company selectByDomain(@Param("domain") String domain);
+}

+ 11 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/ResourcesMapper.java

@@ -0,0 +1,11 @@
+package com.usoftchina.saas.account.mapper;
+
+import com.usoftchina.saas.account.po.Resources;
+import com.usoftchina.saas.base.mapper.CommonBaseMapper;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public interface ResourcesMapper extends CommonBaseMapper<Resources> {
+}

+ 11 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/RoleMapper.java

@@ -0,0 +1,11 @@
+package com.usoftchina.saas.account.mapper;
+
+import com.usoftchina.saas.account.po.Role;
+import com.usoftchina.saas.base.mapper.CommonBaseMapper;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public interface RoleMapper extends CommonBaseMapper<Role> {
+}

+ 11 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/RoleResourceMapper.java

@@ -0,0 +1,11 @@
+package com.usoftchina.saas.account.mapper;
+
+import com.usoftchina.saas.account.po.RoleResource;
+import com.usoftchina.saas.base.mapper.CommonBaseMapper;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public interface RoleResourceMapper extends CommonBaseMapper<RoleResource> {
+}

+ 80 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/po/Account.java

@@ -0,0 +1,80 @@
+package com.usoftchina.saas.account.po;
+
+import com.usoftchina.saas.base.entity.CommonBaseEntity;
+
+import java.io.Serializable;
+
+/**
+ * 账号
+ *
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class Account extends CommonBaseEntity implements Serializable {
+    private String username;
+    private String password;
+    private String salt;
+    private String realname;
+    private String email;
+    private String mobile;
+    /**
+     * 账号类型 0 - 管理员
+     */
+    private Integer type;
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getSalt() {
+        return salt;
+    }
+
+    public void setSalt(String salt) {
+        this.salt = salt;
+    }
+
+    public String getRealname() {
+        return realname;
+    }
+
+    public void setRealname(String realname) {
+        this.realname = realname;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getMobile() {
+        return mobile;
+    }
+
+    public void setMobile(String mobile) {
+        this.mobile = mobile;
+    }
+
+    public Integer getType() {
+        return type;
+    }
+
+    public void setType(Integer type) {
+        this.type = type;
+    }
+}

+ 32 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/po/AccountRole.java

@@ -0,0 +1,32 @@
+package com.usoftchina.saas.account.po;
+
+import com.usoftchina.saas.base.entity.CommonBaseEntity;
+
+import java.io.Serializable;
+
+/**
+ * 账户角色
+ *
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class AccountRole extends CommonBaseEntity implements Serializable {
+    private long accountId;
+    private long roleId;
+
+    public long getAccountId() {
+        return accountId;
+    }
+
+    public void setAccountId(long accountId) {
+        this.accountId = accountId;
+    }
+
+    public long getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(long roleId) {
+        this.roleId = roleId;
+    }
+}

+ 103 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/po/Company.java

@@ -0,0 +1,103 @@
+package com.usoftchina.saas.account.po;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 公司
+ *
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class Company implements Serializable {
+    protected Long id;
+    /**
+     * 唯一名称
+     */
+    private String name;
+    /**
+     * 商业登记证号
+     */
+    private String businessCode;
+    private String address;
+    /**
+     * 二级域名
+     */
+    private String domain;
+    protected Date createTime;
+    protected long creatorId;
+    protected Date updateTime;
+    protected long updaterId;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getBusinessCode() {
+        return businessCode;
+    }
+
+    public void setBusinessCode(String businessCode) {
+        this.businessCode = businessCode;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public long getCreatorId() {
+        return creatorId;
+    }
+
+    public void setCreatorId(long creatorId) {
+        this.creatorId = creatorId;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public long getUpdaterId() {
+        return updaterId;
+    }
+
+    public void setUpdaterId(long updaterId) {
+        this.updaterId = updaterId;
+    }
+}

+ 130 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/po/Resources.java

@@ -0,0 +1,130 @@
+package com.usoftchina.saas.account.po;
+
+import com.usoftchina.saas.base.entity.CommonBaseEntity;
+
+import java.io.Serializable;
+
+/**
+ * 资源
+ *
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class Resources extends CommonBaseEntity implements Serializable {
+    /**
+     * 编号
+     */
+    private String code;
+    /**
+     * 名称
+     */
+    private String name;
+    /**
+     * 资源类型
+     * MENU - 菜单
+     * DIR - 目录
+     * BUTTON - 按钮
+     * URI - 页面上的url
+     * API - api
+     */
+    private String type;
+    /**
+     * url
+     */
+    private String url;
+
+    /**
+     * 资源请求方式 POST/GET/PUT/DELETE
+     */
+    private String method;
+    /**
+     * 菜单打开方式 _self,_top,_blank,_parent
+     */
+    private String target;
+    /**
+     * 菜单图标
+     */
+    private String icon;
+
+    /**
+     * 排序
+     */
+    private Integer orderNum;
+
+    /**
+     * 描述
+     */
+    private String description;
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getMethod() {
+        return method;
+    }
+
+    public void setMethod(String method) {
+        this.method = method;
+    }
+
+    public String getTarget() {
+        return target;
+    }
+
+    public void setTarget(String target) {
+        this.target = target;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public Integer getOrderNum() {
+        return orderNum;
+    }
+
+    public void setOrderNum(Integer orderNum) {
+        this.orderNum = orderNum;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+}

+ 50 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/po/Role.java

@@ -0,0 +1,50 @@
+package com.usoftchina.saas.account.po;
+
+import com.usoftchina.saas.base.entity.CommonBaseEntity;
+
+import java.io.Serializable;
+
+/**
+ * 角色
+ *
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class Role extends CommonBaseEntity implements Serializable {
+    /**
+     * 编号
+     */
+    private String code;
+    /**
+     * 名称
+     */
+    private String name;
+    /**
+     * 描述
+     */
+    private String description;
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+}

+ 32 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/po/RoleResource.java

@@ -0,0 +1,32 @@
+package com.usoftchina.saas.account.po;
+
+import com.usoftchina.saas.base.entity.CommonBaseEntity;
+
+import java.io.Serializable;
+
+/**
+ * 角色资源
+ *
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class RoleResource extends CommonBaseEntity implements Serializable {
+    private long roleId;
+    private long resourceId;
+
+    public long getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(long roleId) {
+        this.roleId = roleId;
+    }
+
+    public long getResourceId() {
+        return resourceId;
+    }
+
+    public void setResourceId(long resourceId) {
+        this.resourceId = resourceId;
+    }
+}

+ 54 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/AccountService.java

@@ -0,0 +1,54 @@
+package com.usoftchina.saas.account.service;
+
+import com.usoftchina.saas.account.mapper.AccountMapper;
+import com.usoftchina.saas.account.po.Account;
+import com.usoftchina.saas.base.service.CommonBaseService;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public interface AccountService extends CommonBaseService<AccountMapper, Account> {
+    /**
+     * 按用户名查找
+     *
+     * @param username
+     * @return
+     */
+    Account findByUsername(String username);
+
+    /**
+     * 按手机号查找
+     *
+     * @param mobile
+     * @return
+     */
+    Account findByMobile(String mobile);
+
+    /**
+     * 按邮箱查找
+     *
+     * @param email
+     * @return
+     */
+    Account findByEmail(String email);
+
+    /**
+     * 校验密码
+     *
+     * @param account
+     * @param plainPassword
+     * @return
+     */
+    boolean checkPwd(Account account, String plainPassword);
+
+    /**
+     * 明文密码加密
+     *
+     * @param plainPassword
+     * @param salt
+     * @return
+     */
+    String getEncryptedPassword(String plainPassword, String salt);
+
+}

+ 41 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/CompanyService.java

@@ -0,0 +1,41 @@
+package com.usoftchina.saas.account.service;
+
+import com.usoftchina.saas.account.po.Company;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public interface CompanyService {
+    /**
+     * 保存
+     *
+     * @param company
+     * @return
+     */
+    boolean save(Company company);
+
+    /**
+     * 按名称查
+     *
+     * @param name
+     * @return
+     */
+    Company findByName(String name);
+
+    /**
+     * 按商业登记证号查
+     *
+     * @param businessCode
+     * @return
+     */
+    Company findByBusinessCode(String businessCode);
+
+    /**
+     * 按二级域名查
+     *
+     * @param domain
+     * @return
+     */
+    Company findByDomain(String domain);
+}

+ 47 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/impl/AccountServiceImpl.java

@@ -0,0 +1,47 @@
+package com.usoftchina.saas.account.service.impl;
+
+import com.usoftchina.saas.account.mapper.AccountMapper;
+import com.usoftchina.saas.account.po.Account;
+import com.usoftchina.saas.account.service.AccountService;
+import com.usoftchina.saas.base.service.CommonBaseServiceImpl;
+import org.springframework.stereotype.Service;
+import org.springframework.util.DigestUtils;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+@Service
+public class AccountServiceImpl extends CommonBaseServiceImpl<AccountMapper, Account> implements AccountService {
+    @Override
+    public Account findByUsername(String username) {
+        return getMapper().selectByUsername(username);
+    }
+
+    @Override
+    public Account findByMobile(String mobile) {
+        return getMapper().selectByMobile(mobile);
+    }
+
+    @Override
+    public Account findByEmail(String email) {
+        return getMapper().selectByEmail(email);
+    }
+
+    @Override
+    public boolean checkPwd(Account account, String plainPassword) {
+        return getEncryptedPassword(plainPassword, account.getSalt()).equals(account.getPassword());
+    }
+
+    /**
+     * 明文密码加密
+     *
+     * @param plainPassword
+     * @param salt
+     * @return
+     */
+    @Override
+    public String getEncryptedPassword(String plainPassword, String salt) {
+        return DigestUtils.md5DigestAsHex(String.format("%s{%s}", plainPassword, salt).getBytes());
+    }
+}

+ 47 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/impl/CompanyServiceImpl.java

@@ -0,0 +1,47 @@
+package com.usoftchina.saas.account.service.impl;
+
+import com.usoftchina.saas.account.mapper.CompanyMapper;
+import com.usoftchina.saas.account.po.Company;
+import com.usoftchina.saas.account.service.CompanyService;
+import com.usoftchina.saas.context.BaseContextHolder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+@Service
+public class CompanyServiceImpl implements CompanyService{
+
+    @Autowired
+    private CompanyMapper companyMapper;
+
+    @Override
+    public boolean save(Company company) {
+        Date nowDate = new Date();
+        company.setCreateTime(nowDate);
+        company.setCreatorId(BaseContextHolder.getUserId());
+        company.setUpdateTime(nowDate);
+        company.setUpdaterId(BaseContextHolder.getUserId());
+
+        return companyMapper.insert(company) > 0;
+    }
+
+    @Override
+    public Company findByName(String name) {
+        return companyMapper.selectByName(name);
+    }
+
+    @Override
+    public Company findByBusinessCode(String businessCode) {
+        return companyMapper.selectByBusinessCode(businessCode);
+    }
+
+    @Override
+    public Company findByDomain(String domain) {
+        return companyMapper.selectByDomain(domain);
+    }
+}

+ 40 - 0
base-servers/account/account-server/src/main/resources/application.yml

@@ -0,0 +1,40 @@
+spring:
+  application:
+    name: account-server
+  security:
+    user:
+      name: admin
+      password: select111***
+  datasource:
+    hikari:
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      jdbc-url: jdbc:mysql://192.168.253.12:3306/saas_account?characterEncoding=utf-8&useSSL=false
+      username: root
+      password: select111***
+  messages:
+    basename: i18n/messages
+eureka:
+  instance:
+    leaseRenewalIntervalInSeconds: 10
+    health-check-url-path: /actuator/health
+    status-page-url-path: /actuator/info
+    metadata-map:
+      user.name: ${spring.security.user.name}
+      user.password: ${spring.security.user.password}
+  client:
+    registryFetchIntervalSeconds: 5
+    serviceUrl:
+      defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@127.0.0.1:8500/eureka/
+server:
+  port: 8580
+  tomcat:
+    uri-encoding: UTF-8
+info:
+  name: '@project.artifactId@'
+  description: '@project.description@'
+  version: '@project.version@'
+  spring-boot-version: '@spring.boot.version@'
+  spring-cloud-version: '@spring.cloud.version@'
+mybatis:
+  type-aliases-package: com.usoftchina.saas.account.po
+  mapper-locations: classpath:mapper/*.xml

+ 15 - 0
base-servers/account/account-server/src/main/resources/banner.txt

@@ -0,0 +1,15 @@
+${AnsiColor.BRIGHT_YELLOW}
+
+88        88   ad88888ba     ,ad8888ba,    88888888888  888888888888  ,ad8888ba,   88        88  88  888b      88         db
+88        88  d8"     "8b   d8"'    `"8b   88                88      d8"'    `"8b  88        88  88  8888b     88        d88b
+88        88  Y8,          d8'        `8b  88                88     d8'            88        88  88  88 `8b    88       d8'`8b
+88        88  `Y8aaaaa,    88          88  88aaaaa           88     88             88aaaaaaaa88  88  88  `8b   88      d8'  `8b
+88        88    `"""""8b,  88          88  88"""""           88     88             88""""""""88  88  88   `8b  88     d8YaaaaY8b
+88        88          `8b  Y8,        ,8P  88                88     Y8,            88        88  88  88    `8b 88    d8""""""""8b
+Y8a.    .a8P  Y8a     a8P   Y8a.    .a8P   88                88      Y8a.    .a8P  88        88  88  88     `8888   d8'        `8b
+ `"Y8888Y"'    "Y88888P"     `"Y8888Y"'    88                88       `"Y8888Y"'   88        88  88  88      `888  d8'          `8b
+
+
+Application Version: ${application.version}${application.formatted-version}
+Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
+${AnsiColor.DEFAULT}

+ 64 - 0
base-servers/account/account-server/src/main/resources/logback-spring.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
+    <jmxConfigurator/>
+
+    <!--
+    %m
+    输出代码中指定的消息
+    %p
+    输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
+    %r
+    输出自应用启动到输出该log信息耗费的毫秒数
+    %c
+    输出所属的类目,通常就是所在类的全名
+    %t
+    输出产生该日志事件的线程名
+    %n
+    输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
+    %d
+    输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},
+    输出类似:2002年10月18日 22:10:28,921
+    %l
+    输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)
+    -->
+
+    <springProperty scope="context" name="log.path" source="logging.path" defaultValue="/var/log/saas/account-server"/>
+    <springProperty scope="context" name="spring.application.name" source="spring.application.name" defaultValue="account-server"/>
+    <springProperty scope="context" name="spring.profiles.active" source="spring.profiles.active" defaultValue="dev"/>
+    <springProperty scope="context" name="common-pattern" source="logging.common-pattern" defaultValue="%d{yyyy-MM-dd HH:mm:ss.SSS}:[%5p] [%t:%r] [%C{1}:%M:%L] --> %m%n"/>
+    <springProperty scope="context" name="log.level.console" source="logging.level.console" defaultValue="INFO"/>
+
+    <contextName>${spring.application.name}-${spring.profiles.active}-logback</contextName>
+
+
+    <appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>${log.level.console}</level>
+        </filter>
+        <encoder>
+            <pattern>${common-pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="ROOT_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/root.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- 每天一归档 -->
+            <fileNamePattern>${log.path}/%d{yyyy-MM}/root-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
+            <!-- 单个日志文件最多 100MB, 60天的日志周期,最大不能超过20GB -->
+            <maxFileSize>128MB</maxFileSize>
+            <maxHistory>60</maxHistory>
+            <totalSizeCap>20GB</totalSizeCap>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${common-pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <root level="${log.level.console}">
+        <appender-ref ref="CONSOLE_APPENDER"/>
+        <appender-ref ref="ROOT_APPENDER"/>
+    </root>
+
+</configuration>

+ 116 - 0
base-servers/account/account-server/src/main/resources/mapper/AccountMapper.xml

@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.usoftchina.saas.account.mapper.AccountMapper">
+    <resultMap id="BaseResultMap" type="com.usoftchina.saas.account.po.Account">
+        <id column="id" jdbcType="BIGINT" property="id"/>
+        <result column="company_id" jdbcType="BIGINT" property="companyId"/>
+        <result column="username" jdbcType="VARCHAR" property="username"/>
+        <result column="password" jdbcType="VARCHAR" property="password"/>
+        <result column="salt" jdbcType="VARCHAR" property="salt"/>
+        <result column="realname" jdbcType="VARCHAR" property="realname"/>
+        <result column="email" jdbcType="VARCHAR" property="email"/>
+        <result column="mobile" jdbcType="VARCHAR" property="mobile"/>
+        <result column="type" jdbcType="INT" property="type"/>
+        <result column="creator_id" jdbcType="BIGINT" property="creatorId"/>
+        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
+        <result column="updater_id" jdbcType="BIGINT" property="updaterId"/>
+        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
+    </resultMap>
+    <sql id="baseColumns">
+        id,company_id,username,password,salt,realname,email,mobile,type,creator_id,create_time,updater_id,update_time
+    </sql>
+    <insert id="insert" parameterType="com.usoftchina.saas.account.po.Account">
+        insert into ac_account(company_id,username,password,salt,realname,email,mobile,type,creator_id,create_time,updater_id,update_time)
+        values (#{companyId,jdbcType=BIGINT}, #{username,jdbcType=VARCHAR},#{password,jdbcType=VARCHAR}, #{salt,jdbcType=VARCHAR},
+        #{realname,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{mobile,jdbcType=VARCHAR}, #{type,jdbcType=INT},
+        #{createTime,jdbcType=TIMESTAMP}, #{updaterId,jdbcType=BIGINT}, #{updateTime,jdbcType=TIMESTAMP})
+    </insert>
+    <insert id="insertSelective" parameterType="com.usoftchina.saas.account.po.Account">
+        insert into ac_account
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="companyId != null">
+                company_id,
+            </if>
+            <if test="username != null">
+                username,
+            </if>
+            <if test="password != null">
+                password,
+            </if>
+            <if test="salt != null">
+                salt,
+            </if>
+            <if test="realname != null">
+                realname,
+            </if>
+            <if test="email != null">
+                email,
+            </if>
+            <if test="mobile != null">
+                mobile,
+            </if>
+            <if test="type != null">
+                type,
+            </if>
+            <if test="creator_id != null">
+                creator_id,
+            </if>
+            <if test="create_time != null">
+                create_time,
+            </if>
+            <if test="updater_id != null">
+                updater_id,
+            </if>
+            <if test="update_time != null">
+                update_time,
+            </if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="companyId != null">
+                #{companyId,jdbcType=BIGINT},
+            </if>
+            <if test="username != null">
+                #{username,jdbcType=VARCHAR},
+            </if>
+            <if test="password != null">
+                #{password,jdbcType=VARCHAR},
+            </if>
+            <if test="salt != null">
+                #{salt,jdbcType=VARCHAR},
+            </if>
+            <if test="realname != null">
+                #{realname,jdbcType=VARCHAR},
+            </if>
+            <if test="email != null">
+                #{email,jdbcType=VARCHAR},
+            </if>
+            <if test="mobile != null">
+                #{mobile,jdbcType=VARCHAR},
+            </if>
+            <if test="type != null">
+                #{type,jdbcType=INT},
+            </if>
+            <if test="creatorId != null">
+                #{creatorId,jdbcType=BIGINT},
+            </if>
+            <if test="createTime != null">
+                #{createTime,jdbcType=TIMESTAMP},
+            </if>
+            <if test="updaterId != null">
+                #{updaterId,jdbcType=BIGINT},
+            </if>
+            <if test="updateTime != null">
+                #{updateTime,jdbcType=TIMESTAMP},
+            </if>
+        </trim>
+    </insert>
+    <select id="selectByUsername" parameterType="java.lang.String" resultMap="BaseResultMap">
+        select <include refid="baseColumns"/> from ac_account where username=#{username}
+    </select>
+    <select id="selectByMobile" parameterType="java.lang.String" resultMap="BaseResultMap">
+        select <include refid="baseColumns"/> from ac_account where mobile=#{mobile}
+    </select>
+    <select id="selectByEmail" parameterType="java.lang.String" resultMap="BaseResultMap">
+        select <include refid="baseColumns"/> from ac_account where email=#{email}
+    </select>
+</mapper>

+ 4 - 0
base-servers/account/account-server/src/main/resources/mapper/AccountRoleMapper.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.usoftchina.saas.account.mapper.AccountRoleMapper">
+</mapper>

+ 89 - 0
base-servers/account/account-server/src/main/resources/mapper/CompanyMapper.xml

@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.usoftchina.saas.account.mapper.CompanyMapper">
+    <resultMap id="BaseResultMap" type="com.usoftchina.saas.account.po.Company">
+        <id column="id" jdbcType="BIGINT" property="id"/>
+        <result column="name" jdbcType="VARCHAR" property="name"/>
+        <result column="business_code" jdbcType="VARCHAR" property="businessCode"/>
+        <result column="address" jdbcType="VARCHAR" property="address"/>
+        <result column="domain" jdbcType="VARCHAR" property="domain"/>
+        <result column="creator_id" jdbcType="BIGINT" property="creatorId"/>
+        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
+        <result column="updater_id" jdbcType="BIGINT" property="updaterId"/>
+        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
+    </resultMap>
+    <sql id="baseColumns">
+        id,name,business_code,address,domain,creator_id,create_time,updater_id,update_time
+    </sql>
+    <insert id="insert" parameterType="com.usoftchina.saas.account.po.Company">
+        insert into ac_company(name, business_code, address, domain, creator_id, create_time, updater_id, update_time)
+        values (#{name,jdbcType=VARCHAR}, #{businessCode,jdbcType=VARCHAR},
+        #{address,jdbcType=VARCHAR}, #{domain,jdbcType=VARCHAR}, #{creatorId,jdbcType=BIGINT},
+        #{createTime,jdbcType=TIMESTAMP}, #{updaterId,jdbcType=BIGINT}, #{updateTime,jdbcType=TIMESTAMP})
+    </insert>
+    <insert id="insertSelective" parameterType="com.usoftchina.saas.account.po.Company">
+        insert into ac_company
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="name != null">
+                name,
+            </if>
+            <if test="businessCode != null">
+                business_code,
+            </if>
+            <if test="address != null">
+                address,
+            </if>
+            <if test="domain != null">
+                domain,
+            </if>
+            <if test="creator_id != null">
+                creator_id,
+            </if>
+            <if test="create_time != null">
+                create_time,
+            </if>
+            <if test="updater_id != null">
+                updater_id,
+            </if>
+            <if test="update_time != null">
+                update_time,
+            </if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="name != null">
+                #{name,jdbcType=VARCHAR},
+            </if>
+            <if test="businessCode != null">
+                #{businessCode,jdbcType=VARCHAR},
+            </if>
+            <if test="address != null">
+                #{address,jdbcType=VARCHAR},
+            </if>
+            <if test="domain != null">
+                #{domain,jdbcType=VARCHAR},
+            </if>
+            <if test="creatorId != null">
+                #{creatorId,jdbcType=BIGINT},
+            </if>
+            <if test="createTime != null">
+                #{createTime,jdbcType=TIMESTAMP},
+            </if>
+            <if test="updaterId != null">
+                #{updaterId,jdbcType=BIGINT},
+            </if>
+            <if test="updateTime != null">
+                #{updateTime,jdbcType=TIMESTAMP},
+            </if>
+        </trim>
+    </insert>
+    <select id="selectByName" parameterType="java.lang.String" resultMap="BaseResultMap">
+        select <include refid="baseColumns"/> from ac_company where name=#{name}
+    </select>
+    <select id="selectByBusinessCode" parameterType="java.lang.String" resultMap="BaseResultMap">
+        select <include refid="baseColumns"/> from ac_company where business_code=#{businessCode}
+    </select>
+    <select id="selectByDomain" parameterType="java.lang.String" resultMap="BaseResultMap">
+        select <include refid="baseColumns"/> from ac_company where domain=#{domain}
+    </select>
+
+</mapper>

+ 4 - 0
base-servers/account/account-server/src/main/resources/mapper/ResourcesMapper.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.usoftchina.saas.account.mapper.ResourcesMapper">
+</mapper>

+ 4 - 0
base-servers/account/account-server/src/main/resources/mapper/RoleMapper.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.usoftchina.saas.account.mapper.RoleMapper">
+</mapper>

+ 4 - 0
base-servers/account/account-server/src/main/resources/mapper/RoleResourceMapper.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.usoftchina.saas.account.mapper.RoleResourceMapper">
+</mapper>

+ 22 - 0
base-servers/account/pom.xml

@@ -0,0 +1,22 @@
+<?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">
+    <parent>
+        <artifactId>base-servers</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>account</artifactId>
+    <description>account center</description>
+    <modules>
+        <module>account-api</module>
+        <module>account-dto</module>
+        <module>account-server</module>
+    </modules>
+    <packaging>pom</packaging>
+
+
+</project>

+ 46 - 0
base-servers/admin-server/pom.xml

@@ -0,0 +1,46 @@
+<?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">
+    <parent>
+        <artifactId>base-servers</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>admin-server</artifactId>
+    <description>admin server</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>de.codecentric</groupId>
+            <artifactId>spring-boot-admin-starter-server</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.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jolokia</groupId>
+            <artifactId>jolokia-core</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 25 - 0
base-servers/admin-server/src/main/java/com/usoftchina/saas/admin/AdminApplication.java

@@ -0,0 +1,25 @@
+package com.usoftchina.saas.admin;
+
+import de.codecentric.boot.admin.server.config.EnableAdminServer;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author yingp
+ * @date 2018/9/28
+ */
+@Configuration
+@EnableAutoConfiguration
+@EnableAdminServer
+@EnableEurekaClient
+public class AdminApplication {
+    public static void main(String[] args) {
+        try {
+            SpringApplication.run(AdminApplication.class, args);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 42 - 0
base-servers/admin-server/src/main/java/com/usoftchina/saas/admin/config/WebSecurityConfig.java

@@ -0,0 +1,42 @@
+package com.usoftchina.saas.admin.config;
+
+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.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
+
+/**
+ * @author yingp
+ * @date 2018/9/28
+ */
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, proxyTargetClass = true)
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
+        successHandler.setTargetUrlParameter("redirectTo");
+        http.authorizeRequests()
+                .antMatchers("/login", "/api/**", "/**/heapdump", "/**/loggers", "/**/liquibase", "/**/logfile", "/**/flyway", "/**/auditevents", "/**/jolokia").permitAll()
+                .and()
+                .authorizeRequests()
+                .antMatchers("/**").hasRole("USER")
+                .antMatchers("/**").authenticated()
+                .and()
+                .formLogin().loginPage("/login").successHandler(successHandler)
+                .and()
+                .logout().deleteCookies("remove").logoutSuccessUrl("/login.html").permitAll()
+                .and()
+                .httpBasic()
+                .and().csrf().disable();
+    }
+
+    @Override
+    public void configure(WebSecurity web) {
+        // 忽略以下文件
+        web.ignoring().antMatchers("/**.html", "/**.css", "/img/**", "/**.js", "/third-party/**");
+    }
+}

+ 29 - 0
base-servers/admin-server/src/main/resources/application.yml

@@ -0,0 +1,29 @@
+spring:
+  application:
+    name: admin-server
+  security:
+    user:
+      name: admin
+      password: select111***
+server:
+  port: 8520
+  tomcat:
+    uri-encoding: UTF-8
+eureka:
+  instance:
+    leaseRenewalIntervalInSeconds: 10
+    health-check-url-path: /actuator/health
+    status-page-url-path: /actuator/info
+    metadata-map:
+      user.name: ${spring.security.user.name}
+      user.password: ${spring.security.user.password}
+  client:
+    registryFetchIntervalSeconds: 5
+    serviceUrl:
+      defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@127.0.0.1:8500/eureka/
+info:
+  name: '@project.artifactId@'
+  description: '@project.description@'
+  version: '@project.version@'
+  spring-boot-version: '@spring.boot.version@'
+  spring-cloud-version: '@spring.cloud.version@'

+ 15 - 0
base-servers/admin-server/src/main/resources/banner.txt

@@ -0,0 +1,15 @@
+${AnsiColor.BRIGHT_YELLOW}
+
+88        88   ad88888ba     ,ad8888ba,    88888888888  888888888888  ,ad8888ba,   88        88  88  888b      88         db
+88        88  d8"     "8b   d8"'    `"8b   88                88      d8"'    `"8b  88        88  88  8888b     88        d88b
+88        88  Y8,          d8'        `8b  88                88     d8'            88        88  88  88 `8b    88       d8'`8b
+88        88  `Y8aaaaa,    88          88  88aaaaa           88     88             88aaaaaaaa88  88  88  `8b   88      d8'  `8b
+88        88    `"""""8b,  88          88  88"""""           88     88             88""""""""88  88  88   `8b  88     d8YaaaaY8b
+88        88          `8b  Y8,        ,8P  88                88     Y8,            88        88  88  88    `8b 88    d8""""""""8b
+Y8a.    .a8P  Y8a     a8P   Y8a.    .a8P   88                88      Y8a.    .a8P  88        88  88  88     `8888   d8'        `8b
+ `"Y8888Y"'    "Y88888P"     `"Y8888Y"'    88                88       `"Y8888Y"'   88        88  88  88      `888  d8'          `8b
+
+
+Application Version: ${application.version}${application.formatted-version}
+Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
+${AnsiColor.DEFAULT}

+ 64 - 0
base-servers/admin-server/src/main/resources/logback-spring.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
+    <jmxConfigurator/>
+
+    <!--
+    %m
+    输出代码中指定的消息
+    %p
+    输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
+    %r
+    输出自应用启动到输出该log信息耗费的毫秒数
+    %c
+    输出所属的类目,通常就是所在类的全名
+    %t
+    输出产生该日志事件的线程名
+    %n
+    输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
+    %d
+    输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},
+    输出类似:2002年10月18日 22:10:28,921
+    %l
+    输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)
+    -->
+
+    <springProperty scope="context" name="log.path" source="logging.path" defaultValue="/var/log/saas/admin-server"/>
+    <springProperty scope="context" name="spring.application.name" source="spring.application.name" defaultValue="admin-server"/>
+    <springProperty scope="context" name="spring.profiles.active" source="spring.profiles.active" defaultValue="dev"/>
+    <springProperty scope="context" name="common-pattern" source="logging.common-pattern" defaultValue="%d{yyyy-MM-dd HH:mm:ss.SSS}:[%5p] [%t:%r] [%C{1}:%M:%L] --> %m%n"/>
+    <springProperty scope="context" name="log.level.console" source="logging.level.console" defaultValue="INFO"/>
+
+    <contextName>${spring.application.name}-${spring.profiles.active}-logback</contextName>
+
+
+    <appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>${log.level.console}</level>
+        </filter>
+        <encoder>
+            <pattern>${common-pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="ROOT_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/root.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- 每天一归档 -->
+            <fileNamePattern>${log.path}/%d{yyyy-MM}/root-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
+            <!-- 单个日志文件最多 100MB, 60天的日志周期,最大不能超过20GB -->
+            <maxFileSize>128MB</maxFileSize>
+            <maxHistory>60</maxHistory>
+            <totalSizeCap>20GB</totalSizeCap>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${common-pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <root level="${log.level.console}">
+        <appender-ref ref="CONSOLE_APPENDER"/>
+        <appender-ref ref="ROOT_APPENDER"/>
+    </root>
+
+</configuration>

+ 34 - 0
base-servers/auth/auth-api/pom.xml

@@ -0,0 +1,34 @@
+<?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">
+    <parent>
+        <artifactId>auth</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>auth-api</artifactId>
+    <description>authentication api</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>auth-dto</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 24 - 0
base-servers/auth/auth-api/src/main/java/com/usoftchina/saas/auth/api/AuthApi.java

@@ -0,0 +1,24 @@
+package com.usoftchina.saas.auth.api;
+
+import com.usoftchina.saas.auth.dto.TokenDTO;
+import com.usoftchina.saas.base.Result;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * @author yingp
+ * @date 2018/9/30
+ */
+@FeignClient(name = "auth-server")
+public interface AuthApi {
+    /**
+     * 登录认证获取token
+     *
+     * @param username
+     * @param password
+     * @return
+     */
+    @PostMapping(value = "/api/auth")
+    Result<TokenDTO> authorize(@RequestParam(value = "username") String username, @RequestParam(value = "password") String password);
+}

+ 23 - 0
base-servers/auth/auth-api/src/main/java/com/usoftchina/saas/auth/api/TokenApi.java

@@ -0,0 +1,23 @@
+package com.usoftchina.saas.auth.api;
+
+import com.usoftchina.saas.auth.dto.TokenDTO;
+import com.usoftchina.saas.base.Result;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * @author yingp
+ * @date 2018/9/30
+ */
+@FeignClient(name = "auth-server")
+public interface TokenApi {
+    /**
+     * 登录获取token
+     *
+     * @param userName
+     * @return
+     */
+    @PostMapping(value = "/client/login")
+    Result<TokenDTO> login(@RequestParam(value = "userName") String userName);
+}

+ 44 - 0
base-servers/auth/auth-api/src/main/java/com/usoftchina/saas/auth/cache/TokenCache.java

@@ -0,0 +1,44 @@
+package com.usoftchina.saas.auth.cache;
+
+import com.usoftchina.saas.auth.api.TokenApi;
+import com.usoftchina.saas.cache.RedisHashCache;
+import com.usoftchina.saas.context.SpringContextHolder;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import java.util.function.Supplier;
+
+/**
+ * @author yingp
+ * @date 2018/9/30
+ */
+public class TokenCache extends RedisHashCache<String, String, String> {
+
+    private final String account;
+
+    private final TokenApi tokenApi;
+
+    private TokenCache(String account) {
+        super(() -> SpringContextHolder.getBean(RedisTemplate.class));
+        this.account = account;
+        this.tokenApi = SpringContextHolder.getBean(TokenApi.class);
+    }
+
+    public static TokenCache of(String account) {
+        return new TokenCache(account);
+    }
+
+    @Override
+    protected String key() {
+        return generateKey("auth", "token");
+    }
+
+    @Override
+    protected String field() {
+        return String.valueOf(account);
+    }
+
+    @Override
+    protected Supplier<String> getSupplier() {
+        return () -> tokenApi.login(account).getData().getToken();
+    }
+}

+ 43 - 0
base-servers/auth/auth-client/pom.xml

@@ -0,0 +1,43 @@
+<?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">
+    <parent>
+        <artifactId>auth</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>auth-client</artifactId>
+    <description>authentication client</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-netflix-core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>auth-common</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>io.github.openfeign</groupId>
+            <artifactId>feign-core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>

+ 20 - 0
base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/EnableAuthClient.java

@@ -0,0 +1,20 @@
+package com.usoftchina.saas.auth.client;
+
+import com.usoftchina.saas.auth.client.configuration.AuthAutoConfiguration;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+/**
+ * 启用鉴权client
+ *
+ * @author yingp
+ * @date 2018/10/2
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Import(AuthAutoConfiguration.class)
+@Documented
+@Inherited
+public @interface EnableAuthClient {
+}

+ 17 - 0
base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/annotation/IgnoreAuth.java

@@ -0,0 +1,17 @@
+package com.usoftchina.saas.auth.client.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 忽略鉴权
+ *
+ * @author yingp
+ * @date 2018/10/2
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value={ElementType.METHOD,ElementType.TYPE})
+public @interface IgnoreAuth {
+}

+ 28 - 0
base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/configuration/AuthAutoConfiguration.java

@@ -0,0 +1,28 @@
+package com.usoftchina.saas.auth.client.configuration;
+
+import com.usoftchina.saas.auth.client.interceptor.AuthRestInterceptor;
+import com.usoftchina.saas.auth.client.interceptor.ServiceFeignInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+@Configuration
+public class AuthAutoConfiguration {
+    @Bean
+    public AuthConfig authConfig() {
+        return new AuthConfig();
+    }
+
+    @Bean
+    public AuthRestInterceptor authRestInterceptor() {
+        return new AuthRestInterceptor();
+    }
+
+    @Bean
+    public ServiceFeignInterceptor serviceFeignInterceptor() {
+        return new ServiceFeignInterceptor();
+    }
+}

+ 40 - 0
base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/configuration/AuthConfig.java

@@ -0,0 +1,40 @@
+package com.usoftchina.saas.auth.client.configuration;
+
+import org.springframework.beans.factory.annotation.Value;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class AuthConfig {
+    @Value("${auth.public-key}")
+    private String publicKey;
+    @Value("${auth.header:Authorization}")
+    private String authHeader;
+    @Value("${spring.application.name}")
+    private String applicationName;
+
+    public String getPublicKey() {
+        return publicKey;
+    }
+
+    public void setPublicKey(String publicKey) {
+        this.publicKey = publicKey;
+    }
+
+    public String getAuthHeader() {
+        return authHeader;
+    }
+
+    public void setAuthHeader(String authHeader) {
+        this.authHeader = authHeader;
+    }
+
+    public String getApplicationName() {
+        return applicationName;
+    }
+
+    public void setApplicationName(String applicationName) {
+        this.applicationName = applicationName;
+    }
+}

+ 53 - 0
base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/interceptor/AuthRestInterceptor.java

@@ -0,0 +1,53 @@
+package com.usoftchina.saas.auth.client.interceptor;
+
+import com.usoftchina.saas.auth.client.annotation.IgnoreAuth;
+import com.usoftchina.saas.auth.client.configuration.AuthConfig;
+import com.usoftchina.saas.auth.common.jwt.JwtHelper;
+import com.usoftchina.saas.auth.common.jwt.JwtInfo;
+import com.usoftchina.saas.context.BaseContextHolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class AuthRestInterceptor extends HandlerInterceptorAdapter {
+
+    private static final Logger log = LoggerFactory.getLogger(AuthRestInterceptor.class);
+
+    @Autowired
+    private AuthConfig authConfig;
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        HandlerMethod handlerMethod = (HandlerMethod) handler;
+        // 配置该注解,说明不进行用户拦截
+        IgnoreAuth annotation = handlerMethod.getBeanType().getAnnotation(IgnoreAuth.class);
+        if (annotation == null) {
+            annotation = handlerMethod.getMethodAnnotation(IgnoreAuth.class);
+        }
+        if (annotation != null) {
+            return super.preHandle(request, response, handler);
+        }
+        String token = request.getHeader(authConfig.getAuthHeader());
+        JwtInfo infoFromToken = JwtHelper.getInfoFromToken(token, authConfig.getPublicKey());
+        BaseContextHolder.setUserId(infoFromToken.getUserId());
+        BaseContextHolder.setCompanyId(infoFromToken.getCompanyId());
+        BaseContextHolder.setToken(token);
+        log.info("token={} \\r\\n userName={}", token, infoFromToken.getUserName());
+        return super.preHandle(request, response, handler);
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+        BaseContextHolder.remove();
+        super.afterCompletion(request, response, handler, ex);
+    }
+}

+ 28 - 0
base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/interceptor/ServiceFeignInterceptor.java

@@ -0,0 +1,28 @@
+package com.usoftchina.saas.auth.client.interceptor;
+
+import com.usoftchina.saas.auth.client.configuration.AuthConfig;
+import com.usoftchina.saas.context.BaseContextHolder;
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class ServiceFeignInterceptor implements RequestInterceptor {
+    @Autowired
+    private AuthConfig authConfig;
+
+    public ServiceFeignInterceptor() {
+    }
+
+    @Override
+    public void apply(RequestTemplate requestTemplate) {
+        requestTemplate.header(authConfig.getAuthHeader(), BaseContextHolder.getToken());
+    }
+
+    public void setAuthConfig(AuthConfig authConfig) {
+        this.authConfig = authConfig;
+    }
+}

+ 43 - 0
base-servers/auth/auth-common/pom.xml

@@ -0,0 +1,43 @@
+<?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">
+    <parent>
+        <artifactId>auth</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>auth-common</artifactId>
+    <description>authentication common</description>
+    <properties>
+        <jjwt.version>0.7.0</jjwt.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>${jjwt.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-netflix-core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 30 - 0
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/event/AuthRemoteEvent.java

@@ -0,0 +1,30 @@
+package com.usoftchina.saas.auth.common.event;
+
+import org.springframework.cloud.bus.event.RemoteApplicationEvent;
+
+import java.util.List;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class AuthRemoteEvent extends RemoteApplicationEvent {
+    private List<String> allowedClient;
+
+    public AuthRemoteEvent() {
+    }
+
+    public AuthRemoteEvent(Object source, String originService, String destinationService, List<String> allowedClient) {
+        super(source, originService, destinationService);
+        this.allowedClient = allowedClient;
+    }
+
+    public List<String> getAllowedClient() {
+        return allowedClient;
+    }
+
+    public void setAllowedClient(List<String> allowedClient) {
+        this.allowedClient = allowedClient;
+    }
+}
+

+ 101 - 0
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/jwt/JwtHelper.java

@@ -0,0 +1,101 @@
+package com.usoftchina.saas.auth.common.jwt;
+
+import com.usoftchina.saas.exception.BizException;
+import com.usoftchina.saas.exception.ExceptionCode;
+import com.usoftchina.saas.utils.RsaUtils;
+import com.usoftchina.saas.utils.ObjectUtils;
+import io.jsonwebtoken.*;
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class JwtHelper {
+
+    private static final Logger log = LoggerFactory.getLogger(JwtHelper.class);
+
+    /**
+     * 密钥加密token
+     *
+     * @param jwtInfo    jwt 帐号信息
+     * @param priKeyPath 私钥地址
+     * @param expire     过期时间
+     * @return
+     * @throws Exception
+     */
+    public static TokenVO generateToken(JwtInfo jwtInfo, String priKeyPath, int expire) throws BizException {
+        try {
+            String compactJws =
+                    // 返回的字符串便是我们的jwt串了
+                    Jwts.builder()
+                            // 设置主题
+                            .setSubject(jwtInfo.getUserName())
+                            .claim("userId", jwtInfo.getUserId())
+                            .claim("companyId", jwtInfo.getCompanyId())
+                            .claim("userName", jwtInfo.getUserName())
+                            .setExpiration(DateTime.now().plusSeconds(expire).toDate())
+                            // 设置算法(必须)
+                            .signWith(SignatureAlgorithm.RS256, RsaUtils.getPrivateKey(priKeyPath))
+                            // 这个是全部设置完成后拼成jwt串的方法
+                            .compact();
+            return new TokenVO(compactJws, expire);
+        } catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) {
+            log.error(e.getMessage());
+            throw new BizException(ExceptionCode.JWT_GEN_TOKEN_FAIL.getCode(), ExceptionCode.JWT_GEN_TOKEN_FAIL.getMessage());
+        }
+    }
+
+    /**
+     * 公钥解析token
+     *
+     * @param token
+     * @param pubKeyPath 公钥路径
+     * @return
+     * @throws Exception
+     */
+    private static Jws<Claims> parserToken(String token, String pubKeyPath) throws BizException {
+        try {
+            return Jwts.parser().setSigningKey(RsaUtils.getPublicKey(pubKeyPath)).parseClaimsJws(token);
+        } catch (ExpiredJwtException ex) {
+            log.error("ExpiredJwtException:", ex);
+            //过期
+            throw new BizException(ExceptionCode.JWT_TOKEN_EXPIRED.getCode(), ExceptionCode.JWT_TOKEN_EXPIRED.getMessage());
+        } catch (SignatureException ex) {
+            log.error("SignatureException:", ex);
+            //签名错误
+            throw new BizException(ExceptionCode.JWT_SIGNATURE.getCode(), ExceptionCode.JWT_SIGNATURE.getMessage());
+        } catch (IllegalArgumentException ex) {
+            log.error("IllegalArgumentException:", ex);
+            //token 为空
+            throw new BizException(ExceptionCode.JWT_ILLEGAL_ARGUMENT.getCode(), ExceptionCode.JWT_ILLEGAL_ARGUMENT.getMessage());
+        } catch (Exception e) {
+            log.error("message:", e);
+            throw new BizException(ExceptionCode.JWT_PARSER_TOKEN_FAIL.getCode(), ExceptionCode.JWT_PARSER_TOKEN_FAIL.getMessage());
+        }
+    }
+
+    /**
+     * 获取token中的用户信息
+     *
+     * @param token      token
+     * @param pubKeyPath 公钥路径
+     * @return
+     * @throws Exception
+     */
+    public static JwtInfo getInfoFromToken(String token, String pubKeyPath) throws BizException {
+        Jws<Claims> claimsJws = parserToken(token, pubKeyPath);
+        Claims body = claimsJws.getBody();
+        return new JwtInfo(
+                ObjectUtils.getLongValue(body.get("userId")),
+                ObjectUtils.getLongValue(body.get("companyId")),
+                ObjectUtils.getStringValue(body.get("userName"))
+        );
+    }
+}

+ 43 - 0
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/jwt/JwtInfo.java

@@ -0,0 +1,43 @@
+package com.usoftchina.saas.auth.common.jwt;
+
+import java.io.Serializable;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class JwtInfo implements Serializable{
+    private Long companyId;
+    private Long userId;
+    private String userName;
+
+    public JwtInfo(Long companyId, Long userId, String userName) {
+        this.companyId = companyId;
+        this.userId = userId;
+        this.userName = userName;
+    }
+
+    public Long getCompanyId() {
+        return companyId;
+    }
+
+    public void setCompanyId(Long companyId) {
+        this.companyId = companyId;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+}

+ 59 - 0
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/jwt/TokenVO.java

@@ -0,0 +1,59 @@
+package com.usoftchina.saas.auth.common.jwt;
+
+import java.io.Serializable;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+public class TokenVO implements Serializable {
+    /**
+     * token
+     */
+    private String token;
+    /**
+     * 有效时间:单位:秒
+     */
+    private Integer expire;
+
+    private Long timestamp;
+
+    public TokenVO(String token, Integer expire) {
+        this.token = token;
+        this.expire = expire;
+        this.timestamp = System.currentTimeMillis();
+    }
+
+    public String getToken() {
+        return token;
+    }
+
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    public Integer getExpire() {
+        return expire;
+    }
+
+    public void setExpire(Integer expire) {
+        this.expire = expire;
+    }
+
+    public Long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    @Override
+    public String toString() {
+        return "TokenVO{" +
+                "token='" + token + '\'' +
+                ", expire=" + expire +
+                ", timestamp=" + timestamp +
+                '}';
+    }
+}

+ 22 - 0
base-servers/auth/auth-dto/pom.xml

@@ -0,0 +1,22 @@
+<?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">
+    <parent>
+        <artifactId>auth</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>auth-dto</artifactId>
+    <description>authentication data transfer object</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+</project>

+ 71 - 0
base-servers/auth/auth-dto/src/main/java/com/usoftchina/saas/auth/dto/TokenDTO.java

@@ -0,0 +1,71 @@
+package com.usoftchina.saas.auth.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * @author yingp
+ * @date 2018/9/30
+ */
+@ApiModel(value = "Token", description = "Token")
+public class TokenDTO implements Serializable{
+    /**
+     * token
+     */
+    @ApiModelProperty(value = "token")
+    private String token;
+    /**
+     * 有效时间:单位:秒
+     */
+    @ApiModelProperty(value = "有效时间(秒)")
+    private Integer expire;
+    /**
+     * 产生时间
+     */
+    @ApiModelProperty(value = "产生时间")
+    private Long timestamp;
+
+    public TokenDTO() {
+    }
+
+    public TokenDTO(String token, Integer expire) {
+        this.token = token;
+        this.expire = expire;
+        this.timestamp = System.currentTimeMillis();
+    }
+
+    public String getToken() {
+        return token;
+    }
+
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    public Integer getExpire() {
+        return expire;
+    }
+
+    public void setExpire(Integer expire) {
+        this.expire = expire;
+    }
+
+    public Long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    @Override
+    public String toString() {
+        return "TokenDTO{" +
+                "token='" + token + '\'' +
+                ", expire=" + expire +
+                ", timestamp=" + timestamp +
+                '}';
+    }
+}

+ 88 - 0
base-servers/auth/auth-server/pom.xml

@@ -0,0 +1,88 @@
+<?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">
+    <parent>
+        <artifactId>auth</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>auth-server</artifactId>
+    <description>authentication server</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>auth-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>auth-dto</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>account-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.hibernate</groupId>
+                    <artifactId>hibernate-validator</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.tomcat.embed</groupId>
+                    <artifactId>tomcat-embed-websocket</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!-- management -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+        </dependency>
+        <!-- db -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+        </dependency>
+        <!-- api doc -->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 17 - 0
base-servers/auth/auth-server/src/main/java/com/usoftchina/saas/auth/AuthApplication.java

@@ -0,0 +1,17 @@
+package com.usoftchina.saas.auth;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
+
+/**
+ * @author yingp
+ * @date 2018/9/30
+ */
+@SpringBootApplication
+@EnableEurekaClient
+public class AuthApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(AuthApplication.class, args);
+    }
+}

+ 51 - 0
base-servers/auth/auth-server/src/main/java/com/usoftchina/saas/auth/controller/AuthController.java

@@ -0,0 +1,51 @@
+package com.usoftchina.saas.auth.controller;
+
+import com.usoftchina.saas.account.api.AccountApi;
+import com.usoftchina.saas.account.dto.AccountDTO;
+import com.usoftchina.saas.auth.common.jwt.JwtHelper;
+import com.usoftchina.saas.auth.common.jwt.JwtInfo;
+import com.usoftchina.saas.auth.common.jwt.TokenVO;
+import com.usoftchina.saas.auth.dto.TokenDTO;
+import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.utils.BeanMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author yingp
+ * @date 2018/10/2
+ */
+@RestController
+@RequestMapping(path = "/api/auth")
+public class AuthController {
+
+    @Autowired
+    private AccountApi accountApi;
+
+    @Value("${auth.private-key}")
+    private String privateKeyPath;
+
+    @Value("${auth.expire:18000}")
+    private int expire;
+
+    /**
+     * 登录认证获取token
+     *
+     * @param username
+     * @param password
+     * @return
+     */
+    @PostMapping
+    public Result<TokenDTO> authorize(@RequestParam(value = "username") String username, @RequestParam(value = "password") String password) {
+        Result<AccountDTO> result = accountApi.validByUsernameAndPwd(username, password);
+        if (result.isSuccess()) {
+            AccountDTO accountDTO = result.getData();
+            JwtInfo info = new JwtInfo(accountDTO.getCompanyId(), accountDTO.getId(), accountDTO.getUsername());
+            TokenVO tokenVO = JwtHelper.generateToken(info, privateKeyPath, expire);
+            TokenDTO tokenDTO = BeanMapper.map(tokenVO, TokenDTO.class);
+            return Result.success(tokenDTO);
+        }
+        return Result.error(result.getCode(), result.getMessage());
+    }
+}

+ 42 - 0
base-servers/auth/auth-server/src/main/resources/application.yml

@@ -0,0 +1,42 @@
+spring:
+  application:
+    name: auth-server
+  security:
+    user:
+      name: admin
+      password: select111***
+  datasource:
+    hikari:
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      jdbc-url: jdbc:mysql://192.168.253.12:3306/saas_auth?characterEncoding=utf-8&useSSL=false
+      username: root
+      password: select111***
+  messages:
+    basename: i18n/messages
+eureka:
+  instance:
+    leaseRenewalIntervalInSeconds: 10
+    health-check-url-path: /actuator/health
+    status-page-url-path: /actuator/info
+    metadata-map:
+      user.name: ${spring.security.user.name}
+      user.password: ${spring.security.user.password}
+  client:
+    registryFetchIntervalSeconds: 5
+    serviceUrl:
+      defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@127.0.0.1:8500/eureka/
+server:
+  port: 8580
+  tomcat:
+    uri-encoding: UTF-8
+info:
+  name: '@project.artifactId@'
+  description: '@project.description@'
+  version: '@project.version@'
+  spring-boot-version: '@spring.boot.version@'
+  spring-cloud-version: '@spring.cloud.version@'
+mybatis:
+  type-aliases-package: com.usoftchina.saas.auth.po
+  mapper-locations: classpath:mapper/*.xml
+auth:
+  private-key: auth/pri.key

BIN
base-servers/auth/auth-server/src/main/resources/auth/pri.key


+ 15 - 0
base-servers/auth/auth-server/src/main/resources/banner.txt

@@ -0,0 +1,15 @@
+${AnsiColor.BRIGHT_YELLOW}
+
+88        88   ad88888ba     ,ad8888ba,    88888888888  888888888888  ,ad8888ba,   88        88  88  888b      88         db
+88        88  d8"     "8b   d8"'    `"8b   88                88      d8"'    `"8b  88        88  88  8888b     88        d88b
+88        88  Y8,          d8'        `8b  88                88     d8'            88        88  88  88 `8b    88       d8'`8b
+88        88  `Y8aaaaa,    88          88  88aaaaa           88     88             88aaaaaaaa88  88  88  `8b   88      d8'  `8b
+88        88    `"""""8b,  88          88  88"""""           88     88             88""""""""88  88  88   `8b  88     d8YaaaaY8b
+88        88          `8b  Y8,        ,8P  88                88     Y8,            88        88  88  88    `8b 88    d8""""""""8b
+Y8a.    .a8P  Y8a     a8P   Y8a.    .a8P   88                88      Y8a.    .a8P  88        88  88  88     `8888   d8'        `8b
+ `"Y8888Y"'    "Y88888P"     `"Y8888Y"'    88                88       `"Y8888Y"'   88        88  88  88      `888  d8'          `8b
+
+
+Application Version: ${application.version}${application.formatted-version}
+Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
+${AnsiColor.DEFAULT}

+ 64 - 0
base-servers/auth/auth-server/src/main/resources/logback-spring.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
+    <jmxConfigurator/>
+
+    <!--
+    %m
+    输出代码中指定的消息
+    %p
+    输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
+    %r
+    输出自应用启动到输出该log信息耗费的毫秒数
+    %c
+    输出所属的类目,通常就是所在类的全名
+    %t
+    输出产生该日志事件的线程名
+    %n
+    输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
+    %d
+    输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},
+    输出类似:2002年10月18日 22:10:28,921
+    %l
+    输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)
+    -->
+
+    <springProperty scope="context" name="log.path" source="logging.path" defaultValue="/var/log/saas/auth-server"/>
+    <springProperty scope="context" name="spring.application.name" source="spring.application.name" defaultValue="auth-server"/>
+    <springProperty scope="context" name="spring.profiles.active" source="spring.profiles.active" defaultValue="dev"/>
+    <springProperty scope="context" name="common-pattern" source="logging.common-pattern" defaultValue="%d{yyyy-MM-dd HH:mm:ss.SSS}:[%5p] [%t:%r] [%C{1}:%M:%L] --> %m%n"/>
+    <springProperty scope="context" name="log.level.console" source="logging.level.console" defaultValue="INFO"/>
+
+    <contextName>${spring.application.name}-${spring.profiles.active}-logback</contextName>
+
+
+    <appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>${log.level.console}</level>
+        </filter>
+        <encoder>
+            <pattern>${common-pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="ROOT_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/root.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- 每天一归档 -->
+            <fileNamePattern>${log.path}/%d{yyyy-MM}/root-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
+            <!-- 单个日志文件最多 100MB, 60天的日志周期,最大不能超过20GB -->
+            <maxFileSize>128MB</maxFileSize>
+            <maxHistory>60</maxHistory>
+            <totalSizeCap>20GB</totalSizeCap>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${common-pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <root level="${log.level.console}">
+        <appender-ref ref="CONSOLE_APPENDER"/>
+        <appender-ref ref="ROOT_APPENDER"/>
+    </root>
+
+</configuration>

+ 4 - 0
base-servers/auth/auth-server/src/main/resources/mapper/AccountMapper.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.usoftchina.saas.auth.mapper.AccountMapper">
+</mapper>

+ 4 - 0
base-servers/auth/auth-server/src/main/resources/mapper/AccountRoleMapper.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.usoftchina.saas.auth.mapper.AccountRoleMapper">
+</mapper>

+ 4 - 0
base-servers/auth/auth-server/src/main/resources/mapper/ResourcesMapper.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.usoftchina.saas.auth.mapper.ResourcesMapper">
+</mapper>

+ 4 - 0
base-servers/auth/auth-server/src/main/resources/mapper/RoleMapper.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.usoftchina.saas.auth.mapper.RoleMapper">
+</mapper>

+ 4 - 0
base-servers/auth/auth-server/src/main/resources/mapper/RoleResourceMapper.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.usoftchina.saas.auth.mapper.RoleResourceMapper">
+</mapper>

+ 23 - 0
base-servers/auth/pom.xml

@@ -0,0 +1,23 @@
+<?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">
+    <parent>
+        <artifactId>base-servers</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>auth</artifactId>
+    <packaging>pom</packaging>
+    <description>authentication</description>
+    <modules>
+        <module>auth-api</module>
+        <module>auth-dto</module>
+        <module>auth-server</module>
+        <module>auth-client</module>
+        <module>auth-common</module>
+    </modules>
+
+</project>

+ 38 - 0
base-servers/eureka-server/pom.xml

@@ -0,0 +1,38 @@
+<?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">
+    <parent>
+        <artifactId>base-servers</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>eureka-server</artifactId>
+    <description>service registry</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-eureka-server</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-actuator</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 17 - 0
base-servers/eureka-server/src/main/java/com/usoftchina/saas/eureka/EurekaApplication.java

@@ -0,0 +1,17 @@
+package com.usoftchina.saas.eureka;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
+
+/**
+ * @author yingp
+ * @date 2018/9/28
+ */
+@SpringBootApplication
+@EnableEurekaServer
+public class EurekaApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(EurekaApplication.class, args);
+    }
+}

+ 19 - 0
base-servers/eureka-server/src/main/java/com/usoftchina/saas/eureka/config/WebSecurityConfig.java

@@ -0,0 +1,19 @@
+package com.usoftchina.saas.eureka.config;
+
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+/**
+ * @author yingp
+ * @date 2018/9/28
+ */
+@EnableWebSecurity
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.csrf().disable();
+        super.configure(http);
+    }
+}

+ 33 - 0
base-servers/eureka-server/src/main/resources/application.yml

@@ -0,0 +1,33 @@
+spring:
+  application:
+    name: eureka-server
+  security:
+    user:
+      name: admin
+      password: select111***
+eureka:
+  server:
+    enable-self-preservation: false
+  instance:
+    status-page-url-path: /actuator/info
+    health-check-url-path: /actuator/health
+    home-page-url-path: /
+    hostname: localhost
+    metadata-map:
+      user.name: ${spring.security.user.name}
+      user.password: ${spring.security.user.password}
+  client:
+    register-with-eureka: false
+    fetch-registry: false
+    service-url:
+      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
+server:
+  port: 8500
+  tomcat:
+    uri-encoding: UTF-8
+info:
+  name: '@project.artifactId@'
+  description: '@project.description@'
+  version: '@project.version@'
+  spring-boot-version: '@spring.boot.version@'
+  spring-cloud-version: '@spring.cloud.version@'

+ 15 - 0
base-servers/eureka-server/src/main/resources/banner.txt

@@ -0,0 +1,15 @@
+${AnsiColor.BRIGHT_YELLOW}
+
+88        88   ad88888ba     ,ad8888ba,    88888888888  888888888888  ,ad8888ba,   88        88  88  888b      88         db
+88        88  d8"     "8b   d8"'    `"8b   88                88      d8"'    `"8b  88        88  88  8888b     88        d88b
+88        88  Y8,          d8'        `8b  88                88     d8'            88        88  88  88 `8b    88       d8'`8b
+88        88  `Y8aaaaa,    88          88  88aaaaa           88     88             88aaaaaaaa88  88  88  `8b   88      d8'  `8b
+88        88    `"""""8b,  88          88  88"""""           88     88             88""""""""88  88  88   `8b  88     d8YaaaaY8b
+88        88          `8b  Y8,        ,8P  88                88     Y8,            88        88  88  88    `8b 88    d8""""""""8b
+Y8a.    .a8P  Y8a     a8P   Y8a.    .a8P   88                88      Y8a.    .a8P  88        88  88  88     `8888   d8'        `8b
+ `"Y8888Y"'    "Y88888P"     `"Y8888Y"'    88                88       `"Y8888Y"'   88        88  88  88      `888  d8'          `8b
+
+
+Application Version: ${application.version}${application.formatted-version}
+Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
+${AnsiColor.DEFAULT}

+ 64 - 0
base-servers/eureka-server/src/main/resources/logback-spring.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
+    <jmxConfigurator/>
+
+    <!--
+    %m
+    输出代码中指定的消息
+    %p
+    输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
+    %r
+    输出自应用启动到输出该log信息耗费的毫秒数
+    %c
+    输出所属的类目,通常就是所在类的全名
+    %t
+    输出产生该日志事件的线程名
+    %n
+    输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
+    %d
+    输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},
+    输出类似:2002年10月18日 22:10:28,921
+    %l
+    输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)
+    -->
+
+    <springProperty scope="context" name="log.path" source="logging.path" defaultValue="/var/log/saas/eureka-server"/>
+    <springProperty scope="context" name="spring.application.name" source="spring.application.name" defaultValue="eureka-server"/>
+    <springProperty scope="context" name="spring.profiles.active" source="spring.profiles.active" defaultValue="dev"/>
+    <springProperty scope="context" name="common-pattern" source="logging.common-pattern" defaultValue="%d{yyyy-MM-dd HH:mm:ss.SSS}:[%5p] [%t:%r] [%C{1}:%M:%L] --> %m%n"/>
+    <springProperty scope="context" name="log.level.console" source="logging.level.console" defaultValue="INFO"/>
+
+    <contextName>${spring.application.name}-${spring.profiles.active}-logback</contextName>
+
+
+    <appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>${log.level.console}</level>
+        </filter>
+        <encoder>
+            <pattern>${common-pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="ROOT_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/root.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- 每天一归档 -->
+            <fileNamePattern>${log.path}/%d{yyyy-MM}/root-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
+            <!-- 单个日志文件最多 100MB, 60天的日志周期,最大不能超过20GB -->
+            <maxFileSize>128MB</maxFileSize>
+            <maxHistory>60</maxHistory>
+            <totalSizeCap>20GB</totalSizeCap>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${common-pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <root level="${log.level.console}">
+        <appender-ref ref="CONSOLE_APPENDER"/>
+        <appender-ref ref="ROOT_APPENDER"/>
+    </root>
+
+</configuration>

+ 46 - 0
base-servers/file/file-api/pom.xml

@@ -0,0 +1,46 @@
+<?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">
+    <parent>
+        <artifactId>file</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>file-api</artifactId>
+    <description>file service api</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>file-dto</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.openfeign.form</groupId>
+            <artifactId>feign-form</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.openfeign.form</groupId>
+            <artifactId>feign-form-spring</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 62 - 0
base-servers/file/file-api/src/main/java/com/usoftchina/saas/file/api/FileApi.java

@@ -0,0 +1,62 @@
+package com.usoftchina.saas.file.api;
+
+import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.file.dto.FileDTO;
+import com.usoftchina.saas.file.dto.FileListDTO;
+import com.usoftchina.saas.file.dto.FolderDTO;
+import com.usoftchina.saas.file.dto.FolderToSaveDTO;
+import feign.codec.Encoder;
+import feign.form.spring.SpringFormEncoder;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 文件接口
+ *
+ * @author yingp
+ * @date 2018/9/29
+ */
+@FeignClient(name = "gateway-server", configuration = FileApi.MultipartSupportConfig.class)
+public interface FileApi {
+
+    @Configuration
+    class MultipartSupportConfig {
+        @Bean
+        public Encoder feignFormEncoder() {
+            return new SpringFormEncoder();
+        }
+    }
+
+    /**
+     * 新建文件夹
+     *
+     * @param newFolder 待保存文件夹
+     * @return
+     */
+    @PostMapping(value = "/api/file/folder")
+    Result<FolderDTO> folder(@RequestBody FolderToSaveDTO newFolder);
+
+    /**
+     * 根据id查看文件详情
+     *
+     * @param id
+     * @return
+     */
+    @GetMapping(value = "/api/file/{id}")
+    Result<FileDTO> get(@PathVariable(value = "id") Long id);
+
+    /**
+     * 上传文件到指定文件夹
+     *
+     * @param folderId 文件夹id
+     * @param file  文件
+     * @return
+     * @throws Exception
+     */
+    @PostMapping(value = "/api/file/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    Result<FileListDTO> upload(@RequestParam(value = "folderId") Long folderId, @RequestPart(value = "file") MultipartFile file) throws Exception;
+}

+ 23 - 0
base-servers/file/file-dto/pom.xml

@@ -0,0 +1,23 @@
+<?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">
+    <parent>
+        <artifactId>file</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>file-dto</artifactId>
+    <description>file data transfer object</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+</project>

+ 60 - 0
base-servers/file/file-dto/src/main/java/com/usoftchina/saas/file/dto/BaseFolder.java

@@ -0,0 +1,60 @@
+package com.usoftchina.saas.file.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author yingp
+ * @date 2018/9/29
+ */
+public abstract class BaseFolder {
+    /**
+     * 名称
+     */
+    @ApiModelProperty(value = "名称")
+    protected String originalFilename;
+
+    /**
+     * 父文件夹
+     */
+    @ApiModelProperty(value = "父文件夹ID")
+    protected Long parentId;
+
+    /**
+     * 排序
+     */
+    @ApiModelProperty(value = "排序")
+    protected Integer orderNum;
+
+    public String getOriginalFilename() {
+        return originalFilename;
+    }
+
+    public void setOriginalFilename(String originalFilename) {
+        this.originalFilename = originalFilename;
+    }
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+
+    public Integer getOrderNum() {
+        return orderNum;
+    }
+
+    public void setOrderNum(Integer orderNum) {
+        this.orderNum = orderNum;
+    }
+
+    @Override
+    public String toString() {
+        return "BaseFolder{" +
+                "originalFilename='" + originalFilename + '\'' +
+                ", parentId=" + parentId +
+                ", orderNum=" + orderNum +
+                '}';
+    }
+}

+ 179 - 0
base-servers/file/file-dto/src/main/java/com/usoftchina/saas/file/dto/FileDTO.java

@@ -0,0 +1,179 @@
+package com.usoftchina.saas.file.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * @author yingp
+ * @date 2018/9/29
+ */
+@ApiModel(value = "File", description = "文件")
+public class FileDTO implements Serializable {
+    @ApiModelProperty(value = "id")
+    private Long id;
+    /**
+     * 文件夹id
+     */
+    @ApiModelProperty(value = "文件夹id")
+    private Long folderId;
+
+    /**
+     * 文件夹名称
+     */
+    @ApiModelProperty(value = "文件夹名称")
+    private Long folderName;
+
+    /**
+     * 链接
+     */
+    @ApiModelProperty(value = "文件url")
+    private String url;
+
+    /**
+     * 类型
+     */
+    @ApiModelProperty(value = "文件mime类型")
+    private String mime;
+
+    /**
+     * 原始文件名
+     */
+    @ApiModelProperty(value = "原始文件名")
+    private String originalFilename;
+
+    /**
+     * 文件名
+     */
+    @ApiModelProperty(value = "唯一文件名")
+    private String filename;
+
+    /**
+     * 后缀 (没有.)
+     */
+    @ApiModelProperty(value = "后缀")
+    private String ext;
+
+    /**
+     * 大小
+     */
+    @ApiModelProperty(value = "大小")
+    private String size;
+
+    /**
+     * 图标
+     */
+    @ApiModelProperty(value = "图标")
+    private String icon;
+    /**
+     * 文件类型
+     */
+    @ApiModelProperty(value = "文件类型 IMAGE/VIDEO/AUDIO/DOC/OTHER/DIR", example = "IMAGE/VIDEO/AUDIO/DOC/OTHER/DIR")
+    private String dataType;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getFolderId() {
+        return folderId;
+    }
+
+    public void setFolderId(Long folderId) {
+        this.folderId = folderId;
+    }
+
+    public Long getFolderName() {
+        return folderName;
+    }
+
+    public void setFolderName(Long folderName) {
+        this.folderName = folderName;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getMime() {
+        return mime;
+    }
+
+    public void setMime(String mime) {
+        this.mime = mime;
+    }
+
+    public String getOriginalFilename() {
+        return originalFilename;
+    }
+
+    public void setOriginalFilename(String originalFilename) {
+        this.originalFilename = originalFilename;
+    }
+
+    public String getFilename() {
+        return filename;
+    }
+
+    public void setFilename(String filename) {
+        this.filename = filename;
+    }
+
+    public String getExt() {
+        return ext;
+    }
+
+    public void setExt(String ext) {
+        this.ext = ext;
+    }
+
+    public String getSize() {
+        return size;
+    }
+
+    public void setSize(String size) {
+        this.size = size;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public String getDataType() {
+        return dataType;
+    }
+
+    public void setDataType(String dataType) {
+        this.dataType = dataType;
+    }
+
+    @Override
+    public String toString() {
+        return "FileDTO{" +
+                "id=" + id +
+                ", folderId=" + folderId +
+                ", folderName=" + folderName +
+                ", url='" + url + '\'' +
+                ", mime='" + mime + '\'' +
+                ", originalFilename='" + originalFilename + '\'' +
+                ", filename='" + filename + '\'' +
+                ", ext='" + ext + '\'' +
+                ", size='" + size + '\'' +
+                ", icon='" + icon + '\'' +
+                ", dataType='" + dataType + '\'' +
+                '}';
+    }
+}

+ 31 - 0
base-servers/file/file-dto/src/main/java/com/usoftchina/saas/file/dto/FileListDTO.java

@@ -0,0 +1,31 @@
+package com.usoftchina.saas.file.dto;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author yingp
+ * @date 2018/9/29
+ */
+public class FileListDTO implements Serializable {
+    private List<FileDTO> files;
+
+    public FileListDTO(List<FileDTO> files) {
+        this.files = files;
+    }
+
+    public List<FileDTO> getFiles() {
+        return files;
+    }
+
+    public void setFiles(List<FileDTO> files) {
+        this.files = files;
+    }
+
+    @Override
+    public String toString() {
+        return "FileListDTO{" +
+                "files=" + files +
+                '}';
+    }
+}

+ 32 - 0
base-servers/file/file-dto/src/main/java/com/usoftchina/saas/file/dto/FolderDTO.java

@@ -0,0 +1,32 @@
+package com.usoftchina.saas.file.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * @author yingp
+ * @date 2018/9/29
+ */
+public class FolderDTO extends BaseFolder implements Serializable{
+    @ApiModelProperty(value = "id", required = true)
+    private Long id;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    @Override
+    public String toString() {
+        return "FolderDTO{" +
+                "id=" + id +
+                ", originalFilename='" + originalFilename + '\'' +
+                ", parentId=" + parentId +
+                ", orderNum=" + orderNum +
+                '}';
+    }
+}

+ 18 - 0
base-servers/file/file-dto/src/main/java/com/usoftchina/saas/file/dto/FolderToSaveDTO.java

@@ -0,0 +1,18 @@
+package com.usoftchina.saas.file.dto;
+
+import java.io.Serializable;
+
+/**
+ * @author yingp
+ * @date 2018/9/29
+ */
+public class FolderToSaveDTO extends BaseFolder implements Serializable{
+    @Override
+    public String toString() {
+        return "FolderToSaveDTO{" +
+                "originalFilename='" + originalFilename + '\'' +
+                ", parentId=" + parentId +
+                ", orderNum=" + orderNum +
+                '}';
+    }
+}

+ 59 - 0
base-servers/file/file-server/pom.xml

@@ -0,0 +1,59 @@
+<?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">
+    <parent>
+        <artifactId>file</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>file-server</artifactId>
+    <description>file service</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>file-dto</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper-spring-boot-starter</artifactId>
+        </dependency>
+        <!-- api doc -->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 21 - 0
base-servers/file/file-server/src/main/java/com/usoftchina/saas/file/FileApplication.java

@@ -0,0 +1,21 @@
+package com.usoftchina.saas.file;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
+import org.springframework.cloud.netflix.hystrix.EnableHystrix;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+/**
+ * @author yingp
+ * @date 2018/9/29
+ */
+@SpringBootApplication
+@EnableEurekaClient
+@EnableHystrix
+@EnableTransactionManagement
+public class FileApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(FileApplication.class, args);
+    }
+}

+ 37 - 0
base-servers/file/file-server/src/main/java/com/usoftchina/saas/file/controller/FileController.java

@@ -0,0 +1,37 @@
+package com.usoftchina.saas.file.controller;
+
+import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.exception.ExceptionCode;
+import com.usoftchina.saas.file.dto.FolderDTO;
+import com.usoftchina.saas.file.dto.FolderToSaveDTO;
+import com.usoftchina.saas.file.service.FileService;
+import com.usoftchina.saas.utils.BizAssert;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 文件接口
+ *
+ * @author yingp
+ * @date 2018/9/29
+ */
+@Api(value = "FileApi", description = "文件管理")
+@RestController
+@RequestMapping("/api/file")
+public class FileController {
+
+    @Autowired
+    private FileService fileService;
+
+    @ApiOperation(value = "保存文件夹")
+    @PostMapping(value = "/folder")
+    public Result<FolderDTO> folder(@RequestBody FolderToSaveDTO newFolder) {
+        BizAssert.notNull(newFolder.getOriginalFilename(), ExceptionCode.FOLDER_NAME_EMPTY);
+        return Result.success();
+    }
+}

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