Forráskód Böngészése

1.增加农小禹服务;2.完成农小禹小程序一键登录注册;

jiuling 1 éve
szülő
commit
5c59a32b0b
20 módosított fájl, 862 hozzáadás és 18 törlés
  1. 1 1
      pom.xml
  2. 22 0
      ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java
  3. 1 0
      ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java
  4. 1 1
      ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/auth/AuthLogic.java
  5. 5 0
      ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/interceptor/HeaderInterceptor.java
  6. 74 3
      ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
  7. 17 5
      ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java
  8. 1 0
      ruoyi-modules/pom.xml
  9. 13 0
      ruoyi-modules/ruoyi-system/pom.xml
  10. 50 0
      ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/UniAppLoginBody.java
  11. 3 2
      ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
  12. 9 0
      ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
  13. 157 2
      ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
  14. 29 4
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
  15. 108 0
      ruoyi-modules/ruoyi-uniapp/pom.xml
  16. 25 0
      ruoyi-modules/ruoyi-uniapp/src/main/java/com/ruoyi/uniapp/UniAppApplication.java
  17. 18 0
      ruoyi-modules/ruoyi-uniapp/src/main/java/com/ruoyi/uniapp/config/RestTemplateConfig.java
  18. 122 0
      ruoyi-modules/ruoyi-uniapp/src/main/java/com/ruoyi/uniapp/controller/UniAppLoginController.java
  19. 32 0
      ruoyi-modules/ruoyi-uniapp/src/main/resources/bootstrap.yml
  20. 174 0
      ruoyi-modules/ruoyi-uniapp/src/main/resources/logback-spring.xml

+ 1 - 1
pom.xml

@@ -34,7 +34,7 @@
         <poi.version>4.1.2</poi.version>
         <springdoc.version>1.6.9</springdoc.version>
         <transmittable-thread-local.version>2.14.4</transmittable-thread-local.version>
-
+        <hutool.version>5.4.2</hutool.version>
         <!-- override dependency version -->
         <tomcat.version>9.0.102</tomcat.version>
         <logback.version>1.2.13</logback.version>

+ 22 - 0
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java

@@ -26,6 +26,9 @@ public class SysUser extends BaseEntity
     @Excel(name = "用户序号", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "用户编号")
     private Long userId;
 
+    /** 用户ID */
+    @Excel(name = "微信openId", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "微信openId")
+    private String openId;
     /** 部门ID */
     @Excel(name = "部门编号", type = Type.IMPORT)
     private Long deptId;
@@ -34,6 +37,10 @@ public class SysUser extends BaseEntity
     @Excel(name = "登录名称")
     private String userName;
 
+    /** 用户类型 00:系统用户 11:微信用户 */
+    @Excel(name = "用户类型")
+    private String userType;
+
     /** 用户昵称 */
     @Excel(name = "用户名称")
     private String nickName;
@@ -100,6 +107,21 @@ public class SysUser extends BaseEntity
         this.userId = userId;
     }
 
+    public String getUserType() {
+        return userType;
+    }
+
+    public void setUserType(String userType) {
+        this.userType = userType;
+    }
+    public String getOpenId() {
+        return openId;
+    }
+
+    public void setOpenId(String openId) {
+        this.openId = openId;
+    }
+
     public Long getUserId()
     {
         return userId;

+ 1 - 0
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java

@@ -31,6 +31,7 @@ public class CacheConstants
      * 权限缓存前缀
      */
     public final static String LOGIN_TOKEN_KEY = "login_tokens:";
+    public final static String UNIAPP_LOGIN_TOKEN_KEY = "uniapp_login_tokens:";
 
     /**
      * 验证码 redis key

+ 1 - 1
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/auth/AuthLogic.java

@@ -94,7 +94,7 @@ public class AuthLogic
     }
 
     /**
-     * 验证当前用户有效期, 如果相差不足120分钟,自动刷新缓存
+     * 验证当前小程序用户/PC端有效期, 如果相差不足120分钟,自动刷新缓存
      * 
      * @param loginUser 当前用户信息
      */

+ 5 - 0
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/interceptor/HeaderInterceptor.java

@@ -39,6 +39,11 @@ public class HeaderInterceptor implements AsyncHandlerInterceptor
             if (StringUtils.isNotNull(loginUser))
             {
                 AuthUtil.verifyLoginUserExpire(loginUser);
+                // ✅ 增加:uniapp 登录用户有效期验证
+                if (loginUser.getSysUser().getUserType().equals("11")) {
+                    // 小程序用户
+                    AuthUtil.verifyLoginUserExpire(loginUser);
+                }
                 SecurityContextHolder.set(SecurityConstants.LOGIN_USER, loginUser);
             }
         }

+ 74 - 3
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java

