Browse Source

Merge remote-tracking branch 'upstream/master'

csk 1 year ago
parent
commit
9d8c543a96

+ 2 - 1
.gitignore

@@ -20,4 +20,5 @@ miniprogram_npm/
 # gradle
 .gradle/
 build/
-out/
+out/
+logs/

+ 6 - 0
sql/2023-6-6/福庆Eid配置.sql

@@ -0,0 +1,6 @@
+INSERT INTO `wx_base`.`eid_merch` (`merch_sn`, `secret_id`, `secret_key`, `merch_id`, `token_expired`, `tstm`) VALUES ('mhbs174902211850035200', 'AKIDUox1swlLfjbFeleNtAdrpXyEEySlqgGc', 'ED1c0AAwVrzue9Tav4ye8NO9f095mHXX', '0NSJ2305041629298230', 4800, '2023-05-06 10:14:18');
+
+INSERT INTO `wx_base`.`merch_app` (`merch_sn`, `app_code`, `app_name`, `tstm`) VALUES ('mhbs174902211850035200', 'kmall-emato', 'Kmall福庆', '2023-05-06 10:10:39');
+
+
+INSERT INTO `wx_base`.`merch_info` (`merch_sn`, `merch_name`, `tstm`) VALUES ('mhbs174902211850035200', '福庆新零售', '2023-05-06 10:09:14');

+ 22 - 1
src/main/java/com/ematou/wxbase/controller/TokenRecordController.java

@@ -4,6 +4,8 @@ import com.ematou.wxbase.common.web.R;
 import com.ematou.wxbase.service.TokenRecordService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 /**
@@ -20,7 +22,16 @@ public class TokenRecordController {
     @GetMapping("/wxbase/token")
     public R<?> get() {
         try {
-            return new R<>().success(tokenRecordService.getLatestToken());
+            return new R<>().success(tokenRecordService.getLatestToken(null));
+        } catch (Exception e) {
+            return new R<>().error("获取AccessToken失败!errorMessage: " + e.getMessage());
+        }
+    }
+
+    @GetMapping("/wxbase/token/{system}")
+    public R<?> get(@PathVariable String system) {
+        try {
+            return new R<>().success(tokenRecordService.getLatestToken(system));
         } catch (Exception e) {
             return new R<>().error("获取AccessToken失败!errorMessage: " + e.getMessage());
         }
@@ -36,5 +47,15 @@ public class TokenRecordController {
         }
 
     }
+    @GetMapping("/wxbase/generate/token/{system}")
+    public R<?> generateToken(@PathVariable String system){
+
+        try {
+            return new R<>().success(tokenRecordService.generateToken(system));
+        } catch (Exception e) {
+            return new R<>().error("生成AccessToken失败!errorMessage:" + e.getMessage());
+        }
+
+    }
 
 }

+ 10 - 0
src/main/java/com/ematou/wxbase/entity/TokenRecord.java

@@ -31,8 +31,18 @@ public class TokenRecord {
 
     private String modTime;
 
+    private String appId;
+
     private Timestamp tstm;
 
+    public String getAppId() {
+        return appId;
+    }
+
+    public void setAppId(String appId) {
+        this.appId = appId;
+    }
+
     public Integer getId() {
         return id;
     }

+ 1 - 1
src/main/java/com/ematou/wxbase/mapper/TokenRecordMapper.java

@@ -19,7 +19,7 @@ public interface TokenRecordMapper {
 
     public int insertRecord(@Param("record") TokenRecord record);
 
-    public TokenRecord queryLatestAndValidRecord();
+    public TokenRecord queryLatestAndValidRecord(String appId);
 
     public int queryLatestAndValidRecordCount();
 

+ 2 - 1
src/main/java/com/ematou/wxbase/scheduler/RefreshAccessTokenScheduler.java

@@ -37,7 +37,8 @@ public class RefreshAccessTokenScheduler {
     public void refreshAccessToken() {
         try {
             logger.info("定时器开始刷新Token...");
-            tokenRecordService.generateToken();
+            tokenRecordService.generateToken("emato");
+            tokenRecordService.generateToken("qhemato");
         } catch (Exception e) {
             logger.error("定时刷新Token失败!errorMessage: " + e.getMessage());
         }

+ 97 - 7
src/main/java/com/ematou/wxbase/service/TokenRecordService.java

@@ -5,6 +5,7 @@ import com.ematou.wxbase.config.WxGeneralConfig;
 import com.ematou.wxbase.entity.OperationRecord;
 import com.ematou.wxbase.entity.TokenRecord;
 import com.ematou.wxbase.mapper.TokenRecordMapper;
+import io.netty.util.internal.StringUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -13,10 +14,13 @@ import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
 import org.springframework.web.client.RestTemplate;
 
+import javax.annotation.PostConstruct;
 import java.text.ParseException;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * @author lhm
@@ -40,6 +44,31 @@ public class TokenRecordService {
     @Autowired
     WxGeneralConfig wxGeneralConfig;
 
+    private static Map<String,WxGeneralConfig> configMap = new ConcurrentHashMap<>();
+    @PostConstruct
+    private static void init (){
+        WxGeneralConfig eztConfig = new WxGeneralConfig();
+        eztConfig.setAppId("wxf9360d70bc1406ee");
+        eztConfig.setAppSecret("78413a82d0332ecbf7fdf475d0a8b08e");
+        eztConfig.setUrl("https://api.weixin.qq.com/cgi-bin/token?grant_type=%s&appid=%s&secret=%s");
+        eztConfig.setGrantType("client_credential");
+        eztConfig.setTicketUrl("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi");
+
+        configMap.put("emato",eztConfig);
+
+
+        WxGeneralConfig ematoConfig = new WxGeneralConfig();
+        ematoConfig.setAppId("wx8735db2da152ce19");
+        ematoConfig.setAppSecret("016edeba9d3f0508c95476ceec5f65e4");
+        ematoConfig.setUrl("https://api.weixin.qq.com/cgi-bin/token?grant_type=%s&appid=%s&secret=%s");
+        ematoConfig.setGrantType("client_credential");
+        ematoConfig.setTicketUrl("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi");
+
+        configMap.put("qhemato",ematoConfig);
+
+
+    }
+
     /**
      * 查询所有未失效的Token记录
      * @return 所有未失效的Token记录
@@ -87,22 +116,82 @@ public class TokenRecordService {
      *
      * @return token
      */
