多租户配置
diff --git a/build.gradle b/build.gradle
index 72ec3a0..96a615d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -53,7 +53,7 @@
     implementation group: 'taglibs', name: 'standard', version: '1.1.2'
     implementation group: 'commons-codec', name: 'commons-codec', version: '1.6'
     implementation files('libs/ojdbc6.jar')
-
+    implementation 'commons-dbcp:commons-dbcp:1.4'
 
     annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
 
diff --git a/config/application-devel-pg.properties b/config/application-devel-pg.properties
index 61b2df9..61c327f 100644
--- a/config/application-devel-pg.properties
+++ b/config/application-devel-pg.properties
@@ -24,8 +24,19 @@
 security.request.sign=false
 ##################################################
 ## quartz task scheduler
-<<<<<<< HEAD
 shopbalance.updater.cron=-
-=======
-shopbalance.updater.cron = -
->>>>>>> 手机端API认证
+
+##################多租户配置 start################################
+#多租户时使用的配置,如果不是用多租户,以下可注释掉
+#spring.jpa.properties.hibernate.multiTenancy=DATABASE
+#spring.jpa.properties.hibernate.tenant_identifier_resolver=com.supwisdom.dlpay.framework.tenant.MultiTenantIdentifierResolver
+#spring.jpa.properties.hibernate.multi_tenant_connection_provider=com.supwisdom.dlpay.framework.tenant.MultiTenantConnectionProviderImpl
+#datasource.driverClass=org.postgresql.Driver
+#datasource.url=jdbc:postgresql://172.28.201.70:15432/payapi
+#datasource.username=payapi
+#datasource.password=123456
+#datasource.maxActive=100
+#datasource.maxIdle=30
+#datasource.maxWait=30
+#datasource.minIdle=5
+##################多租户配置 end################################
\ No newline at end of file
diff --git a/src/main/java/com/supwisdom/dlpay/framework/tenant/MultiTenantConnectionProviderImpl.java b/src/main/java/com/supwisdom/dlpay/framework/tenant/MultiTenantConnectionProviderImpl.java
new file mode 100644
index 0000000..0f1d799
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/framework/tenant/MultiTenantConnectionProviderImpl.java
@@ -0,0 +1,20 @@
+package com.supwisdom.dlpay.framework.tenant;
+
+import org.hibernate.engine.jdbc.connections.spi.AbstractDataSourceBasedMultiTenantConnectionProviderImpl;
+
+import javax.sql.DataSource;
+
+/**
+ * Created by shuwei on 2018/12/4.
+ */
+public class MultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
+    @Override
+    protected DataSource selectAnyDataSource() {
+        return TenantDataSourceProvider.getTenantDataSource("default");
+    }
+
+    @Override
+    protected DataSource selectDataSource(String tenantIdentifier) {
+        return TenantDataSourceProvider.getTenantDataSource(TenantThread.getTenantSchema());
+    }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/tenant/MultiTenantIdentifierResolver.java b/src/main/java/com/supwisdom/dlpay/framework/tenant/MultiTenantIdentifierResolver.java
new file mode 100644
index 0000000..d2dc781
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/framework/tenant/MultiTenantIdentifierResolver.java
@@ -0,0 +1,21 @@
+package com.supwisdom.dlpay.framework.tenant;
+
+import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
+
+/**
+ * Created by shuwei on 2018/12/4.
+ */
+public class MultiTenantIdentifierResolver implements CurrentTenantIdentifierResolver {
+    @Override
+    public String resolveCurrentTenantIdentifier() {
+        if(TenantThread.getTenantSchema()==null){
+            return "default";
+        }
+        return TenantThread.getTenantSchema();
+    }
+
+    @Override
+    public boolean validateExistingCurrentSessions() {
+        return true;
+    }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/tenant/TenantDataSourceProvider.java b/src/main/java/com/supwisdom/dlpay/framework/tenant/TenantDataSourceProvider.java
new file mode 100644
index 0000000..d93db46
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/framework/tenant/TenantDataSourceProvider.java
@@ -0,0 +1,96 @@
+package com.supwisdom.dlpay.framework.tenant;
+
+import org.apache.commons.dbcp.BasicDataSource;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.sql.DataSource;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by shuwei on 2018/12/4.
+ */
+@Component
+public class TenantDataSourceProvider {
+    @Value("${datasource.driverClass}")
+    private String driver;
+    @Value("${datasource.url}")
+    private String url;
+    @Value("${datasource.username}")
+    private String username;
+    @Value("${datasource.password}")
+    private String password;
+    @Value("${datasource.maxIdle}")
+    private int maxIdle;
+    @Value("${datasource.maxActive}")
+    private int maxActive;
+    @Value("${datasource.minIdle}")
+    private int minIdle;
+    @Value("${datasource.maxWait}")
+    private int maxWait;
+
+    public static String static_driver;
+    public static String static_url;
+    public static String static_username;
+    public static String static_password;
+    public static int static_maxIdle;
+    public static int static_maxActive;
+    public static int static_minIdle;
+    public static int static_maxWait;
+
+
+    @PostConstruct
+    public void beforeInit() {
+        static_driver = driver;
+        static_url = url;
+        static_username = username;
+        static_password = password;
+        static_maxIdle = maxIdle;
+        static_maxActive = maxActive;
+        static_minIdle = minIdle;
+        static_maxWait = maxWait;
+    }
+    // 使用一个map来存储我们租户和对应的数据源,租户和数据源的信息就是从我们的tenant_info表中读出来
+    private static Map<String, DataSource> dataSourceMap = new HashMap<>();
+
+    /**
+     * 静态建立一个数据源,也就是我们的默认数据源,假如我们的访问信息里面没有指定tenantId,就使用默认数据源。
+     * 在我这里默认数据源是cloud_config,实际上你可以指向你们的公共信息的库,或者拦截这个操作返回错误。
+     */
+    // 根据传进来的tenantId决定返回的数据源
+    public static DataSource getTenantDataSource(String schemaId) {
+        DataSource d = dataSourceMap.get(schemaId);
+        if (d == null) {
+            String appSchema = schemaId != null ? "'" + schemaId + "','public'" : "'public'";
+            String searchPath = "SET search_path = " + appSchema + ";";
+            d = createDataSource(schemaId == null, searchPath);
+            dataSourceMap.put(schemaId, d);
+        }
+        return d;
+    }
+
+    // 初始化的时候用于添加数据源的方法
+    public static DataSource createDataSource(boolean rootdatabase, String searchPath) {
+        BasicDataSource dataSource = new BasicDataSource();
+        dataSource.setDriverClassName(static_driver);
+        dataSource.setUrl(static_url);
+        dataSource.setUsername(static_username);
+        dataSource.setPassword(static_password);
+        dataSource.setMaxActive(static_maxActive);
+        dataSource.setMaxIdle(static_maxIdle);
+        dataSource.setMaxWait(static_maxWait);
+        dataSource.setMinIdle(static_minIdle);
+        if(static_driver.toLowerCase().contains("oracle")){
+            dataSource.setValidationQuery("select 1 from dual");
+        }else {
+            dataSource.setValidationQuery("select 1 ");
+            if(static_driver.toLowerCase().contains("postgresql")) {
+                dataSource.setConnectionInitSqls(Collections.singletonList(searchPath));
+            }
+        }
+        return dataSource;
+    }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/tenant/TenantThread.java b/src/main/java/com/supwisdom/dlpay/framework/tenant/TenantThread.java
new file mode 100644
index 0000000..2bfb113
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/framework/tenant/TenantThread.java
@@ -0,0 +1,16 @@
+package com.supwisdom.dlpay.framework.tenant;
+
+/**
+ * Created by shuwei on 2018/11/29.
+ */
+public class TenantThread {
+    private static ThreadLocal<String> tenant_schema = new ThreadLocal<>();
+
+    public static void setTenantSchema(String tid) {
+        tenant_schema.set(tid);
+    }
+
+    public static String getTenantSchema() {
+        return tenant_schema.get();
+    }
+}
diff --git a/src/main/kotlin/com/supwisdom/dlpay/mobile/AuthLoginHandler.kt b/src/main/kotlin/com/supwisdom/dlpay/mobile/AuthLoginHandler.kt
index e1b5869..d401fa0 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/mobile/AuthLoginHandler.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/mobile/AuthLoginHandler.kt
@@ -8,6 +8,7 @@
 import com.supwisdom.dlpay.framework.domain.JwtRedis
 import com.supwisdom.dlpay.framework.redisrepo.ApiClientRepository
 import com.supwisdom.dlpay.framework.redisrepo.ApiJwtRepository
+import com.supwisdom.dlpay.framework.util.Constants
 import com.supwisdom.dlpay.framework.util.DateUtil
 import com.supwisdom.dlpay.framework.util.TradeDict
 import com.supwisdom.dlpay.mobile.dao.MobileUserDao
@@ -47,6 +48,7 @@
             val token = JwtTokenUtil(jwtConfig).generateToken(
                     mapOf("uid" to user.uid, "issuer" to "payapi",
                             "audience" to temp.phone,
+                            Constants.JWT_CLAIM_TENANTID to "mobile",
                             "authorities" to temp.authorities))
             var jwt = JwtRedis().apply {
                 jti = token.jti