@@ -39,6 +39,7 @@ public class TokenService
     private final static long TOKEN_EXPIRE_TIME = CacheConstants.EXPIRATION;
 
     private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;
+    private final static String UNIAPP_ACCESS_TOKEN = CacheConstants.UNIAPP_LOGIN_TOKEN_KEY;
 
     private final static Long TOKEN_REFRESH_THRESHOLD_MINUTES = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
 
@@ -68,6 +69,32 @@ public class TokenService
         rspMap.put("expires_in", TOKEN_EXPIRE_TIME);
         return rspMap;
     }
+    /**
+     * 创建Uniapp令牌
+     */
+    public Map<String, Object> createUniappToken(LoginUser loginUser)
+    {
+        String token = IdUtils.fastUUID();
+        Long userId = loginUser.getSysUser().getUserId();
+        String userName = loginUser.getSysUser().getUserName();
+        loginUser.setToken(token);
+        loginUser.setUserid(userId);
+        loginUser.setUsername(userName);
+        loginUser.setIpaddr(IpUtils.getIpAddr());
+        refreshUniappToken(loginUser);
+
+        // Jwt存储信息
+        Map<String, Object> claimsMap = new HashMap<String, Object>();
+        claimsMap.put(SecurityConstants.USER_KEY, token);
+        claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
+        claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName);
+
+        // 接口返回信息
+        Map<String, Object> rspMap = new HashMap<String, Object>();
+        rspMap.put("access_token", JwtUtils.createToken(claimsMap));
+        rspMap.put("expires_in", TOKEN_EXPIRE_TIME);
+        return rspMap;
+    }
 
     /**
      * 获取用户身份信息
@@ -104,7 +131,19 @@ public class TokenService
             if (StringUtils.isNotEmpty(token))
             {
                 String userkey = JwtUtils.getUserKey(token);
-                user = redisService.getCacheObject(getTokenKey(userkey));
+                // 尝试从 PC 登录缓存中获取
+                String pcTokenKey = getTokenKey(userkey);
+                user = redisService.getCacheObject(pcTokenKey);
+                if (user != null) {
+                    log.debug("从PC缓存中获取用户: {}", user.getUsername());
+                    return user;
+                }
+                // PC未命中,尝试从UniApp缓存中获取
+                String uniappTokenKey = getUniappTokenKey(userkey);
+                user = redisService.getCacheObject(uniappTokenKey);
+                if (user != null) {
+                    log.debug("从UniApp缓存中获取用户: {}", user.getUsername());
+                }
                 return user;
             }
         }
@@ -133,8 +172,20 @@ public class TokenService
     {
         if (StringUtils.isNotEmpty(token))
         {
-            String userkey = JwtUtils.getUserKey(token);
-            redisService.deleteObject(getTokenKey(userkey));
+            String userKey = JwtUtils.getUserKey(token);
+            String pcTokenKey = getTokenKey(userKey);
+            String uniappTokenKey = getUniappTokenKey(userKey);
+
+            if (redisService.hasKey(pcTokenKey)) {
+                redisService.deleteObject(pcTokenKey);
+                log.info("Deleted PC/H5 token: {}", pcTokenKey);
+            } else if (redisService.hasKey(uniappTokenKey)) {
+                redisService.deleteObject(uniappTokenKey);
+                log.info("Deleted UniApp token: {}", uniappTokenKey);
+            } else {
+                log.warn("No token found in Redis for userKey: {}", userKey);
+            }
+
         }
     }
 
@@ -150,6 +201,9 @@ public class TokenService
         if (expireTime - currentTime <= TOKEN_REFRESH_THRESHOLD_MINUTES)
         {
             refreshToken(loginUser);
+            if (loginUser.getSysUser().getUserType().equals("11")){
+                refreshUniappToken(loginUser);
+            }
         }
     }
 
@@ -166,9 +220,26 @@ public class TokenService
         String userKey = getTokenKey(loginUser.getToken());
         redisService.setCacheObject(userKey, loginUser, TOKEN_EXPIRE_TIME, TimeUnit.MINUTES);
     }
+    /**
+     * 刷新令牌有效期
+     *
+     * @param loginUser 登录信息
+     */
+    public void refreshUniappToken(LoginUser loginUser)
+    {
+        loginUser.setLoginTime(System.currentTimeMillis());
+        loginUser.setExpireTime(loginUser.getLoginTime() + TOKEN_EXPIRE_TIME * MILLIS_MINUTE);
+        // 根据uuid将loginUser缓存
+        String userKey = getUniappTokenKey(loginUser.getToken());
+        redisService.setCacheObject(userKey, loginUser, TOKEN_EXPIRE_TIME, TimeUnit.MINUTES);
+    }
 
     private String getTokenKey(String token)
     {
         return ACCESS_TOKEN + token;
     }