-    public TokenRecord getLatestToken() throws ParseException {
-        // 如果数据库中没有或者是该token已过期,则需要重新生成token
-        TokenRecord tokenRecord = tokenRecordMapper.queryLatestAndValidRecord();
+    public TokenRecord getLatestToken(String system) throws ParseException {
+        TokenRecord tokenRecord;
+        if(StringUtil.isNullOrEmpty(system)){
+            // 如果数据库中没有或者是该token已过期,则需要重新生成token
+            tokenRecord = tokenRecordMapper.queryLatestAndValidRecord(wxGeneralConfig.getAppId());
+        }else{
+            WxGeneralConfig wxGeneralConfigTmp = configMap.get(system);
+            tokenRecord = tokenRecordMapper.queryLatestAndValidRecord(wxGeneralConfigTmp.getAppId());
+        }
+
+
         if (null == tokenRecord) {
             // 需要生成Token
-            return generateToken();
+            if(StringUtil.isNullOrEmpty(system)){
+                return generateToken();
+            }else{
+                return generateToken(system);
+            }
+
         }
         String expiresTime = tokenRecord.getExpiresTime();
         Date tokenExpiresTime = DateUtils.parseString(expiresTime);
         Date now = new Date();
         if (now.getTime() > tokenExpiresTime.getTime()) {
-            return generateToken();
+            if(StringUtil.isNullOrEmpty(system)){
+                return generateToken();
+            }else{
+                return generateToken(system);
+            }
         }
         return tokenRecord;
     }
 
+
+    /**
+     * 主动请求微信生成accessToken
+     *
+     * @return token记录
+     */
+    public TokenRecord generateToken(String system) throws RuntimeException {
+        WxGeneralConfig wxGeneralConfig = configMap.get(system);
+        String url = "";
+        if(Objects.nonNull(wxGeneralConfig)){
+            url = String.format(wxGeneralConfig.getUrl(), wxGeneralConfig.getGrantType(), wxGeneralConfig.getAppId(), wxGeneralConfig.getAppSecret());
+        }
+        Map response = null;
+        try {
+            response = restTemplate.getForEntity(url, Map.class).getBody();
+        } catch (Exception e) {
+            logger.error("请求微信平台失败!errorMessage:" + e.getMessage());
+            throw new RuntimeException("请求微信平台失败!");
+        }
+        if (null == response) {
+            logger.error("请求微信平台失败!errorMessage:response is null");
+            throw new RuntimeException("请求微信平台失败!");
+        }
+
+        OperationRecord operationRecord = wrapOperationRecord("目前暂无");
+        TokenRecord tokenRecord = wrapTokenRecord(operationRecord, response,wxGeneralConfig.getAppId());
+
+        if (null == tokenRecord) {
+            Object errcode = response.get("errcode");
+            Object errmsg = response.get("errmsg");
+            logger.error("请求微信平台生成AccessToken失败!errorCode:" + errcode + ",errorMessage:" + errmsg);
+            throw new RuntimeException("请求微信平台生成AccessToken失败!");
+        }
+
+        // 保存操作记录
+        operationRecordService.insertRecord(operationRecord);
+        int latestId = operationRecordService.queryLatestId();
+        // 保存TokenRecord
+        tokenRecord.setOpId(latestId);
+        insertRecord(tokenRecord);
+        return tokenRecord;
+    }
+
     /**
      * 主动请求微信生成accessToken
      *
@@ -125,7 +214,7 @@ public class TokenRecordService {
         }
 
         OperationRecord operationRecord = wrapOperationRecord("目前暂无");
-        TokenRecord tokenRecord = wrapTokenRecord(operationRecord, response);
+        TokenRecord tokenRecord = wrapTokenRecord(operationRecord, response,wxGeneralConfig.getAppId());
 
         if (null == tokenRecord) {
             Object errcode = response.get("errcode");
@@ -179,7 +268,7 @@ public class TokenRecordService {
      * @param response        请求微信平台响应
      * @return Token记录
      */
-    private TokenRecord wrapTokenRecord(OperationRecord operationRecord, Map response) {
+    private TokenRecord wrapTokenRecord(OperationRecord operationRecord, Map response,String appid) {
         TokenRecord tokenRecord = new TokenRecord();
         String accessToken = (String) response.get("access_token");
         Integer expiresIn = (Integer) response.get("expires_in");
@@ -196,6 +285,7 @@ public class TokenRecordService {
             tokenRecord.setExpiresTime(DateUtils.formatDate(new Date(expiresTime)));
             tokenRecord.setOpId(operationRecord.getOpId());
             tokenRecord.setIsValid(0);
+            tokenRecord.setAppId(appid);
             return tokenRecord;
         }
         return null;

+ 1 - 1
src/main/java/com/ematou/wxbase/service/impl/TicketRecordServiceImpl.java

@@ -96,7 +96,7 @@ public class TicketRecordServiceImpl implements TicketRecordService {
         // 获取微信 token
         TokenRecord latestToken = null;
         try {
-            latestToken = tokenRecordService.getLatestToken();
+            latestToken = tokenRecordService.getLatestToken(null);
         } catch (ParseException e) {
             logger.error("获取微信 token 失败", e);
             throw new RuntimeException("获取微信 token 失败!");

+ 6 - 6
src/main/resources/application-test.yml

@@ -5,12 +5,12 @@ spring:
   # 数据源配置
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-#    username: tuser
-#    password: Qq!123
-#    url: jdbc:mysql://47.112.115.196:3306/wx_base?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
-    username: wx_base
-    password: goZ7ooGmxV
-    url: jdbc:mysql://out-rm-wz92efl25x02n44xego.mysql.rds.aliyuncs.com:3306/wx_base?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
+    username: tuser
+    password: Qq!123
+    url: jdbc:mysql://47.112.115.196:3306/wx_base?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
+#    username: wx_base
+#    password: goZ7ooGmxV
+#    url: jdbc:mysql://out-rm-wz92efl25x02n44xego.mysql.rds.aliyuncs.com:3306/wx_base?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
   # redis 配置
   redis:
     database: 1

+ 168 - 38
src/main/resources/logback.xml

@@ -1,50 +1,180 @@
-<configuration>
-    <!-- %m输出的信息, %p日志级别, %t线程名, %d日期, %c类的全名, %i索引 -->
-    <!-- appender是configuration的子节点,是负责写日志的组件 -->
-    <!-- ConsoleAppender把日志输出到控制台 -->
-    <!--    <property name="CONSOLE_LOG_PATTERN" -->
-    <!--               value="%date{yyyy-MM-dd HH:mm:ss} | %highlight(%-5level) | %boldYellow(%thread) | %boldGreen(%logger) | %msg%n"/> -->
-    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+<?xml version="1.0" encoding="UTF-8"?>
+
+<configuration scan="false" scanPeriod="60 seconds" debug="false">
+
+    <property name="LOG_HOME" value="/data/project/logs/wxbase"/>
+    <!-- 定义日志的根目录 -->
+    <property name="TRACE_DIR" value="trace" />
+    <property name="DEBUG_DIR" value="debug" />
+    <property name="INFO_DIR" value="info" />
+    <property name="WARN_DIR" value="warn" />
+    <property name="ERROR_DIR" value="error" />
+    <!-- 定义日志文件名称 -->
+    <property name="TRACE_FILE_NAME" value="wxbase-trace"></property>
+    <property name="DEBUG_FILE_NAME" value="wxbase-debug"></property>
+    <property name="INFO_FILE_NAME" value="wxbase-info"></property>
+    <property name="WARN_FILE_NAME" value="wxbase-warn"></property>
+    <property name="ERROR_FILE_NAME" value="wxbase-error"></property>
+
+    <!-- 定义日志级别颜色 -->
+    <!-- 控制台显示 -->
+    <property name="STD_CONSOLE_LOG_PATTERN"
+              value="%d{yyyy-MM-dd HH:mm:ss.SSS}[%yellow(%thread)]-[%highlight(%-5level)][%green(%logger{70}):%cyan(%line)] - %msg%n"/>
+
+    <!-- 日志文件打印 -->
+    <property name="CONSOLE_LOG_PATTERN"
+              value="%d{yyyy-MM-dd HH:mm:ss.SSS}[%thread]-[%-5level][%logger{70}:%line] - %msg%n"/>
+
+    <!-- ConsoleAppender 控制台输出 appender -->
+    <appender name="stdoutAppender" class="ch.qos.logback.core.ConsoleAppender">
+        <!--
+        日志输出格式:%d表示日期时间,%thread表示线程名,%-5level:级别从左显示5个字符宽度
+        %logger{70} 表示logger名字最长50个字符,否则按照句点分割。 %msg:日志消息,%n是换行符
+        -->
         <encoder>
-            <!--<pattern>${CONSOLE_LOG_PATTERN}</pattern> -->
-            <pattern>%date{yyyy-MM-dd HH:mm:ss} %highlight(%-5level) (%file:%line\)- %m%n</pattern>
-            <!-- 控制台也要使用utf-8,不要使用gbk -->
+            <pattern>${STD_CONSOLE_LOG_PATTERN}</pattern>
             <charset>UTF-8</charset>
         </encoder>
     </appender>
 
-    <!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
-    <!-- 1.先按日期存日志,日期变了,将前一天的日志文件名重命名为xxx%日期%索引,新的日志仍然是sys.log -->
-    <!-- 2.如果日期没有变化,但是当前日志文件的大小超过1kb时,对当前日志进行分割 重名名 -->
-    <appender name="syslog" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <!--<File>${catalina.base}/mylog/sys.log</File>-->
-        <File>logs/wxbase.log</File>
-        <!-- rollingPolicy:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。 -->
-        <!-- TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动 -->
+
+    <!-- TRACE 日志 appender  -->
+    <appender name="traceAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 指定日志文件的名称 -->
+        <file>${LOG_HOME}/${TRACE_DIR}/${TRACE_FILE_NAME}.log</file>
         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-            <!-- 活动文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
-            <!--<fileNamePattern>${catalina.base}/mylog/sys.%d.%i.log</fileNamePattern>-->
-            <fileNamePattern>${catalina.base}/%d/sys.%d.%i.log</fileNamePattern>
-            <!-- 每产生一个日志文件,该日志文件的保存期限为30天 -->
-            <maxHistory>30</maxHistory>
-            <timeBasedFileNamingAndTriggeringPolicy  class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
-                <!-- maxFileSize:这是活动文件的大小,默认值是10MB,本篇设置为1KB,只是为了演示 -->
-                <maxFileSize>1KB</maxFileSize>
+            <fileNamePattern>${LOG_HOME}/${TRACE_DIR}/${TRACE_FILE_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
+            <MaxHistory>365</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
             </timeBasedFileNamingAndTriggeringPolicy>
         </rollingPolicy>
         <encoder>
-            <!-- pattern节点,用来设置日志的输入格式 -->
-            <pattern>
-                %d %p (%file:%line\)- %m%n
-            </pattern>
-            <!-- 记录日志的编码 -->
-            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
         </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>TRACE</level>
+            <!--<onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>-->
+        </filter>
     </appender>
-    <!-- 控制台日志输出级别 -->
-    <root level="info">
-        <appender-ref ref="STDOUT" />
-        <appender-ref ref="syslog" />
-    </root>
 
-</configuration>
+
+    <!-- DEBUG 日志 appender  -->
+    <appender name="debugAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 指定日志文件的名称 -->
+        <file>${LOG_HOME}/${DEBUG_DIR}/${DEBUG_FILE_NAME}.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${DEBUG_DIR}/${DEBUG_FILE_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
+            <MaxHistory>365</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>DEBUG</level>
+            <!--<onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>-->
+        </filter>
+    </appender>
+
+
+    <!-- phrase 日志 appender  -->
+    <appender name="infoAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 指定日志文件的名称 -->
+        <file>${LOG_HOME}/${INFO_DIR}/${INFO_FILE_NAME}.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${INFO_DIR}/${INFO_FILE_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
+            <MaxHistory>365</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>INFO</level>
+            <!--<onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>-->
+        </filter>
+    </appender>
+
+
+    <!-- WARN 日志 appender  -->
+    <appender name="warnAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 指定日志文件的名称 -->
+        <file>${LOG_HOME}/${WARN_DIR}/${WARN_FILE_NAME}.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${WARN_DIR}/${WARN_FILE_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
+            <MaxHistory>365</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>WARN</level>
+            <!--<onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>-->
+        </filter>
+    </appender>
+
+
+    <!-- ERROR 日志 appender  -->
+    <appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 指定日志文件的名称 -->
+        <file>${LOG_HOME}/${ERROR_DIR}/${ERROR_FILE_NAME}.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${ERROR_DIR}/${ERROR_FILE_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
+            <MaxHistory>365</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
+            <level>ERROR</level>
+        </filter>
+    </appender>
+
+    <logger name="org.apache.shiro" level="DEBUG" additivity="false" />
+    <logger name="com.zaxxer.hikari" level="ERROR" additivity="false" />
+    <logger name="org.apache" level="ERROR" />
+    <logger name="org.springframework.context.annotation.ClassPathBeanDefinitionScanner" level="INFO" />
+    <logger name="org.springframework.beans.factory.support.DefaultListableBeanFactory" level="INFO" />
+    <logger name="org.springframework.data.convert.CustomConversions" level="INFO"/>
+    <logger name="org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener" level="INFO" />
+    <logger name="org.springframework.boot.autoconfigure.web.servlet.WelcomePageHandlerMapping" level="INFO" />
+    <logger name="org.springframework" level="INFO" />
+    <logger name="io.netty" level="INFO" />
+    <logger name="org.mybatis" level="INFO" />
+    <logger name="org.hibernate" level="INFO" />
+    <logger name="io.lettuce" level="INFO" />
+    <logger name="springfox.documentation" level="INFO" />
+
+    <logger name="com.netflix.discovery" level="ERROR" />
+    <logger name="com.netflix.eureka" level="ERROR" />
+    <logger name="org.springframework.security" level="ERROR" />
+
+    <root level="DEBUG" >
+        <appender-ref ref="stdoutAppender" />
+        <!--<appender-ref ref="traceAppender" />-->
+        <appender-ref ref="debugAppender" />
+        <!--<appender-ref ref="infoAppender" />-->
+        <!--<appender-ref ref="warnAppender" />-->
+        <!--<appender-ref ref="errorAppender" />-->
+    </root>
+</configuration>

+ 10 - 1
src/main/resources/mybatis/TokenRecordMapper.xml

@@ -5,7 +5,7 @@
 <mapper namespace="com.ematou.wxbase.mapper.TokenRecordMapper">
 
     <sql id="Base_Column_List">
-        id, access_token, expires_time, effect_time, expires_in, op_id, is_valid, creater_sn, create_time, moder_sn, mod_time, tstm
+        id, access_token, expires_time, effect_time, expires_in, op_id, is_valid, creater_sn, create_time, moder_sn, mod_time, tstm, app_id
     </sql>
 
     <!-- 插入记录后返回id -->
@@ -48,6 +48,9 @@
             <if test="record.tstm != null">
                 tstm,
             </if>
+            <if test="record.appId != null">
+                app_id,
+            </if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides="," >
             <if test="record.accessToken != null">
@@ -83,6 +86,9 @@
             <if test="record.tstm != null">
                 #{record.tstm},
             </if>
+            <if test="record.appId != null">
+                #{record.appId},
+            </if>
         </trim>
     </insert>
 
@@ -100,6 +106,9 @@
         <include refid="Base_Column_List"/>
         from wx_token_record
         where is_valid=0
+        <if test="appId != null">
+            and app_id = #{appId}
+        </if>
         order by id desc
         limit 1
     </select>

+ 1 - 1
src/test/java/com/ematou/wxbase/WxbaseApplicationTests.java

@@ -16,7 +16,7 @@ class WxbaseApplicationTests {
     @Test
     void contextLoads() throws Exception {
 
-        TokenRecord latestToken = tokenRecordService.getLatestToken();
+        TokenRecord latestToken = tokenRecordService.getLatestToken(null);
 
         System.out.println(latestToken);