From 0605dd4b364c7d74bd4a8cdde57b431187a5826d Mon Sep 17 00:00:00 2001
From: libiao <libiao.866@163.com>
Date: Sun, 17 Oct 2021 20:29:34 +0800
Subject: [PATCH 1/5] =?UTF-8?q?nf:mod:1.=E6=95=B0=E6=8D=AE=E5=BA=93?=
 =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=B0=83=E6=95=B42.=E6=89=93=E5=8D=B0?=
 =?UTF-8?q?=E5=BA=94=E7=94=A8=E5=90=AF=E5=8A=A8=E7=9A=84=E6=9C=8D=E5=8A=A1?=
 =?UTF-8?q?=E5=99=A8=E4=BF=A1=E6=81=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../main/java/com/ruoyi/RuoYiApplication.java | 102 +++++++---
 .../ruoyi/common/utils/ConfigConstant.java    |  18 ++
 .../common/utils/DefaultProfileUtil.java      |  42 ++++
 .../common/utils/SpringContextUtils.java      |  60 ++++++
 .../src/main/resources/application-druid.yml  | 112 +++++------
 ruoyi-admin/src/main/resources/logback.xml    | 184 +++++++++---------
 6 files changed, 340 insertions(+), 178 deletions(-)
 create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/common/utils/ConfigConstant.java
 create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/common/utils/DefaultProfileUtil.java
 create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/common/utils/SpringContextUtils.java

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
index e3c56ee54..99d6ae800 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
@@ -1,30 +1,72 @@
-package com.ruoyi;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
-
-/**
- * 启动程序
- * 
- * @author ruoyi
- */
-@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
-public class RuoYiApplication
-{
-    public static void main(String[] args)
-    {
-        // System.setProperty("spring.devtools.restart.enabled", "false");
-        SpringApplication.run(RuoYiApplication.class, args);
-        System.out.println("(♥◠‿◠)ノ゙  若依启动成功   ლ(´ڡ`ლ)゙  \n" +
-                " .-------.       ____     __        \n" +
-                " |  _ _   \\      \\   \\   /  /    \n" +
-                " | ( ' )  |       \\  _. /  '       \n" +
-                " |(_ o _) /        _( )_ .'         \n" +
-                " | (_,_).' __  ___(_ o _)'          \n" +
-                " |  |\\ \\  |  ||   |(_,_)'         \n" +
-                " |  | \\ `'   /|   `-'  /           \n" +
-                " |  |  \\    /  \\      /           \n" +
-                " ''-'   `'-'    `-..-'              ");
-    }
-}
+package com.ruoyi;
+
+import com.ruoyi.common.utils.DefaultProfileUtil;
+import com.ruoyi.common.utils.SpringContextUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.env.Environment;
+
+import java.lang.invoke.MethodHandles;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * 启动程序
+ * 
+ * @author ruoyi
+ */
+@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
+public class RuoYiApplication
+{
+    //private static final Log logger = LogFactory.getLog(MethodHandles.lookup().lookupClass());
+    private static final Logger syslog = LoggerFactory.getLogger(RuoYiApplication.class);
+    public static void main(String[] args)
+    {
+        // System.setProperty("spring.devtools.restart.enabled", "false");
+        //SpringApplication.run(RuoYiApplication.class, args);
+        //System.out.println("(♥◠‿◠)ノ゙  若依启动成功   ლ(´ڡ`ლ)゙  \n" +
+        //        " .-------.       ____     __        \n" +
+        //        " |  _ _   \\      \\   \\   /  /    \n" +
+        //        " | ( ' )  |       \\  _. /  '       \n" +
+        //        " |(_ o _) /        _( )_ .'         \n" +
+        //        " | (_,_).' __  ___(_ o _)'          \n" +
+        //        " |  |\\ \\  |  ||   |(_,_)'         \n" +
+        //        " |  | \\ `'   /|   `-'  /           \n" +
+        //        " |  |  \\    /  \\      /           \n" +
+        //        " ''-'   `'-'    `-..-'              ");
+        appEnvInfo(args);
+    }
+    /**
+     * @Description: 打印应用启动环境信息
+     * @Author: libiao
+     * @Date: 2021/10/17 19:40
+     * @param args:
+     * @return: void
+     **/
+    public static void appEnvInfo(String[] args){
+        SpringApplication app = new SpringApplication(RuoYiApplication.class);
+        DefaultProfileUtil.addDefaultProfile(app);
+        ApplicationContext appc =  app.run(args);
+        Environment env = appc.getEnvironment();
+        String ip = "localhost";
+        try {
+            ip = InetAddress.getLocalHost().getHostAddress();
+        } catch (UnknownHostException e) {
+            e.printStackTrace();
+        }
+        syslog.info("\n----------------------------------------------------------\n\t" +
+                        "Application '{}' is running! Access URLs:\n\t" +
+                        "Local: \t\thttp://{}:{}\n\t" +
+                        "----------------------------------------------------------",
+                env.getProperty("spring.profiles.active"),ip,
+                env.getProperty("server.port"));
+        syslog.info("程序启动完成!");
+        SpringContextUtils.setStaticApplicationContext(appc);
+    }
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/common/utils/ConfigConstant.java b/ruoyi-admin/src/main/java/com/ruoyi/common/utils/ConfigConstant.java
new file mode 100644
index 000000000..aa0e14f1e
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/common/utils/ConfigConstant.java
@@ -0,0 +1,18 @@
+package com.ruoyi.common.utils;
+
+/**
+ * 系统参数相关Key
+ */
+public class ConfigConstant {
+    /**
+     * 云存储配置KEY
+     */
+    public final static String CLOUD_STORAGE_CONFIG_KEY = "CLOUD_STORAGE_CONFIG_KEY";
+    
+    /**
+     * 运行环境
+     */
+    public static final String SPRING_PROFILE_DEVELOPMENT = "dev";
+	public static final String SPRING_PROFILE_TEST = "uat";
+    public static final String SPRING_PROFILE_PRODUCTION = "prd";
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/common/utils/DefaultProfileUtil.java b/ruoyi-admin/src/main/java/com/ruoyi/common/utils/DefaultProfileUtil.java
new file mode 100644
index 000000000..001e73f2c
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/common/utils/DefaultProfileUtil.java
@@ -0,0 +1,42 @@
+package com.ruoyi.common.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.core.env.Environment;
+
+public class DefaultProfileUtil {
+
+	private static final String SPRING_PROFILE_DEFAULT = "spring.profiles.default";
+	 
+    private DefaultProfileUtil(){
+    }
+ 
+    /**
+     * Set a default to use when no profile is configured.
+     *
+     * @param app the spring application
+     */
+    public static void addDefaultProfile(SpringApplication app) {
+        Map<String, Object> defProperties =  new HashMap<String, Object>();
+        /*
+        * The default profile to use when no other profiles are defined
+        * This cannot be set in the <code>application.yml</code> file.
+        * See https://github.com/spring-projects/spring-boot/issues/1219
+        */
+        defProperties.put(SPRING_PROFILE_DEFAULT, ConfigConstant.SPRING_PROFILE_DEVELOPMENT);
+        app.setDefaultProperties(defProperties);
+    }
+ 
+    /**
+     * Get the profiles that are applied else get default profiles.
+     */
+    public static String[] getActiveProfiles(Environment env) {
+        String[] profiles = env.getActiveProfiles();
+        if (profiles.length == 0) {
+            return env.getDefaultProfiles();
+        }
+        return profiles;
+    }
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/common/utils/SpringContextUtils.java b/ruoyi-admin/src/main/java/com/ruoyi/common/utils/SpringContextUtils.java
new file mode 100644
index 000000000..e8277c2af
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/common/utils/SpringContextUtils.java
@@ -0,0 +1,60 @@
+package com.ruoyi.common.utils;
+
+import org.apache.commons.lang3.Validate;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * Spring Context 工具类
+ * 
+ * @author libiao
+ * @date 2021-10-17
+ */
+@Component
+public class SpringContextUtils implements ApplicationContextAware {
+	public static ApplicationContext applicationContext; 
+
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext)
+			throws BeansException {
+		SpringContextUtils.applicationContext = applicationContext;
+	}
+	
+	public static void setStaticApplicationContext(ApplicationContext applicationContext)
+			throws BeansException {
+		SpringContextUtils.applicationContext = applicationContext;
+	}
+
+	public static Object getBean(String name) {
+		return applicationContext.getBean(name);
+	}
+
+	/**
+	 * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
+	 */
+	public static <T> T getBean(String name, Class<T> requiredType) {
+		return applicationContext.getBean(name, requiredType);
+	}
+
+	/**
+	 * 检查ApplicationContext不为空.
+	 */
+	private static void assertContextInjected() {
+		Validate.validState(applicationContext != null, "applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder.");
+	}
+	
+	public static boolean containsBean(String name) {
+		return applicationContext.containsBean(name);
+	}
+
+	public static boolean isSingleton(String name) {
+		return applicationContext.isSingleton(name);
+	}
+
+	public static Class<? extends Object> getType(String name) {
+		return applicationContext.getType(name);
+	}
+
+}
\ No newline at end of file
diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml
index 1f098e407..1ee6e891d 100644
--- a/ruoyi-admin/src/main/resources/application-druid.yml
+++ b/ruoyi-admin/src/main/resources/application-druid.yml
@@ -1,57 +1,57 @@
-# 数据源配置
-spring:
-    datasource:
-        type: com.alibaba.druid.pool.DruidDataSource
-        driverClassName: com.mysql.cj.jdbc.Driver
-        druid:
-            # 主库数据源
-            master:
-                url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                username: root
-                password: password
-            # 从库数据源
-            slave:
-                # 从数据源开关/默认关闭
-                enabled: false
-                url: 
-                username: 
-                password: 
-            # 初始连接数
-            initialSize: 5
-            # 最小连接池数量
-            minIdle: 10
-            # 最大连接池数量
-            maxActive: 20
-            # 配置获取连接等待超时的时间
-            maxWait: 60000
-            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
-            timeBetweenEvictionRunsMillis: 60000
-            # 配置一个连接在池中最小生存的时间,单位是毫秒
-            minEvictableIdleTimeMillis: 300000
-            # 配置一个连接在池中最大生存的时间,单位是毫秒
-            maxEvictableIdleTimeMillis: 900000
-            # 配置检测连接是否有效
-            validationQuery: SELECT 1 FROM DUAL
-            testWhileIdle: true
-            testOnBorrow: false
-            testOnReturn: false
-            webStatFilter: 
-                enabled: true
-            statViewServlet:
-                enabled: true
-                # 设置白名单,不填则允许所有访问
-                allow:
-                url-pattern: /druid/*
-                # 控制台管理用户名和密码
-                login-username: ruoyi
-                login-password: 123456
-            filter:
-                stat:
-                    enabled: true
-                    # 慢SQL记录
-                    log-slow-sql: true
-                    slow-sql-millis: 1000
-                    merge-sql: true
-                wall:
-                    config:
+# 数据源配置
+spring:
+    datasource:
+        type: com.alibaba.druid.pool.DruidDataSource
+        driverClassName: com.mysql.cj.jdbc.Driver
+        druid:
+            # 主库数据源
+            master:
+                url: jdbc:mysql://localhost:3306/shopee_erp?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                username: shopee_erp
+                password: shopee_erp123
+            # 从库数据源
+            slave:
+                # 从数据源开关/默认关闭
+                enabled: false
+                url: 
+                username: 
+                password: 
+            # 初始连接数
+            initialSize: 5
+            # 最小连接池数量
+            minIdle: 10
+            # 最大连接池数量
+            maxActive: 20
+            # 配置获取连接等待超时的时间
+            maxWait: 60000
+            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+            timeBetweenEvictionRunsMillis: 60000
+            # 配置一个连接在池中最小生存的时间,单位是毫秒
+            minEvictableIdleTimeMillis: 300000
+            # 配置一个连接在池中最大生存的时间,单位是毫秒
+            maxEvictableIdleTimeMillis: 900000
+            # 配置检测连接是否有效
+            validationQuery: SELECT 1 FROM DUAL
+            testWhileIdle: true
+            testOnBorrow: false
+            testOnReturn: false
+            webStatFilter: 
+                enabled: true
+            statViewServlet:
+                enabled: true
+                # 设置白名单,不填则允许所有访问
+                allow:
+                url-pattern: /druid/*
+                # 控制台管理用户名和密码
+                login-username: ruoyi
+                login-password: 123456
+            filter:
+                stat:
+                    enabled: true
+                    # 慢SQL记录
+                    log-slow-sql: true
+                    slow-sql-millis: 1000
+                    merge-sql: true
+                wall:
+                    config:
                         multi-statement-allow: true
\ No newline at end of file
diff --git a/ruoyi-admin/src/main/resources/logback.xml b/ruoyi-admin/src/main/resources/logback.xml
index d69a57207..a8c526ec2 100644
--- a/ruoyi-admin/src/main/resources/logback.xml
+++ b/ruoyi-admin/src/main/resources/logback.xml
@@ -1,93 +1,93 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration>
-    <!-- 日志存放路径 -->
-	<property name="log.path" value="/home/ruoyi/logs" />
-    <!-- 日志输出格式 -->
-	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
-
-	<!-- 控制台输出 -->
-	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
-		<encoder>
-			<pattern>${log.pattern}</pattern>
-		</encoder>
-	</appender>
-	
-	<!-- 系统日志输出 -->
-	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
-	    <file>${log.path}/sys-info.log</file>
-        <!-- 循环政策:基于时间创建日志文件 -->
-		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-            <!-- 日志文件名格式 -->
-			<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
-			<!-- 日志最大的历史 60天 -->
-			<maxHistory>60</maxHistory>
-		</rollingPolicy>
-		<encoder>
-			<pattern>${log.pattern}</pattern>
-		</encoder>
-		<filter class="ch.qos.logback.classic.filter.LevelFilter">
-            <!-- 过滤的级别 -->
-            <level>INFO</level>
-            <!-- 匹配时的操作:接收(记录) -->
-            <onMatch>ACCEPT</onMatch>
-            <!-- 不匹配时的操作:拒绝(不记录) -->
-            <onMismatch>DENY</onMismatch>
-        </filter>
-	</appender>
-	
-	<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
-	    <file>${log.path}/sys-error.log</file>
-        <!-- 循环政策:基于时间创建日志文件 -->
-        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-            <!-- 日志文件名格式 -->
-            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
-			<!-- 日志最大的历史 60天 -->
-			<maxHistory>60</maxHistory>
-        </rollingPolicy>
-        <encoder>
-            <pattern>${log.pattern}</pattern>
-        </encoder>
-        <filter class="ch.qos.logback.classic.filter.LevelFilter">
-            <!-- 过滤的级别 -->
-            <level>ERROR</level>
-			<!-- 匹配时的操作:接收(记录) -->
-            <onMatch>ACCEPT</onMatch>
-			<!-- 不匹配时的操作:拒绝(不记录) -->
-            <onMismatch>DENY</onMismatch>
-        </filter>
-    </appender>
-	
-	<!-- 用户访问日志输出  -->
-    <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
-		<file>${log.path}/sys-user.log</file>
-        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-            <!-- 按天回滚 daily -->
-            <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
-            <!-- 日志最大的历史 60天 -->
-            <maxHistory>60</maxHistory>
-        </rollingPolicy>
-        <encoder>
-            <pattern>${log.pattern}</pattern>
-        </encoder>
-    </appender>
-	
-	<!-- 系统模块日志级别控制  -->
-	<logger name="com.ruoyi" level="info" />
-	<!-- Spring日志级别控制  -->
-	<logger name="org.springframework" level="warn" />
-
-	<root level="info">
-		<appender-ref ref="console" />
-	</root>
-	
-	<!--系统操作日志-->
-    <root level="info">
-        <appender-ref ref="file_info" />
-        <appender-ref ref="file_error" />
-    </root>
-	
-	<!--系统用户操作日志-->
-    <logger name="sys-user" level="info">
-        <appender-ref ref="sys-user"/>
-    </logger>
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <!-- 日志存放路径 -->
+	<property name="log.path" value="./logs" />
+    <!-- 日志输出格式 -->
+	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
+
+	<!-- 控制台输出 -->
+	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+	</appender>
+	
+	<!-- 系统日志输出 -->
+	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/sys-info.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+			<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>INFO</level>
+            <!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+	</appender>
+	
+	<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/sys-error.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>ERROR</level>
+			<!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+			<!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+	
+	<!-- 用户访问日志输出  -->
+    <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>${log.path}/sys-user.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 按天回滚 daily -->
+            <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <!-- 日志最大的历史 60天 -->
+            <maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+    </appender>
+	
+	<!-- 系统模块日志级别控制  -->
+	<logger name="com.ruoyi" level="info" />
+	<!-- Spring日志级别控制  -->
+	<logger name="org.springframework" level="warn" />
+
+	<root level="info">
+		<appender-ref ref="console" />
+	</root>
+	
+	<!--系统操作日志-->
+    <root level="info">
+        <appender-ref ref="file_info" />
+        <appender-ref ref="file_error" />
+    </root>
+	
+	<!--系统用户操作日志-->
+    <logger name="sys-user" level="info">
+        <appender-ref ref="sys-user"/>
+    </logger>
 </configuration> 
\ No newline at end of file

From 79b19803979171d3b4d34f137ba99ff4fbeaeb3a Mon Sep 17 00:00:00 2001
From: daisylys <9819554+daisylys@user.noreply.gitee.com>
Date: Fri, 22 Oct 2021 06:57:25 +0000
Subject: [PATCH 2/5] update README.md.

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index f1ec311a8..a8dbc22ef 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-## 平台简介
+## 平台的简介
 
 若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
 

From b45dd7bf096118b170b1eb3da3a7cc69f32ea01d Mon Sep 17 00:00:00 2001
From: libiao <libiao.866@163.com>
Date: Sun, 24 Oct 2021 16:32:13 +0800
Subject: [PATCH 3/5] =?UTF-8?q?fix:mod:=E6=89=93=E5=8D=B0=E5=BA=94?=
 =?UTF-8?q?=E7=94=A8=E5=90=AF=E5=8A=A8=E7=9A=84=E6=9C=8D=E5=8A=A1=E5=99=A8?=
 =?UTF-8?q?=E4=BF=A1=E6=81=AF=E4=BC=98=E5=8C=96=EF=BC=8C=E7=9B=B4=E6=8E=A5?=
 =?UTF-8?q?=E6=89=93=E5=8D=B0=EF=BC=8C=E4=B8=8D=E5=86=8D=E8=AE=BE=E7=BD=AE?=
 =?UTF-8?q?=E9=BB=98=E8=AE=A4=E7=8E=AF=E5=A2=83?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../main/java/com/ruoyi/RuoYiApplication.java | 45 +++++---------
 .../ruoyi/common/utils/ConfigConstant.java    | 18 ------
 .../common/utils/DefaultProfileUtil.java      | 42 -------------
 .../common/utils/SpringContextUtils.java      | 60 -------------------
 4 files changed, 14 insertions(+), 151 deletions(-)
 delete mode 100644 ruoyi-admin/src/main/java/com/ruoyi/common/utils/ConfigConstant.java
 delete mode 100644 ruoyi-admin/src/main/java/com/ruoyi/common/utils/DefaultProfileUtil.java
 delete mode 100644 ruoyi-admin/src/main/java/com/ruoyi/common/utils/SpringContextUtils.java

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
index 99d6ae800..19f8fc1e5 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
@@ -1,9 +1,5 @@
 package com.ruoyi;
 
-import com.ruoyi.common.utils.DefaultProfileUtil;
-import com.ruoyi.common.utils.SpringContextUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.SpringApplication;
@@ -12,7 +8,6 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 import org.springframework.context.ApplicationContext;
 import org.springframework.core.env.Environment;
 
-import java.lang.invoke.MethodHandles;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 
@@ -28,31 +23,20 @@ public class RuoYiApplication
     private static final Logger syslog = LoggerFactory.getLogger(RuoYiApplication.class);
     public static void main(String[] args)
     {
-        // System.setProperty("spring.devtools.restart.enabled", "false");
-        //SpringApplication.run(RuoYiApplication.class, args);
-        //System.out.println("(♥◠‿◠)ノ゙  若依启动成功   ლ(´ڡ`ლ)゙  \n" +
-        //        " .-------.       ____     __        \n" +
-        //        " |  _ _   \\      \\   \\   /  /    \n" +
-        //        " | ( ' )  |       \\  _. /  '       \n" +
-        //        " |(_ o _) /        _( )_ .'         \n" +
-        //        " | (_,_).' __  ___(_ o _)'          \n" +
-        //        " |  |\\ \\  |  ||   |(_,_)'         \n" +
-        //        " |  | \\ `'   /|   `-'  /           \n" +
-        //        " |  |  \\    /  \\      /           \n" +
-        //        " ''-'   `'-'    `-..-'              ");
-        appEnvInfo(args);
-    }
-    /**
-     * @Description: 打印应用启动环境信息
-     * @Author: libiao
-     * @Date: 2021/10/17 19:40
-     * @param args:
-     * @return: void
-     **/
-    public static void appEnvInfo(String[] args){
-        SpringApplication app = new SpringApplication(RuoYiApplication.class);
-        DefaultProfileUtil.addDefaultProfile(app);
-        ApplicationContext appc =  app.run(args);
+        System.setProperty("spring.devtools.restart.enabled", "false");
+        ApplicationContext appc = SpringApplication.run(RuoYiApplication.class, args);
+        System.out.println("(♥◠‿◠)ノ゙  若依启动成功   ლ(´ڡ`ლ)゙  \n" +
+                " .-------.       ____     __        \n" +
+                " |  _ _   \\      \\   \\   /  /    \n" +
+                " | ( ' )  |       \\  _. /  '       \n" +
+                " |(_ o _) /        _( )_ .'         \n" +
+                " | (_,_).' __  ___(_ o _)'          \n" +
+                " |  |\\ \\  |  ||   |(_,_)'         \n" +
+                " |  | \\ `'   /|   `-'  /           \n" +
+                " |  |  \\    /  \\      /           \n" +
+                " ''-'   `'-'    `-..-'              ");
+
+        // 打印应用启动环境信息
         Environment env = appc.getEnvironment();
         String ip = "localhost";
         try {
@@ -67,6 +51,5 @@ public class RuoYiApplication
                 env.getProperty("spring.profiles.active"),ip,
                 env.getProperty("server.port"));
         syslog.info("程序启动完成!");
-        SpringContextUtils.setStaticApplicationContext(appc);
     }
 }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/common/utils/ConfigConstant.java b/ruoyi-admin/src/main/java/com/ruoyi/common/utils/ConfigConstant.java
deleted file mode 100644
index aa0e14f1e..000000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/common/utils/ConfigConstant.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.common.utils;
-
-/**
- * 系统参数相关Key
- */
-public class ConfigConstant {
-    /**
-     * 云存储配置KEY
-     */
-    public final static String CLOUD_STORAGE_CONFIG_KEY = "CLOUD_STORAGE_CONFIG_KEY";
-    
-    /**
-     * 运行环境
-     */
-    public static final String SPRING_PROFILE_DEVELOPMENT = "dev";
-	public static final String SPRING_PROFILE_TEST = "uat";
-    public static final String SPRING_PROFILE_PRODUCTION = "prd";
-}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/common/utils/DefaultProfileUtil.java b/ruoyi-admin/src/main/java/com/ruoyi/common/utils/DefaultProfileUtil.java
deleted file mode 100644
index 001e73f2c..000000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/common/utils/DefaultProfileUtil.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.ruoyi.common.utils;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.core.env.Environment;
-
-public class DefaultProfileUtil {
-
-	private static final String SPRING_PROFILE_DEFAULT = "spring.profiles.default";
-	 
-    private DefaultProfileUtil(){
-    }
- 
-    /**
-     * Set a default to use when no profile is configured.
-     *
-     * @param app the spring application
-     */
-    public static void addDefaultProfile(SpringApplication app) {
-        Map<String, Object> defProperties =  new HashMap<String, Object>();
-        /*
-        * The default profile to use when no other profiles are defined
-        * This cannot be set in the <code>application.yml</code> file.
-        * See https://github.com/spring-projects/spring-boot/issues/1219
-        */
-        defProperties.put(SPRING_PROFILE_DEFAULT, ConfigConstant.SPRING_PROFILE_DEVELOPMENT);
-        app.setDefaultProperties(defProperties);
-    }
- 
-    /**
-     * Get the profiles that are applied else get default profiles.
-     */
-    public static String[] getActiveProfiles(Environment env) {
-        String[] profiles = env.getActiveProfiles();
-        if (profiles.length == 0) {
-            return env.getDefaultProfiles();
-        }
-        return profiles;
-    }
-}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/common/utils/SpringContextUtils.java b/ruoyi-admin/src/main/java/com/ruoyi/common/utils/SpringContextUtils.java
deleted file mode 100644
index e8277c2af..000000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/common/utils/SpringContextUtils.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.ruoyi.common.utils;
-
-import org.apache.commons.lang3.Validate;
-import org.springframework.beans.BeansException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.stereotype.Component;
-
-/**
- * Spring Context 工具类
- * 
- * @author libiao
- * @date 2021-10-17
- */
-@Component
-public class SpringContextUtils implements ApplicationContextAware {
-	public static ApplicationContext applicationContext; 
-
-	@Override
-	public void setApplicationContext(ApplicationContext applicationContext)
-			throws BeansException {
-		SpringContextUtils.applicationContext = applicationContext;
-	}
-	
-	public static void setStaticApplicationContext(ApplicationContext applicationContext)
-			throws BeansException {
-		SpringContextUtils.applicationContext = applicationContext;
-	}
-
-	public static Object getBean(String name) {
-		return applicationContext.getBean(name);
-	}
-
-	/**
-	 * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
-	 */
-	public static <T> T getBean(String name, Class<T> requiredType) {
-		return applicationContext.getBean(name, requiredType);
-	}
-
-	/**
-	 * 检查ApplicationContext不为空.
-	 */
-	private static void assertContextInjected() {
-		Validate.validState(applicationContext != null, "applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder.");
-	}
-	
-	public static boolean containsBean(String name) {
-		return applicationContext.containsBean(name);
-	}
-
-	public static boolean isSingleton(String name) {
-		return applicationContext.isSingleton(name);
-	}
-
-	public static Class<? extends Object> getType(String name) {
-		return applicationContext.getType(name);
-	}
-
-}
\ No newline at end of file

From e168dc674eafa836368d5c082e9c99969d984891 Mon Sep 17 00:00:00 2001
From: libiao <libiao.866@163.com>
Date: Wed, 3 Nov 2021 22:04:43 +0800
Subject: [PATCH 4/5] =?UTF-8?q?fix:mod:=E4=BF=AE=E6=AD=A3sign=E7=AD=BE?=
 =?UTF-8?q?=E5=90=8D=E6=97=A0=E6=B3=95=E9=87=8D=E5=A4=8D=E7=94=9F=E6=88=90?=
 =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=8Csign=E8=AE=A1=E7=AE=97=E6=97=B6?=
 =?UTF-8?q?=E7=94=A8=E5=AD=97=E7=AC=A6=E4=B8=B2=E6=89=BF=E6=8E=A5=E7=BB=93?=
 =?UTF-8?q?=E6=9E=9C=E8=80=8C=E4=B8=8D=E6=98=AFBigInteger=E3=80=82?=
 =?UTF-8?q?=E6=96=B0=E5=A2=9EAPI=E6=8E=88=E6=9D=83token=E8=8E=B7=E5=8F=96?=
 =?UTF-8?q?=E6=96=B9=E6=B3=95=E9=9B=8F=E5=BD=A2=EF=BC=8C=E5=BE=85=E8=A1=A5?=
 =?UTF-8?q?=E5=85=85http=E8=AF=B7=E6=B1=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../src/main/resources/application-shopee.yml | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 ruoyi-admin/src/main/resources/application-shopee.yml

diff --git a/ruoyi-admin/src/main/resources/application-shopee.yml b/ruoyi-admin/src/main/resources/application-shopee.yml
new file mode 100644
index 000000000..2eea6252b
--- /dev/null
+++ b/ruoyi-admin/src/main/resources/application-shopee.yml
@@ -0,0 +1,20 @@
+shopee:
+  partnerID: 845774
+  secrret: ea6e399abcBb69eacbeBfe38bc89a9ef35Za8Ze48a92535211c2Ъ92e18Ba52d
+  #回跳到系统
+  redirectURL: http://www.edterp.com/shop/shop
+  #shopee 认证
+  authpartner_url: https://partner.shopeemobile.com/api/v1/shop/auth partner
+  #
+  cancel_auth_partner_url:  https://partner.shopeemobile.com/api/v1/shop/cancel_auth_partner
+  #shopee 消息推送到系统
+  msgPushUrl: http://www.edterp.com/dev-dpi/orders/shop/verfiyPushMsg
+  #shopee
+  shopInfoApiUrl: https://partner.shopeemobile.com/api/v1/shop/get
+  ordersApiUrl: https://partner.shopeemobile.com/api/v1/orders/basics
+  #
+  orderDetailApiUrl:https://partner.shopeemobile.com/api/v1/orders/detail
+  #
+  orderDetailUariationspiUrl1: https://partner.shopeemobile.com/api/v1/item/tier_var/get
+  socketHost: 172.19.92.42
+  socketPort: 10000
\ No newline at end of file

From 65a1e7a52f35bfebd034e63532cd00b85a100a7c Mon Sep 17 00:00:00 2001
From: libiao <libiao.866@163.com>
Date: Wed, 5 Jan 2022 10:24:15 +0800
Subject: [PATCH 5/5] =?UTF-8?q?fix:mod:=E4=BF=AE=E6=AD=A3sign=E7=AD=BE?=
 =?UTF-8?q?=E5=90=8D=E6=97=A0=E6=B3=95=E9=87=8D=E5=A4=8D=E7=94=9F=E6=88=90?=
 =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=8Csign=E8=AE=A1=E7=AE=97=E6=97=B6?=
 =?UTF-8?q?=E7=94=A8=E5=AD=97=E7=AC=A6=E4=B8=B2=E6=89=BF=E6=8E=A5=E7=BB=93?=
 =?UTF-8?q?=E6=9E=9C=E8=80=8C=E4=B8=8D=E6=98=AFBigInteger=E3=80=82?=
 =?UTF-8?q?=E6=96=B0=E5=A2=9EAPI=E6=8E=88=E6=9D=83token=E8=8E=B7=E5=8F=96?=
 =?UTF-8?q?=E6=96=B9=E6=B3=95=E9=9B=8F=E5=BD=A2=EF=BC=8C=E5=BE=85=E8=A1=A5?=
 =?UTF-8?q?=E5=85=85http=E8=AF=B7=E6=B1=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../java/com/ruoyi/common/utils/ShopAuth.java | 133 ++++++++++++++++++
 .../java/com/ruoyi/common/utils/Test.java     |  85 +++++++++++
 2 files changed, 218 insertions(+)
 create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/common/utils/ShopAuth.java
 create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/common/utils/Test.java

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/common/utils/ShopAuth.java b/ruoyi-admin/src/main/java/com/ruoyi/common/utils/ShopAuth.java
new file mode 100644
index 000000000..6a5c83f95
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/common/utils/ShopAuth.java
@@ -0,0 +1,133 @@
+package com.ruoyi.common.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ruoyi.common.core.text.CharsetKit;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.math.BigInteger;
+
+/**
+ * @author libiao
+ * @version 1.0
+ * @Description: 虾皮2.0授权工具类
+ * @date 2021/10/24 21:12
+ **/
+public class ShopAuth {
+    public static final String AUTH_SIGN_METHOD = "HmacSHA256";
+
+    public static void main(String[] args) {
+        // 虾皮测试环境
+        String host = "https://partner.test-stable.shopeemobile.com";
+        String path = "/api/v2/shop/auth_partner";
+        //TODO 回跳到花生壳内网地址(转发到8080端口),需要补充URI
+        String redirect_url = "http://4v4c570155.zicp.vip:47393/swagger-ui/index.html";
+        // edterp 的 测试 Partner
+        long partner_id = 1002192L;
+        String partner_key = "8e8618dbb99923b4b298517d263b0b45df02a2ef8341d512539bdbacc76b0bb1";
+        String authUrl = calculateShopAuthUrl(host, path, redirect_url, partner_id, partner_key);
+        System.out.println(authUrl);
+
+        getTokenShopLevel("code123",partner_id,partner_key,"");
+    }
+
+    /**
+     * @Description: 虾皮店铺授权链接生成
+     * 1.拼接基础字符串,api path + partner_id + api path + timestamp
+     * 2.基于基础字符串计算签名
+     * @Author: libiao
+     * @Date: 2021/10/24 21:56
+     * @param host: 虾皮地址
+     * @param path: 虾皮授权接口路径(授权:"/api/v2/shop/auth_partner",取消授权:"/api/v2/shop/cancel_auth_partner")
+     * @param redirect_url: 授权成功后跳转地址,ERP的地址
+     * @param partner_id: 开发者账号id
+     * @param partner_key: 开发者账号key
+     * @return: java.lang.String 授权链接
+     **/
+    public static String calculateShopAuthUrl(String host, String path, String redirect_url, long partner_id, String partner_key) {
+        long timestamp = System.currentTimeMillis() / 1000L;
+        String tmp_base_string = String.format("%s%s%s", partner_id, path, timestamp);
+        byte[] partner_key_bytes;
+        byte[] base_string_bytes;
+        // 计算加密签名
+        BigInteger sign = null;
+        String sign_str = "";
+        try {
+            partner_key_bytes = partner_key.getBytes(CharsetKit.CHARSET_UTF_8);
+            base_string_bytes = tmp_base_string.getBytes(CharsetKit.CHARSET_UTF_8);
+            Mac mac = Mac.getInstance("HmacSHA256"); //"HmacSHA256"
+            SecretKeySpec secretKeySpec = new SecretKeySpec(partner_key_bytes, "HmacSHA256");
+            mac.init(secretKeySpec);
+            //sign = new BigInteger(mac.doFinal(base_string_bytes));
+            byte[] sign_bytes = mac.doFinal(base_string_bytes);
+            sign_str = byteArrayToHexString(sign_bytes);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        // 拼接授权url
+        //String url = host + path + String.format("?partner_id=%s&timestamp=%s&sign=%032x&redirect=%s", partner_id, timestamp, sign, redirect_url);
+        String url = host + path + String.format("?partner_id=%s&timestamp=%s&sign=%s&redirect=%s", partner_id, timestamp, sign_str, redirect_url);
+        return url;
+    }
+
+    /**
+     * @Description: 获取店铺级别接口鉴权access_token refresh_token
+     * @Author: libiao
+     * @Date: 2021/11/3 21:16
+     * @param code: 店铺授权成功后返回的
+     * @param partner_id: 开发者账号id
+     * @param partner_key: 开发者账号key
+     * @param shop_id: 店铺id(店铺授权成功后也会返回)
+     * @return: void
+     **/
+    public static void getTokenShopLevel(String code, long partner_id, String partner_key, String shop_id){
+        long timestamp = System.currentTimeMillis()/1000L;
+        JSONObject body = new JSONObject();
+        body.put("code",code);
+        body.put("shop_id",shop_id);
+        body.put("partner_id", partner_id);
+
+        //String host = "https://partner.shopeemobile.com/api/v2/auth/token/get";
+        String host = "https://partner.test-stable.shopeemobile.com";
+        String path = "/api/v2/auth/token/get";
+        String tmp_base_string = String.format("%s%s%s",partner_id,path,timestamp);
+
+        byte[] partner_key_bytes;
+        byte[] base_string_bytes;
+
+        String sign = null;
+        try {
+            partner_key_bytes = partner_key.getBytes("UTF-8");
+            base_string_bytes = tmp_base_string.getBytes("UTF-8");
+            Mac mac = Mac.getInstance(AUTH_SIGN_METHOD); //"HmacSHA256"
+            SecretKeySpec secretKeySpec = new SecretKeySpec(partner_key_bytes,AUTH_SIGN_METHOD);
+            mac.init(secretKeySpec);
+            byte[] sign_bytes = mac.doFinal(base_string_bytes);
+            sign = byteArrayToHexString(sign_bytes);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        // 拼接授权url
+        String url = host + path + String.format("?partner_id=%s&timestamp=%s&sign=%s",partner_id,timestamp,sign);
+        // TODO http请求获取access_token和refresh_token
+        System.out.println(url);
+    }
+
+    /**
+     * 将加密后的字节数组转换成字符串
+     *
+     * @param b 字节数组
+     * @return 字符串
+     */
+    public static String byteArrayToHexString(byte[] b) {
+        StringBuilder hs = new StringBuilder();
+        String stmp;
+        for (int n = 0; b!=null && n < b.length; n++) {
+            stmp = Integer.toHexString(b[n] & 0XFF);
+            if (stmp.length() == 1)
+                hs.append('0');
+            hs.append(stmp);
+        }
+        return hs.toString().toLowerCase();
+    }
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/common/utils/Test.java b/ruoyi-admin/src/main/java/com/ruoyi/common/utils/Test.java
new file mode 100644
index 000000000..8c10caea4
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/common/utils/Test.java
@@ -0,0 +1,85 @@
+package com.ruoyi.common.utils;
+
+import com.ruoyi.common.core.text.CharsetKit;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.math.BigInteger;
+
+/**
+ * @author libiao
+ * @version 1.0
+ * @Description: TODO
+ * @date 2021/11/3 21:48
+ **/
+public class Test {
+    public static void main(String[] args) {
+        // 虾皮测试环境
+        String host = "https://partner.test-stable.shopeemobile.com";
+        String path = "/api/v2/shop/auth_partner";
+        //TODO 回跳到花生壳内网地址(转发到8080端口),需要补充URI
+        String redirect_url = "http://4v4c570155.zicp.vip:47393";
+        // edterp 的 测试 Partner
+        long partner_id = 1002192;
+        String partner_key = "8e8618dbb99923b4b298517d263b0b45df02a2ef8341d512539bdbacc76b0bb1";
+        String authUrl = calculateShopAuthUrl(host, path, redirect_url, partner_id, partner_key);
+        System.out.println(authUrl);
+    }
+
+    /**
+     * @Description: 虾皮店铺授权链接生成
+     * 1.拼接基础字符串,api path + partner_id + api path + timestamp
+     * 2.基于基础字符串计算签名
+     * @Author: libiao
+     * @Date: 2021/10/24 21:56
+     * @param host: 虾皮地址
+     * @param path: 虾皮授权接口路径(授权:"/api/v2/shop/auth_partner",取消授权:"/api/v2/shop/cancel_auth_partner")
+     * @param redirect_url: 授权成功后跳转地址
+     * @param partner_id: 开发者账号id
+     * @param partner_key: 开发者账号key
+     * @return: java.lang.String 授权链接
+     **/
+    public static String calculateShopAuthUrl(String host, String path, String redirect_url, long partner_id, String partner_key) {
+        long timestamp = System.currentTimeMillis() / 1000L;
+        String tmp_base_string = String.format("%s%s%s", partner_id, path, timestamp);
+        byte[] partner_key_bytes;
+        byte[] base_string_bytes;
+        // 计算加密签名
+        BigInteger sign = null;
+        String sign_str = "";
+        try {
+            partner_key_bytes = partner_key.getBytes(CharsetKit.CHARSET_UTF_8);
+            base_string_bytes = tmp_base_string.getBytes(CharsetKit.CHARSET_UTF_8);
+            Mac mac = Mac.getInstance("HmacSHA256"); //"HmacSHA256"
+            SecretKeySpec secretKeySpec = new SecretKeySpec(partner_key_bytes, "HmacSHA256");
+            mac.init(secretKeySpec);
+            //sign = new BigInteger(mac.doFinal(base_string_bytes));
+            byte[] sign_bytes = mac.doFinal(base_string_bytes);
+            sign_str = byteArrayToHexString(sign_bytes);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        // 拼接授权url
+        //String url = host + path + String.format("?partner_id=%s&timestamp=%s&sign=%032x&redirect=%s", partner_id, timestamp, sign, redirect_url);
+        String url = host + path + String.format("?partner_id=%s&timestamp=%s&sign=%s&redirect=%s", partner_id, timestamp, sign_str, redirect_url);
+        return url;
+    }
+
+    /**
+     * 将加密后的字节数组转换成字符串
+     *
+     * @param b 字节数组
+     * @return 字符串
+     */
+    public static String byteArrayToHexString(byte[] b) {
+        StringBuilder hs = new StringBuilder();
+        String stmp;
+        for (int n = 0; b!=null && n < b.length; n++) {
+            stmp = Integer.toHexString(b[n] & 0XFF);
+            if (stmp.length() == 1)
+                hs.append('0');
+            hs.append(stmp);
+        }
+        return hs.toString().toLowerCase();
+    }
+}