+    private String getUniappTokenKey(String token)
+    {
+        return UNIAPP_ACCESS_TOKEN + token;
+    }
 }

+ 17 - 5
ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java

@@ -61,10 +61,15 @@ public class AuthFilter implements GlobalFilter, Ordered
         {
             return unauthorizedResponse(exchange, "令牌已过期或验证不正确!");
         }
-        String userkey = JwtUtils.getUserKey(claims);
-        boolean islogin = redisService.hasKey(getTokenKey(userkey));
-        if (!islogin)
-        {
+        //处理token
+        String userKey = JwtUtils.getUserKey(claims);
+        String pcTokenKey = getTokenKey(userKey);
+        String uniappTokenKey = getUniappTokenKey(userKey);
+
+        // 优先检查 PC Token,其次 Uniapp Token
+        boolean isLogin = redisService.hasKey(pcTokenKey) || redisService.hasKey(uniappTokenKey);
+
+        if (!isLogin) {
             return unauthorizedResponse(exchange, "登录状态已过期");
         }
         String userid = JwtUtils.getUserId(claims);
@@ -75,7 +80,7 @@ public class AuthFilter implements GlobalFilter, Ordered
         }
 
         // 设置用户信息到请求
-        addHeader(mutate, SecurityConstants.USER_KEY, userkey);
+        addHeader(mutate, SecurityConstants.USER_KEY, userKey);
         addHeader(mutate, SecurityConstants.DETAILS_USER_ID, userid);
         addHeader(mutate, SecurityConstants.DETAILS_USERNAME, username);
         // 内部请求来源参数清除
@@ -112,6 +117,13 @@ public class AuthFilter implements GlobalFilter, Ordered
     {
         return CacheConstants.LOGIN_TOKEN_KEY + token;
     }
+    /**
+     * 获取缓存key
+     */
+    private String getUniappTokenKey(String token)
+    {
+        return CacheConstants.UNIAPP_LOGIN_TOKEN_KEY + token;
+    }
 
     /**
      * 获取请求token

+ 1 - 0
ruoyi-modules/pom.xml

@@ -13,6 +13,7 @@
         <module>ruoyi-gen</module>
         <module>ruoyi-job</module>
         <module>ruoyi-file</module>
+        <module>ruoyi-uniapp</module>
     </modules>
 
     <artifactId>ruoyi-modules</artifactId>

+ 13 - 0
ruoyi-modules/ruoyi-system/pom.xml

@@ -70,6 +70,19 @@
             <groupId>com.ruoyi</groupId>
             <artifactId>ruoyi-common-swagger</artifactId>
         </dependency>
+        <!-- Hutool工具包 -->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>${hutool.version}</version>
+        </dependency>
+
+        <!--Lombok-->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
 
     </dependencies>
 

+ 50 - 0
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/UniAppLoginBody.java

@@ -0,0 +1,50 @@
+package com.ruoyi.system.domain;
+
+import lombok.Data;
+
+/**
+ * UniApp登录对象
+ */
+@Data
+public class UniAppLoginBody
+{
+    /**
+     * 微信登录code
+     */
+    private String code;
+
+    /**
+     * 微信openid
+     */
+    private String openId;
+
+    /**
+     * 用户昵称
+     */
+    private String nickName;
+
+    /**
+     * 用户头像
+     */
+    private String avatarUrl;
+
+    /**
+     * 性别
+     */
+    private String gender;
+
+    /**
+     * 手机号
+     */
+    private String phoneNumber;
+
+    /*
+     * encryptedData 微信返回加密信息
+     * */
+    private String encryptedData;
+    /*
+     * iv 微信返回
+     * */
+    private String iv;
+
+} 

+ 3 - 2
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java

@@ -36,11 +36,12 @@ public interface SysUserMapper
     public List<SysUser> selectUnallocatedList(SysUser user);
 
     /**
-     * 通过用户名查询用户
+     * 查询用户
      * 
-     * @param userName 用户名
+     * @param sysUser 用户名
      * @return 用户对象信息
      */
+    public SysUser selectUserByUser(SysUser sysUser);
     public SysUser selectUserByUserName(String userName);
 
     /**

+ 9 - 0
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java

@@ -1,7 +1,12 @@
 package com.ruoyi.system.service;
 
 import java.util.List;
+
+import com.ruoyi.common.core.domain.R;
 import com.ruoyi.system.api.domain.SysUser;
+import com.ruoyi.system.domain.UniAppLoginBody;
+
+import javax.servlet.http.HttpServletRequest;
 
 /**
  * 用户 业务层
@@ -203,4 +208,8 @@ public interface ISysUserService
      * @return 结果
      */
     public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName);
+
+    R<?> uniappLogin(UniAppLoginBody loginBody, HttpServletRequest request);
+
+    void uniappLogout(String token);
 }

+ 157 - 2
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java

@@ -1,12 +1,30 @@
 package com.ruoyi.system.service.impl;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
+import javax.servlet.http.HttpServletRequest;
 import javax.validation.Validator;
+
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.ruoyi.common.core.constant.CacheConstants;
+import com.ruoyi.common.core.constant.Constants;
+import com.ruoyi.common.core.constant.SecurityConstants;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.utils.JwtUtils;
+import com.ruoyi.common.core.utils.ip.IpUtils;
+import com.ruoyi.common.core.utils.uuid.IdUtils;
+import com.ruoyi.common.redis.service.RedisService;
+import com.ruoyi.common.security.service.TokenService;
+import com.ruoyi.system.api.model.LoginUser;
+import com.ruoyi.system.domain.UniAppLoginBody;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
@@ -30,6 +48,7 @@ import com.ruoyi.system.mapper.SysUserRoleMapper;
 import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.system.service.ISysDeptService;
 import com.ruoyi.system.service.ISysUserService;
+import org.springframework.web.client.RestTemplate;
 
 /**
  * 用户 业务层处理
@@ -40,6 +59,20 @@ import com.ruoyi.system.service.ISysUserService;
 public class SysUserServiceImpl implements ISysUserService
 {
     private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class);
+    @Value("${weixin.appid}")
+    private String appid;
+
+    @Value("${weixin.secret}")
+    private String secret;
+
+    @Value("${weixin.token-expire}")
+    private long expire;
+
+    @Value("${weixin.token-secret}")
+    private String tokenSecret;
+
+    @Autowired
+    private RestTemplate restTemplate;
 
     @Autowired
     private SysUserMapper userMapper;
@@ -64,6 +97,10 @@ public class SysUserServiceImpl implements ISysUserService
 
     @Autowired
     protected Validator validator;
+    @Autowired
+    private RedisService redisService;
+    @Autowired
+    private TokenService tokenService;
 
     /**
      * 根据条件分页查询用户列表
@@ -548,4 +585,122 @@ public class SysUserServiceImpl implements ISysUserService
         return successMsg.toString();
     }
 
+    /**
+     * 小程序登录
+     *
+     * @param loginBody 登录信息
+     * @return 结果
+     */
+    @Override
+    public R<?> uniappLogin(UniAppLoginBody loginBody, HttpServletRequest request) {
+        try {
+            // 调用微信接口获取openid
+            String url = "https://api.weixin.qq.com/sns/jscode2session?" +
+                    "appid=" + appid + "&" +
+                    "secret=" + secret + "&" +
+                    "js_code=" + loginBody.getCode() + "&" +
+                    "grant_type=authorization_code";
+            String result = restTemplate.getForObject(url, String.class);
+            JSONObject json = JSONUtil.parseObj(result);
+
+            // 解析json获取openid (简化处理,实际应使用JSON解析库)
+            String openid = json.getStr("openid");
+            if (StringUtils.isEmpty(openid)) {
+                return R.fail("获取微信openid失败");
+            }
+            // 返回数据封装
+            Map<String, Object> data = new HashMap<>();
+            // 根据 openid 查询用户信息
+            SysUser userQuery = new SysUser();
+            userQuery.setOpenId(openid);
+            userQuery.setStatus("0");
+            SysUser dbUser = userMapper.selectUserByUser(userQuery);
+            // 若用户不存在,则注册新用户
+            if (dbUser == null) {
+                data.put("isNewUser",true); // 新用户标志
+                dbUser = new SysUser();
+                dbUser.setOpenId(openid);
+                dbUser.setNickName(loginBody.getNickName());
+                dbUser.setUserName(loginBody.getNickName());
+                dbUser.setUserType("11"); // 表示微信用户
+                dbUser.setAvatar(loginBody.getAvatarUrl());
+                dbUser.setCreateBy(loginBody.getNickName());
+                dbUser.setCreateTime(new Date());
+                dbUser.setLoginIp(IpUtils.getIpAddr());
+                dbUser.setSex(loginBody.getGender());
+                dbUser.setDelFlag("0");
+                userMapper.insertUser(dbUser);
+            }else {
+                data.put("isNewUser",false);
+            }
+            // 判断当前 request 是否已登录(即 token 是否有效)
+            LoginUser loginUser = tokenService.getLoginUser(request);
+            String token;
+
+            if (loginUser == null) {
+                // 无效 token 或未登录:重新生成 token
+                token = createToken(dbUser);
+            } else {
+                token = loginUser.getToken(); // 已登录用户,直接复用 token
+            }
+
+            data.put("token", token);
+            data.put("userInfo", dbUser);
+            return R.ok(data);
+        } catch (Exception e) {
+            return R.fail("登录失败:" + e.getMessage());
+        }
+    }
+
+    public void uniappLogout(String token) {
+       /* String tokenKey = CacheConstants.UNIAPP_LOGIN_TOKEN_KEY + token;
+        SysUser user = redisService.getCacheObject(tokenKey);
+
+        if (user != null) {
+            String userTokenKey = CacheConstants.UNIAPP_LOGIN_TOKEN_KEY + user.getUserId();
+            redisService.deleteObject(userTokenKey);
+        }
+
+        redisService.deleteObject(tokenKey);*/
+    }
+
+
+    /**
+     * 创建JWT Token
+     */
+    public String createToken(SysUser user) {
+        LoginUser loginUser = new LoginUser();
+        loginUser.setSysUser(user);
+
+        // 创建token
+        Map<String, Object> uniappToken = tokenService.createUniappToken(loginUser);
+
+
+        /*String userTokenKey = CacheConstants.UNIAPP_LOGIN_TOKEN_KEY + user.getUserId();
+        String token = redisService.getCacheObject(userTokenKey);
+
+        if (StringUtils.isNotBlank(token)) {
+            // 已登录过,复用旧 token
+            return token;
+        }
+
+        // 否则生成新的 token
+        long currentTime = System.currentTimeMillis();
+        token = Jwts.builder()
+                .setSubject(user.getUserId().toString())
+                .setIssuedAt(new Date(currentTime))
+                .setExpiration(new Date(currentTime + expire * 60 * 1000))
+                .signWith(SignatureAlgorithm.HS512, tokenSecret)
+                .compact();
+
+        String tokenKey = CacheConstants.UNIAPP_LOGIN_TOKEN_KEY + token;
+
+        // 写入 Redis:token->user,userId->token(双向缓存)
+        redisService.setCacheObject(tokenKey, user, expire, TimeUnit.MINUTES);
+        redisService.setCacheObject(userTokenKey, token, expire, TimeUnit.MINUTES);*/
+
+        return (String) uniappToken.get("access_token");
+    }
+
+
 }

+ 29 - 4
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml

@@ -7,6 +7,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <resultMap type="SysUser" id="SysUserResult">
         <id     property="userId"       column="user_id"      />
         <result property="deptId"       column="dept_id"      />
+        <result property="openId"       column="open_id"      />
+        <result property="userType"       column="user_type"      />
         <result property="userName"     column="user_name"    />
         <result property="nickName"     column="nick_name"    />
         <result property="email"        column="email"        />
@@ -47,7 +49,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 	
 	<sql id="selectUserVo">
-        select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, 
+        select u.user_id, u.dept_id,u.open_id, u.user_type, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
         d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status,
         r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status
         from sys_user u
@@ -57,7 +59,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </sql>
     
     <select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
-		select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from sys_user u
+		select u.user_id, u.dept_id, u.nick_name, u.open_id, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from sys_user u
 		left join sys_dept d on u.dept_id = d.dept_id
 		where u.del_flag = '0'
 		<if test="userId != null and userId != 0">
@@ -66,6 +68,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		<if test="userName != null and userName != ''">
 			AND u.user_name like concat('%', #{userName}, '%')
 		</if>
+		<if test="openId != null and openId != ''">
+			AND u.open_id = #{openId}
+		</if>
 		<if test="status != null and status != ''">
 			AND u.status = #{status}
 		</if>
@@ -120,8 +125,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		${params.dataScope}
 	</select>
 	
-	<select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult">
+	<select id="selectUserByUser" parameterType="com.ruoyi.system.api.domain.SysUser" resultMap="SysUserResult">
 	    <include refid="selectUserVo"/>
+		<where>
+			<if test="openId != null and openId != ''">
+				AND u.open_id = #{openId}
+			</if>
+		</where>
+	</select>
+	<select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult">
+		<include refid="selectUserVo"/>
 		where u.user_name = #{userName} and u.del_flag = '0'
 	</select>
 	
@@ -146,8 +159,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  		insert into sys_user(
  			<if test="userId != null and userId != 0">user_id,</if>
  			<if test="deptId != null and deptId != 0">dept_id,</if>
+ 			<if test="openId != null and openId != ''">open_id,</if>
  			<if test="userName != null and userName != ''">user_name,</if>
  			<if test="nickName != null and nickName != ''">nick_name,</if>
+ 			<if test="userType != null and userType != ''">user_type,</if>
  			<if test="email != null and email != ''">email,</if>
  			<if test="avatar != null and avatar != ''">avatar,</if>
  			<if test="phonenumber != null and phonenumber != ''">phonenumber,</if>
@@ -160,8 +175,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  		)values(
  			<if test="userId != null and userId != ''">#{userId},</if>
  			<if test="deptId != null and deptId != ''">#{deptId},</if>
+ 			<if test="openId != null and openId != ''">#{openId},</if>
  			<if test="userName != null and userName != ''">#{userName},</if>
  			<if test="nickName != null and nickName != ''">#{nickName},</if>
+ 			<if test="userType != null and userType != ''">#{userType},</if>
  			<if test="email != null and email != ''">#{email},</if>
  			<if test="avatar != null and avatar != ''">#{avatar},</if>
  			<if test="phonenumber != null and phonenumber != ''">#{phonenumber},</if>
@@ -179,6 +196,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  		<set>
  			<if test="deptId != null and deptId != 0">dept_id = #{deptId},</if>
  			<if test="nickName != null and nickName != ''">nick_name = #{nickName},</if>
+ 			<if test="openId != null and openId != ''">open_id = #{openId},</if>
  			<if test="email != null ">email = #{email},</if>
  			<if test="phonenumber != null ">phonenumber = #{phonenumber},</if>
  			<if test="sex != null and sex != ''">sex = #{sex},</if>
@@ -191,7 +209,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			<if test="remark != null">remark = #{remark},</if>
  			update_time = sysdate()
  		</set>
- 		where user_id = #{userId}
+ 		<where>
+			<if test="userId != null and userId != 0">
+				AND user_id = #{userId}
+			</if>
+			<if test="openId != null and openId != ''">
+				AND open_id = #{openId}
+			</if>
+		</where>
 	</update>
 	
 	<update id="updateUserStatus" parameterType="SysUser">

+ 108 - 0
ruoyi-modules/ruoyi-uniapp/pom.xml

@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>com.ruoyi</groupId>
+        <artifactId>ruoyi-modules</artifactId>
+        <version>3.6.5</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+	
+    <artifactId>ruoyi-modules-uniapp</artifactId>
+
+    <description>
+        ruoyi-modules-uniapp小程序服务模块
+    </description>
+	
+    <dependencies>
+
+        <!-- RuoYi System 模块 -->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-modules-system</artifactId>
+            <version>3.6.5</version>
+        </dependency>
+        
+    	<!-- SpringCloud Alibaba Nacos -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+        
+        <!-- SpringCloud Alibaba Nacos Config -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+        
+    	<!-- SpringCloud Alibaba Sentinel -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
+        </dependency>
+        
+    	<!-- SpringBoot Actuator -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        
+        <!-- Mysql Connector -->
+        <dependency>
+            <groupId>com.mysql</groupId>
+            <artifactId>mysql-connector-j</artifactId>
+        </dependency>
+        
+        <!-- RuoYi Common DataSource -->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-common-datasource</artifactId>
+        </dependency>
+        
+        <!-- RuoYi Common DataScope -->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-common-datascope</artifactId>
+        </dependency>
+        
+        <!-- RuoYi Common Log -->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-common-log</artifactId>
+        </dependency>
+        
+        <!-- RuoYi Common Swagger -->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-common-swagger</artifactId>
+        </dependency>
+
+        <!-- JWT -->
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.9.1</version>
+        </dependency>
+
+
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+   
+</project> 

+ 25 - 0
ruoyi-modules/ruoyi-uniapp/src/main/java/com/ruoyi/uniapp/UniAppApplication.java

@@ -0,0 +1,25 @@
+package com.ruoyi.uniapp;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import com.ruoyi.common.security.annotation.EnableCustomConfig;
+import com.ruoyi.common.security.annotation.EnableRyFeignClients;
+import org.springframework.context.annotation.ComponentScan;
+
+/**
+ * UniApp服务启动类
+ */
+@EnableCustomConfig
+@EnableRyFeignClients
+@SpringBootApplication
+@ComponentScan(basePackages = {"com.ruoyi.system.*","com.ruoyi.uniapp.*"})
+@MapperScan("com.ruoyi.*.mapper")
+public class UniAppApplication
+{
+    public static void main(String[] args)
+    {
+        SpringApplication.run(UniAppApplication.class, args);
+        System.out.println("(♥◠‿◠)ノ゙  UniApp服务模块启动成功   ლ(´ڡ`ლ)゙");
+    }
+} 

+ 18 - 0
ruoyi-modules/ruoyi-uniapp/src/main/java/com/ruoyi/uniapp/config/RestTemplateConfig.java

@@ -0,0 +1,18 @@
+package com.ruoyi.uniapp.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * RestTemplate配置
+ */
+@Configuration
+public class RestTemplateConfig
+{
+    @Bean
+    public RestTemplate restTemplate()
+    {
+        return new RestTemplate();
+    }
+} 

+ 122 - 0
ruoyi-modules/ruoyi-uniapp/src/main/java/com/ruoyi/uniapp/controller/UniAppLoginController.java

@@ -0,0 +1,122 @@
+package com.ruoyi.uniapp.controller;
+
+import com.ruoyi.common.core.utils.JwtUtils;
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.security.auth.AuthUtil;
+import com.ruoyi.common.security.service.TokenService;
+import com.ruoyi.common.security.utils.SecurityUtils;
+import com.ruoyi.system.api.domain.SysUser;
+import com.ruoyi.system.api.model.LoginUser;
+import com.ruoyi.system.domain.UniAppLoginBody;
+import com.ruoyi.system.mapper.SysUserMapper;
+import com.ruoyi.system.service.ISysUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.utils.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/**
+ * UniApp登录控制器
+ */
+@RestController
+@RequestMapping("/wechat")
+public class UniAppLoginController extends BaseController
+{
+    @Autowired
+    private ISysUserService userService;
+    @Autowired
+    private TokenService tokenService;
+
+    /**
+     * 小程序登录
+     */
+    @PostMapping("/login")
+    public R<?> login(@RequestBody UniAppLoginBody loginBody, HttpServletRequest request)
+    {
+        if (StringUtils.isEmpty(loginBody.getCode()))
+        {
+            return R.fail("登录code不能为空");
+        }
+        // 登录处理
+        return userService.uniappLogin(loginBody,request);
+    }
+    /**
+     * 小程序登录
+     */
+    @PostMapping("/logout")
+    public R<?> logout(HttpServletRequest request)
+    {
+        String token = SecurityUtils.getToken(request);
+        if (StringUtils.isNotEmpty(token))
+        {
+            String username = JwtUtils.getUserName(token);
+            // 删除用户缓存记录
+            AuthUtil.logoutByToken(token);
+//            // 记录用户退出日志
+//            sysLoginService.logout(username);
+        }
+        return R.ok();
+    }
+
+    @PostMapping("/refresh")
+    public R<?> refresh(HttpServletRequest request)
+    {
+        LoginUser loginUser = tokenService.getLoginUser(request);
+        if (StringUtils.isNotNull(loginUser))
+        {
+            // 刷新令牌有效期
+            tokenService.refreshUniappToken(loginUser);
+            return R.ok();
+        }
+        return R.ok();
+    }
+
+    /*
+    * 小程序上传用户头像、昵称
+    * */
+    @PostMapping("/uploadInfo")
+    public R<?> uploadInfo(@RequestBody UniAppLoginBody loginBody,HttpServletRequest request) {
+        // 参数为空校验
+        if (loginBody == null || (loginBody.getAvatarUrl() == null && loginBody.getNickName() == null)) {
+            return R.fail(400, "请上传用户头像或昵称");
+        }
+        try {
+            SysUser queryUser = new SysUser();
+            queryUser.setOpenId(loginBody.getOpenId());
+
+            List<SysUser> userList = userService.selectUserList(queryUser);
+            if (userList == null || userList.isEmpty()) {
+                return R.fail(404, "未找到对应用户");
+            }
+
+            queryUser = userList.get(0);
+            if (queryUser.getUserId() == null) {
+                return R.fail(500, "用户信息异常");
+            }
+
+            // 更新头像和昵称
+            queryUser.setAvatar(loginBody.getAvatarUrl());
+            queryUser.setNickName(loginBody.getNickName());
+
+            int updateCount = userService.updateUser(queryUser);
+            if (updateCount <= 0) {
+                return R.fail(500, "上传头像和昵称失败");
+            }
+            LoginUser loginUser = tokenService.getLoginUser(request);
+            if (StringUtils.isNotNull(loginUser))
+            {
+               loginUser.setSysUser(queryUser);
+                // 刷新令牌有效期 同步缓存中的用户信息
+                tokenService.refreshUniappToken(loginUser);
+            }
+            return R.ok(queryUser, "更新用户信息成功");
+        } catch (Exception e) {
+            return R.fail(500, "服务器异常,请稍后重试");
+        }
+    }
+
+
+} 

+ 32 - 0
ruoyi-modules/ruoyi-uniapp/src/main/resources/bootstrap.yml

@@ -0,0 +1,32 @@
+# Tomcat
+server:
+  port: 9203
+
+# Spring
+spring: 
+  application:
+    # 应用名称
+    name: ruoyi-uniapp
+  profiles:
+    # 环境配置
+    active: dev
+  cloud:
+    nacos:
+      discovery:
+        # 服务注册地址
+        server-addr: 121.4.16.100:8848
+        username: nacos
+        password: nacos369
+      config:
+        username: nacos
+        password: nacos369
+        # 配置中心地址
+        server-addr: 121.4.16.100:8848
+        # 配置文件格式
+        file-extension: yml
+        # 共享配置
+        shared-configs:
+          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
+          - data-id: ruoyi-uniapp-dev.yml
+            group: DEFAULT_GROUP
+            refresh: true

+ 174 - 0
ruoyi-modules/ruoyi-uniapp/src/main/resources/logback-spring.xml

@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    小技巧: 在根pom里面设置统一存放路径,统一管理方便维护
+    <properties>
+        <log-path>/Users/xyhy</log-path>
+    </properties>
+    1. 其他模块加日志输出,直接copy本文件放在resources 目录即可
+    2. 注意修改 <property name="${log-path}/log.path" value=""/> 的value模块
+-->
+<configuration debug="false" scan="false">
+    <property name="log.path" value="logs/${project.artifactId}"/>
+	<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
+
+	<property name="log.date" value="%d{yyyy-MM-dd}" />
+    <!-- 彩色日志格式 -->
+    <property name="CONSOLE_LOG_PATTERN"
+              value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
+    <!-- 彩色日志依赖的渲染类 -->
+    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
+    <conversionRule conversionWord="wex"
+                    converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
+    <conversionRule conversionWord="wEx"
+                    converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
+    <!-- Console log output -->
+    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+        </encoder>
+    </appender>
+
+    <!-- Log file info output -->
+    <appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/info.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/%d{yyyy-MM, aux}/info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+            <maxFileSize>200MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- Log file error output -->
+    <appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/error.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+            <maxFileSize>200MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>ERROR</level>
+        </filter>
+    </appender>
+
+
+	<!-- E充网访问日志输出  -->
+	<appender name="sys-pilelog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>${log.path}/sys-pilelog/sys-pilelog.log</file>
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<!-- 按天回滚 daily -->
+			<fileNamePattern>${log.path}/sys-pilelog/sys-pilelog.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>14</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+	</appender>
+	<!--uniapp小程序日志访问日志输出  -->
+	<appender name="sys-uniapp" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>${log.path}/sys-uniapp/sys-uniapp.log</file>
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<!-- 按天回滚 daily -->
+			<fileNamePattern>${log.path}/sys-uniapp/sys-uniapp.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>14</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+	</appender>
+	<!--支付充电访问日志输出  -->
+	<appender name="sys-pay" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>${log.path}/sys-pay/sys-pay.log</file>
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<!-- 按天回滚 daily -->
+			<fileNamePattern>${log.path}/sys-pay/sys-pay.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>14</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+	</appender>
+	<!--结算访问日志输出  -->
+	<appender name="sys-settlement" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>${log.path}/sys-settlement/settlement.log</file>
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<!-- 按天回滚 daily -->
+			<fileNamePattern>${log.path}/sys-settlement/sys-settlement.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>14</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+	</appender>
+	<!--数据共享日志输出  -->
+	<appender name="datashare" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>${log.path}/datashare/datashare.log</file>
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<!-- 按天回滚 daily -->
+			<fileNamePattern>${log.path}/sys-datashare/datashare.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>14</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+	</appender>
+
+	<!--二代电池包日志输出  -->
+	<appender name="sys-secondBattery" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>${log.path}/sys-secondBattery/secondBattery.log</file>
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<!-- 按天回滚 daily -->
+			<fileNamePattern>${log.path}/sys-secondBattery/sys-secondBattery.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>14</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+	</appender>
+
+    <logger name="org.activiti.engine.impl.db" level="info">
+        <appender-ref ref="info"/>
+    </logger>
+
+    <!--nacos 心跳 INFO 屏蔽-->
+    <logger name="com.alibaba.nacos" level="OFF">
+        <appender-ref ref="error"/>
+    </logger>
+    <!-- Level: FATAL 0  ERROR 3  WARN 4  INFO 6  DEBUG 7 -->
+    <root level="INFO">
+        <appender-ref ref="console"/>
+        <appender-ref ref="info"/>
+    </root>
+	<!--充电操作日志-->
+	<logger name="sys-pilelog" level="INFO">
+		<appender-ref ref="sys-pilelog"/>
+	</logger>
+	<!--小程序操作日志-->
+	<logger name="sys-uniapp" level="INFO">
+		<appender-ref ref="sys-uniapp"/>
+	</logger>
+	<!--支付充值操作日志-->
+	<logger name="sys-pay" level="INFO">
+		<appender-ref ref="sys-pay"/>
+	</logger>
+	<!--结算操作日志-->
+	<logger name="sys-settlement" level="INFO">
+		<appender-ref ref="sys-settlement"/>
+	</logger>
+	<!--二代电池包操作日志-->
+	<logger name="sys-secondBattery" level="INFO">
+		<appender-ref ref="sys-secondBattery"/>
+	</logger>
+</configuration>