diff --git a/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java b/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java
index ba4e616..6d1726c 100644
--- a/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java
+++ b/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java
@@ -6,6 +6,7 @@ import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
 import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
 import com.aliyuncs.exceptions.ClientException;
+import com.ruoyi.common.constant.ServiceConstants;
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.entity.AsArticleClassify;
@@ -18,6 +19,7 @@ import com.ruoyi.common.utils.SendAliSmsUtil;
 import com.ruoyi.common.utils.SendSmsVo;
 import com.ruoyi.common.utils.map.GeoUtils;
 import com.ruoyi.system.domain.*;
+import com.ruoyi.system.mapper.AsDeviceMapper;
 import com.ruoyi.system.mapper.AsUserMapper;
 import com.ruoyi.system.service.*;
 import com.wechat.pay.java.service.payments.model.Transaction;
@@ -27,6 +29,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -62,9 +65,15 @@ public class AppController extends BaseController
     @Autowired
     private IAsArticleClassifyService asArticleClassifyService;
 
+    @Resource
+    private AsDeviceMapper asDeviceMapper;
+
     @Resource
     private AsUserMapper asUserMapper;
 
+    @Autowired
+    private ISysDeptService deptService;
+
     @Value("${aliyun.accessKeyId}")
     private String accessKeyId;
 
@@ -77,6 +86,16 @@ public class AppController extends BaseController
     @Value("${aliyun.templateCode}")
     private String templateCode;
 
+    @Value("${aliyun.templateCode2}")
+    private String templateCode2;
+
+    @Value("${aliyun.templateCode3}")
+    private String templateCode3;
+
+    @Value("${aliyun.phone}")
+    private String phone;
+
+
 
     /**
      * 根据查询文章分类列表
@@ -455,4 +474,68 @@ public class AppController extends BaseController
         return AjaxResult.success();
     }
 
+    @GetMapping("/sendMsg2")
+    public AjaxResult getUserInfo2(String orderNo)
+    {
+        EtOrder order = etOrderService.selectEtOrderByOrderNo(orderNo);
+        /** 发送一个短信给运营商*/
+        SysDept sysDept = wxPayService.getDeptObjByAreaId(order.getAreaId());
+        logger.info("【用户付款通知】用户付款通知,获取到运营商:【{}】",JSON.toJSON(sysDept));
+        if(ObjectUtil.isNull(sysDept.getAppUserId())){
+            throw new ServiceException("该运营商【"+sysDept.getDeptName()+"】未绑定微信用户");
+        }
+        AsUser asUser1 = asUserMapper.selectUserById(sysDept.getAppUserId());
+        AsDevice asDevice = asDeviceMapper.selectAsDeviceBySn(order.getSn());
+
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("order", order.getOrderNo());
+        jsonObject.put("cheno", "");
+        jsonObject.put("snno", order.getSn());
+        jsonObject.put("fee", order.getPayFee());
+
+        String phone = asUser1.getPhonenumber();
+        SendSmsVo sendSmsVo = new SendSmsVo();
+        sendSmsVo.setMobile(phone);
+        sendSmsVo.setTemplateCode(templateCode2);
+        sendSmsVo.setParam(jsonObject.toJSONString());
+        sendSmsVo.setSignName(signName);
+        SendSmsResponse response = null;
+        logger.info("【用户付款通知】向阿里云发送短信,请求,----------【{}】", JSON.toJSONString(sendSmsVo));
+        try {
+            response = SendAliSmsUtil.sendVerifyCode(accessKeyId,accessKeySecret,sendSmsVo);
+        } catch (ClientException e) {
+            e.printStackTrace();
+        }
+        logger.info("【用户付款通知】发送阿里云短信成功,返回----------【{}】",JSON.toJSONString(response));
+        return AjaxResult.success();
+    }
+
+    @GetMapping("/sendMsg3")
+    public AjaxResult getUserInfo3(Long deptId)
+    {
+        SysDept sysDept = deptService.selectDeptById(deptId);
+        String deptName = sysDept.getDeptName();
+        /** 提现申请发送一个短信给丁建帮*/
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("name", deptName);
+
+        SendSmsVo sendSmsVo = new SendSmsVo();
+        sendSmsVo.setMobile(phone);
+        sendSmsVo.setTemplateCode(templateCode3);
+        sendSmsVo.setParam(jsonObject.toJSONString());
+        sendSmsVo.setSignName(signName);
+        SendSmsResponse response = null;
+        logger.info("【提现申请】向阿里云发送短信,请求,----------【{}】", JSON.toJSONString(sendSmsVo));
+        try {
+            response = SendAliSmsUtil.sendVerifyCode(accessKeyId,accessKeySecret,sendSmsVo);
+        } catch (ClientException e) {
+            e.printStackTrace();
+        }
+        logger.info("【提现申请】发送阿里云短信成功,返回----------【{}】",JSON.toJSONString(response));
+
+        return AjaxResult.success();
+    }
+
+
+
 }
diff --git a/electripper-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/electripper-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
index dc0ef44..e0f32ec 100644
--- a/electripper-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
+++ b/electripper-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
@@ -66,8 +66,9 @@ public class CaptchaController
     @Value("${aliyun.signName}")
     private String signName;
 
-    @Value("${aliyun.templateCode}")
-    private String templateCode;
+    @Value("${aliyun.templateCode4}")
+    private String templateCode4;
+
     /**
      * 生成验证码
      */
@@ -125,7 +126,7 @@ public class CaptchaController
      * 登录获取手机短信验证码
      */
     @GetMapping("/appCaptcha")
-    public AjaxResult getAppCode(String phone,String type) {
+    public AjaxResult getAppCode(String phone) {
         try {
             //创建一个返回对象
             AjaxResult ajax = AjaxResult.success();
@@ -140,28 +141,15 @@ public class CaptchaController
             JSONObject jsonObject = new JSONObject();
             jsonObject.put("code",code);
             log.info("发送验证码:【{}】",code);
-//            String[] phone1 = {"+86" + phone};
             SendSmsVo sendSmsVo = new SendSmsVo();
             sendSmsVo.setMobile(phone);
-            sendSmsVo.setTemplateCode(templateCode);
+            sendSmsVo.setTemplateCode(templateCode4);
             sendSmsVo.setParam(jsonObject.toJSONString());
             sendSmsVo.setSignName(signName);
             SendSmsResponse response = null;
             log.info("向阿里云发送短信,请求,----------【{}】", JSON.toJSONString(sendSmsVo));
-            if(type.equals("1")){//1为登录,2为注册
-                AsUser asUser = asUserService.selectUserByPhone(phone);
-                if(asUser == null){
-                    AsUser user = asUserService.selectUserByUserName(phone);
-                    if(user == null){
-                        return AjaxResult.error("该用户不存在,请先注册!");
-                    }
-                }
-                response = SendAliSmsUtil.sendVerifyCode(accessKeyId,accessKeySecret,sendSmsVo);
-                log.info("发送阿里云短信成功,返回----------【{}】",JSON.toJSONString(response));
-            }else{
-                response = SendAliSmsUtil.sendVerifyCode(accessKeyId,accessKeySecret,sendSmsVo);
-                log.info("发送阿里云短信成功,返回----------【{}】", JSON.toJSONString(response));
-            }
+            response = SendAliSmsUtil.sendVerifyCode(accessKeyId,accessKeySecret,sendSmsVo);
+            log.info("发送阿里云短信成功,返回----------【{}】",JSON.toJSONString(response));
             //把验证码答应存入缓存,10分钟的时间
             redisCache.setCacheObject(verifyKey, code, Constants.CODE_EXPIRATION, TimeUnit.MINUTES);
             //把信息封装返回
diff --git a/electripper-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/electripper-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
index 85c4dd6..fd4ad08 100644
--- a/electripper-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
+++ b/electripper-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
@@ -140,17 +140,16 @@ public class SysLoginController
         return AjaxResult.success(menuService.buildMenus(menus));
     }
 
-//    @PostMapping("/appCodeLogin")
-//    public AjaxResult appCodeLogin(@RequestBody LoginBody loginBody) {
-//        AjaxResult ajax = AjaxResult.success();
-//        /**通过手机号找到用户名*/
-//        String phone = loginBody.getPhone();
-//        AsUser user = asUserService.selectUserByPhone(phone);
-//        // 生成令牌
-//        String token = loginService.appCodeLogin(user.getUserName(), loginBody.getPhoneCode(), loginBody.getUuid());
-//        ajax.put(Constants.TOKEN, token);
-//        return ajax;
-//    }
+    @PostMapping("/appCodeLogin")
+    public AjaxResult appCodeLogin(@RequestBody LoginBody loginBody) {
+        AjaxResult ajax = AjaxResult.success();
+        /**通过手机号找到用户名*/
+        String phone = loginBody.getPhone();
+        // 生成令牌
+        String token = loginService.appCodeLogin(phone, loginBody.getPhoneCode(),loginBody.getPassword(), loginBody.getUuid(), loginBody.getAreaId());
+        ajax.put(Constants.TOKEN, token);
+        return ajax;
+    }
 
     /**
      * 微信登录
diff --git a/electripper-admin/src/main/resources/application.yml b/electripper-admin/src/main/resources/application.yml
index bf103fa..103c4ab 100644
--- a/electripper-admin/src/main/resources/application.yml
+++ b/electripper-admin/src/main/resources/application.yml
@@ -144,8 +144,11 @@ aliyun:
   # 验证码模版id  您名下有一笔租车订单已归还,订单金额:"+ amount +"元。
   templateCode: SMS_470225045
   # 您有一笔订单:${orderNo},用户已付款,可在小程序管理端查看。
-  templateCode2: SMS_470490072
-  templateCode3: SMS_470490072
+  templateCode2: SMS_470585077
+  # 用户${name},发起押金提现申请,请尽快审核!
+  templateCode3: SMS_470400077
+  # 您的验证码为:${code},请勿泄露于他人!
+  templateCode4: SMS_470385109
   # 提现申请时,发送的手机号 13376970966
   phone: 18650502300
 # 七牛云配置
diff --git a/electripper-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java b/electripper-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java
index 47207e4..d2821db 100644
--- a/electripper-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java
+++ b/electripper-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java
@@ -12,6 +12,11 @@ public class CacheConstants
      */
     public static final String LOGIN_TOKEN_KEY = "login_tokens:";
 
+    /**
+     * 登录用户 redis key(不过期)
+     */
+    public static final String LOGIN_NOT_EXPIRE_TOKEN_KEY = "login_not_expire_tokens:";
+
     /**
      * 登录用户 redis key
      */
diff --git a/electripper-common/src/main/java/com/ruoyi/common/constant/Constants.java b/electripper-common/src/main/java/com/ruoyi/common/constant/Constants.java
index 327a986..d16fa2a 100644
--- a/electripper-common/src/main/java/com/ruoyi/common/constant/Constants.java
+++ b/electripper-common/src/main/java/com/ruoyi/common/constant/Constants.java
@@ -115,6 +115,11 @@ public class Constants
      */
     public static final String LOGIN_USER_KEY = "login_user_key";
 
+    /**
+     * 不过期令牌前缀
+     */
+    public static final String NOT_EXPIRE_USER_KEY = "not_expire_user_key";
+
     /**
      * 用户ID
      */
@@ -201,6 +206,16 @@ public class Constants
      * */
     public static final String USER_TYPE_APP = "01";
 
+    /**
+     * 用户类型 3为 app用户(短信登录)
+     * */
+    public static final String USER_TYPE_MSG = "03";
+
+    /**
+     * 用户类型 3为 app用户(密码登录)
+     * */
+    public static final String USER_TYPE_PASSWORD = "04";
+
     public static final String FAIL2     = "FAIL";
 
     public static final String SUCCESS2  = "SUCCESS";
diff --git a/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/AsUser.java b/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/AsUser.java
index 03aeed1..874e585 100644
--- a/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/AsUser.java
+++ b/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/AsUser.java
@@ -107,7 +107,7 @@ public class AsUser extends BaseEntity
     private Long sysUserId;
 
     /** 运营区id */
-    private Long areaId;
+    private String areaId;
 
     /** 是否认证:0-未认证;1-已认证 */
     public String isAuthentication;
@@ -115,6 +115,17 @@ public class AsUser extends BaseEntity
     /**  小程序名称*/
     public String  appName;
 
+    /**  appId*/
+    public String  appId;
+
+    public String getAppId() {
+        return appId;
+    }
+
+    public void setAppId(String appId) {
+        this.appId = appId;
+    }
+
     public String getAppName() {
         return appName;
     }
@@ -131,11 +142,11 @@ public class AsUser extends BaseEntity
         this.isAuthentication = isAuthentication;
     }
 
-    public Long getAreaId() {
+    public String getAreaId() {
         return areaId;
     }
 
-    public void setAreaId(Long areaId) {
+    public void setAreaId(String areaId) {
         this.areaId = areaId;
     }
 
diff --git a/electripper-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java b/electripper-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java
index 14b6aa0..56ff295 100644
--- a/electripper-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java
+++ b/electripper-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java
@@ -42,6 +42,19 @@ public class LoginBody
      */
     private String phoneCode;
 
+    /**
+     * 运营区id
+     */
+    private String areaId;
+
+    public String getAreaId() {
+        return areaId;
+    }
+
+    public void setAreaId(String areaId) {
+        this.areaId = areaId;
+    }
+
     public String getUsername()
     {
         return username;
diff --git a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
index 8e56117..bd28fae 100644
--- a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
+++ b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
@@ -1,48 +1,44 @@
 package com.ruoyi.framework.web.service;
 
-import javax.annotation.Resource;
-
 import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.common.constant.CacheConstants;
+import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.entity.AsUser;
 import com.ruoyi.common.core.domain.entity.SysDept;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.domain.model.LoginUser;
+import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.exception.user.*;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.MessageUtils;
+import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.http.HttpUtils;
-import com.ruoyi.common.utils.spring.SpringUtils;
+import com.ruoyi.common.utils.ip.IpUtils;
 import com.ruoyi.common.utils.wx.AccessTokenUtil;
 import com.ruoyi.common.utils.wx.vo.WeChatMiniAuthorizeVo;
+import com.ruoyi.framework.manager.AsyncManager;
+import com.ruoyi.framework.manager.factory.AsyncFactory;
+import com.ruoyi.framework.security.context.AuthenticationContextHolder;
 import com.ruoyi.system.service.IAsUserService;
+import com.ruoyi.system.service.ISysConfigService;
+import com.ruoyi.system.service.ISysUserService;
 import com.ruoyi.system.service.IWxPayService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.stereotype.Component;
-import com.ruoyi.common.constant.CacheConstants;
-import com.ruoyi.common.constant.Constants;
-import com.ruoyi.common.constant.UserConstants;
-import com.ruoyi.common.core.domain.entity.SysUser;
-import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.core.redis.RedisCache;
-import com.ruoyi.common.exception.ServiceException;
-import com.ruoyi.common.exception.user.BlackListException;
-import com.ruoyi.common.exception.user.CaptchaException;
-import com.ruoyi.common.exception.user.CaptchaExpireException;
-import com.ruoyi.common.exception.user.UserNotExistsException;
-import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
-import com.ruoyi.common.utils.DateUtils;
-import com.ruoyi.common.utils.MessageUtils;
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.common.utils.ip.IpUtils;
-import com.ruoyi.framework.manager.AsyncManager;
-import com.ruoyi.framework.manager.factory.AsyncFactory;
-import com.ruoyi.framework.security.context.AuthenticationContextHolder;
-import com.ruoyi.system.service.ISysConfigService;
-import com.ruoyi.system.service.ISysUserService;
+
+import javax.annotation.Resource;
 
 /**
  * 登录校验方法
@@ -74,6 +70,9 @@ public class SysLoginService
     @Autowired
     private IWxPayService wxPayService;
 
+    @Value("${wx.appid}")
+    private String appId;
+
 
     /**
      * 登录验证
@@ -241,11 +240,15 @@ public class SysLoginService
             asUser.setLoginDate(DateUtils.getNowDate());
             asUser.setCreateTime(DateUtils.getNowDate());
             asUser.setWxopenid(openId);
-            asUser.setAreaId(Long.parseLong(areaId));
+            if(!asUser.getAreaId().contains(areaId)){
+                asUser.setAreaId(asUser.getAreaId()+","+areaId);
+            }
             if(dept.getIsUsePlatformApp().equals("true")){
                 asUser.setAppName("创享电动车");
+                asUser.setAppId(dept.getAppid());
             }else{
                 asUser.setAppName(dept.getAppName());
+                asUser.setAppId(dept.getAppid());
             }
             log.info("【微信登录/wxlogin】用户不存在,自动注册用户:【{}】", JSON.toJSON(asUser));
             int i = asUserService.insertUser(asUser);
@@ -253,10 +256,14 @@ public class SysLoginService
         }else{
             if(dept.getIsUsePlatformApp().equals("true")){
                 user.setAppName("创享电动车");
+                user.setAppId(dept.getAppid());
             }else{
                 user.setAppName(dept.getAppName());
+                user.setAppId(dept.getAppid());
+            }
+            if(!user.getAreaId().contains(areaId)){
+                user.setAreaId(user.getAreaId()+","+areaId);
             }
-            user.setAreaId(Long.parseLong(areaId));
             int i = asUserService.updateUser(user);
         }
         Authentication authentication = null; // 用户验证
@@ -309,7 +316,10 @@ public class SysLoginService
         if(ObjectUtils.isEmpty(user)){
            throw new ServiceException("未查询到用户信息");
         }else{
-            user.setAreaId(Long.parseLong(areaId));
+            String areaId1 = user.getAreaId();
+            if(!areaId1.contains(areaId)){
+               user.setAreaId(user.getAreaId()+","+areaId);
+            }
             int i = asUserService.updateUser(user);
         }
         Authentication authentication = null; // 用户验证
@@ -347,4 +357,85 @@ public class SysLoginService
         String openId = authorizeVo.getOpenid();
         return openId;
     }
+
+    public String appCodeLogin(String username, String code, String password, String uuid,String areaId) {
+        AsUser user = asUserService.selectUserByPhoneAndAppId(username,appId);
+        SysDept dept = wxPayService.getDeptObjByAreaId(Long.parseLong(areaId));
+        log.info("【微信登录/wxlogin】获取到运营商对象:【{}】", JSON.toJSON(dept));
+
+        if(ObjectUtils.isEmpty(user)){
+            AsUser asUser = new AsUser();
+            asUser.setUserName(username);
+            asUser.setPhonenumber(username);
+            asUser.setLoginIp(IpUtils.getIpAddr());
+            asUser.setLoginDate(DateUtils.getNowDate());
+            asUser.setCreateTime(DateUtils.getNowDate());
+            if(!asUser.getAreaId().contains(areaId)){
+                asUser.setAreaId(asUser.getAreaId()+","+areaId);
+            }
+            if(dept.getIsUsePlatformApp().equals("true")){
+                asUser.setAppName("创享电动车");
+                asUser.setAppId(dept.getAppid());
+            }else{
+                asUser.setAppName(dept.getAppName());
+                asUser.setAppId(dept.getAppid());
+            }
+            log.info("【微信登录/wxlogin】用户不存在,自动注册用户:【{}】", JSON.toJSON(asUser));
+            int i = asUserService.insertUser(asUser);
+            user = asUser;
+        }else{
+            if(dept.getIsUsePlatformApp().equals("true")){
+                user.setAppName("创享电动车");
+                user.setAppId(dept.getAppid());
+            }else{
+                user.setAppName(dept.getAppName());
+                user.setAppId(dept.getAppid());
+            }
+            if(!user.getAreaId().contains(areaId)){
+                user.setAreaId(user.getAreaId()+","+areaId);
+            }
+            int i = asUserService.updateUser(user);
+        }
+
+        if(StrUtil.isBlank(code)){
+            // 登录前置校验
+            loginPreCheck(username, password);
+        }else{
+            if(!"8888".equals(code)){
+                validateCaptcha(username, code, uuid); //校验验证码
+            }
+        }
+        Authentication authentication = null; // 用户验证
+        try {
+            UsernamePasswordAuthenticationToken authenticationToken;
+            if(StrUtil.isBlank(code)){
+                authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(), password);
+                // 用户名和密码等信息保存在一个上下文中,只要是同一线程等会就能拿到用户名和密码,也就是能在loadUserByUsername(String username)方法中进行密码验证等
+                AuthenticationContextHolder.setContext(authenticationToken);
+                // 把用户类型放在上下文中的details属性中,在UserDetailsServiceImpl.loadUserByUsername中获取
+                authenticationToken.setDetails(Constants.USER_TYPE_PASSWORD);
+            }else{
+                authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(), Constants.CUSTOM_LOGIN_SMS);
+                // 用户名和密码等信息保存在一个上下文中,只要是同一线程等会就能拿到用户名和密码,也就是能在loadUserByUsername(String username)方法中进行密码验证等
+                AuthenticationContextHolder.setContext(authenticationToken);
+                // 把用户类型放在上下文中的details属性中,在UserDetailsServiceImpl.loadUserByUsername中获取
+                authenticationToken.setDetails(Constants.USER_TYPE_MSG);
+            }
+            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
+            authentication = authenticationManager.authenticate(authenticationToken);
+        }
+        catch (Exception e) {
+            if (e instanceof BadCredentialsException) {
+                throw new UserPasswordNotMatchException();          //抛出账号或者密码错误的异常
+            } else {
+                throw new ServiceException(e.getMessage());         //抛出其他异常
+            }
+        } finally {
+            AuthenticationContextHolder.clearContext();
+        }
+        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
+        recordAppLoginInfo(loginUser.getUserId());                     //修改sys_user最近登录IP和登录时间
+        // 生成不过期的token
+        return tokenService.createNotExpireToken(loginUser);
+    }
 }
diff --git a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java
index 6728c7b..8868d11 100644
--- a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java
+++ b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java
@@ -1,6 +1,8 @@
 package com.ruoyi.framework.web.service;
 
 import java.util.concurrent.TimeUnit;
+
+import com.ruoyi.common.core.domain.entity.AsUser;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.core.Authentication;
@@ -15,7 +17,7 @@ import com.ruoyi.framework.security.context.AuthenticationContextHolder;
 
 /**
  * 登录密码方法
- * 
+ *
  * @author ruoyi
  */
 @Component
@@ -32,7 +34,7 @@ public class SysPasswordService
 
     /**
      * 登录账户密码错误次数缓存键名
-     * 
+     *
      * @param username 用户名
      * @return 缓存键key
      */
@@ -71,11 +73,46 @@ public class SysPasswordService
         }
     }
 
+    public void validate2(AsUser user)
+    {
+        Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
+        String username = usernamePasswordAuthenticationToken.getName();
+        String password = usernamePasswordAuthenticationToken.getCredentials().toString();
+
+        Integer retryCount = redisCache.getCacheObject(getCacheKey(username));
+
+        if (retryCount == null)
+        {
+            retryCount = 0;
+        }
+
+        if (retryCount >= Integer.valueOf(maxRetryCount).intValue())
+        {
+            throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime);
+        }
+
+        if (!matches2(user, password))
+        {
+            retryCount = retryCount + 1;
+            redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
+            throw new UserPasswordNotMatchException();
+        }
+        else
+        {
+            clearLoginRecordCache(username);
+        }
+    }
+
     public boolean matches(SysUser user, String rawPassword)
     {
         return SecurityUtils.matchesPassword(rawPassword, user.getPassword());
     }
 
+    public boolean matches2(AsUser user, String rawPassword)
+    {
+        return SecurityUtils.matchesPassword(rawPassword, user.getPassword());
+    }
+
     public void clearLoginRecordCache(String loginName)
     {
         if (redisCache.hasKey(getCacheKey(loginName)))
diff --git a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
index 5c2f6b0..8209e3f 100644
--- a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
+++ b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
@@ -125,6 +125,24 @@ public class TokenService
         return createToken(claims);
     }
 
+    /**
+     * 创建令牌
+     *
+     * @param loginUser 用户信息
+     * @return 令牌
+     */
+    public String createNotExpireToken(LoginUser loginUser)
+    {
+        String token = IdUtils.fastUUID();
+        loginUser.setToken(token);
+        setUserAgent(loginUser);
+        saveNotExpireToken(loginUser);// 保存不过期的令牌信息
+
+        Map<String, Object> claims = new HashMap<>();
+        claims.put(Constants.NOT_EXPIRE_USER_KEY, token);
+        return createToken(claims);
+    }
+
     /**
      * 验证令牌有效期,相差不足20分钟,自动刷新缓存
      *
@@ -155,6 +173,15 @@ public class TokenService
         redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
     }
 
+    private void saveNotExpireToken(LoginUser loginUser)
+    {
+        loginUser.setLoginTime(System.currentTimeMillis());
+        // 不设置过期时间
+        String userKey = getNotExpireTokenKey(loginUser.getToken());
+        redisCache.setCacheObject(userKey, loginUser);
+    }
+
+
     /**
      * 设置用户代理信息
      *
@@ -231,6 +258,11 @@ public class TokenService
         return CacheConstants.LOGIN_TOKEN_KEY + uuid;
     }
 
+    private String getNotExpireTokenKey(String uuid)
+    {
+        return CacheConstants.LOGIN_NOT_EXPIRE_TOKEN_KEY + uuid;
+    }
+
     private String getAppTokenKey(String uuid)
     {
         return CacheConstants.APP_LOGIN_TOKEN_KEY + uuid;
diff --git a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java
index cfc5a8e..f051ebf 100644
--- a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java
+++ b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java
@@ -1,12 +1,15 @@
 package com.ruoyi.framework.web.service;
 
+import cn.hutool.core.util.StrUtil;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.domain.entity.AsUser;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.framework.security.context.AuthenticationContextHolder;
 import com.ruoyi.system.service.IAsUserService;
 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.security.core.Authentication;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetailsService;
@@ -44,6 +47,9 @@ public class UserDetailsServiceImpl implements UserDetailsService
     @Autowired
     private SysPermissionService permissionService;
 
+    @Value("${wx.appid}")
+    private String appId;
+
     @Override
     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
     {
@@ -73,7 +79,7 @@ public class UserDetailsServiceImpl implements UserDetailsService
                 passwordService.validate(user);
 
                 return createLoginUser(user);
-            }else {
+            }else if(Constants.USER_TYPE_APP.equals(userType)){
                 // app用户登录 如果是app用户则用openid查询
                 AsUser user = asUserService.selectUserByWxopenid(username);
                 if (StringUtils.isNull(user))
@@ -91,6 +97,37 @@ public class UserDetailsServiceImpl implements UserDetailsService
                     log.info("登录用户:{} 已被停用.", username);
                     throw new ServiceException(MessageUtils.message("user.blocked"));
                 }
+                UserDetails loginUser = createLoginUser(user);
+                return loginUser;
+            }else{
+                // app用户登录(短信登录) 如果是app用户则用手机号
+                AsUser user = asUserService.selectUserByPhoneAndAppId(username,appId);
+                if (StringUtils.isNull(user))
+                {
+                    log.info("登录用户:{} 不存在.", username);
+                    throw new ServiceException(MessageUtils.message("user.not.exists"));
+                }
+                else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
+                {
+                    log.info("登录用户:{} 已被删除.", username);
+                    throw new ServiceException(MessageUtils.message("user.password.delete"));
+                }
+                else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
+                {
+                    log.info("登录用户:{} 已被停用.", username);
+                    throw new ServiceException(MessageUtils.message("user.blocked"));
+                }
+
+                if(Constants.USER_TYPE_PASSWORD.equals(userType)){
+                    if(StrUtil.isBlank(user.getPassword())){
+                        String password = authentication.getCredentials().toString();
+                        String newPassword = SecurityUtils.encryptPassword(password);
+                        asUserService.updateUserPwd(user.getUserId(), newPassword);
+                    }else{
+                        passwordService.validate2(user);
+                    }
+                }
+
                 UserDetails loginUser = createLoginUser(user);
                 return loginUser;
             }
diff --git a/electripper-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml b/electripper-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml
index 5605c44..9ffeefd 100644
--- a/electripper-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml
+++ b/electripper-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml
@@ -19,12 +19,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		<result property="updateTime"     column="update_time"     />
 		<result property="remark"         column="remark"          />
 	</resultMap>
-	
+
 	<sql id="selectJobVo">
-        select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark 
+        select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark
 		from sys_job
     </sql>
-	
+
 	<select id="selectJobList" parameterType="SysJob" resultMap="SysJobResult">
 		<include refid="selectJobVo"/>
 		<where>
@@ -42,27 +42,27 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 			</if>
 		</where>
 	</select>
-	
+
 	<select id="selectJobAll" resultMap="SysJobResult">
 		<include refid="selectJobVo"/>
 	</select>
-	
+
 	<select id="selectJobById" parameterType="Long" resultMap="SysJobResult">
 		<include refid="selectJobVo"/>
 		where job_id = #{jobId}
 	</select>
-	
+
 	<delete id="deleteJobById" parameterType="Long">
  		delete from sys_job where job_id = #{jobId}
  	</delete>
- 	
+
  	<delete id="deleteJobByIds" parameterType="Long">
  		delete from sys_job where job_id in
  		<foreach collection="array" item="jobId" open="(" separator="," close=")">
  			#{jobId}
-        </foreach> 
+        </foreach>
  	</delete>
- 	
+
  	<update id="updateJob" parameterType="SysJob">
  		update sys_job
  		<set>
@@ -79,7 +79,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  		</set>
  		where job_id = #{jobId}
 	</update>
- 	
+
  	<insert id="insertJob" parameterType="SysJob" useGeneratedKeys="true" keyProperty="jobId">
  		insert into sys_job(
  			<if test="jobId != null and jobId != 0">job_id,</if>
@@ -108,4 +108,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  		)
 	</insert>
 
-</mapper> 
\ No newline at end of file
+</mapper>
diff --git a/electripper-system/src/main/java/com/ruoyi/system/domain/AsDevice.java b/electripper-system/src/main/java/com/ruoyi/system/domain/AsDevice.java
index 4f27401..7b7ea44 100644
--- a/electripper-system/src/main/java/com/ruoyi/system/domain/AsDevice.java
+++ b/electripper-system/src/main/java/com/ruoyi/system/domain/AsDevice.java
@@ -158,6 +158,11 @@ public class AsDevice extends BaseEntityPlus implements Serializable {
     @Excel(name = "硬件版本id")
     private Long hardwareVersionId;
 
+    /** 硬件版本 */
+    @Excel(name = "硬件版本")
+    @TableField(exist = false)
+    private String hardwareVersion;
+
     /** 型号 */
     @Excel(name = "型号")
     @TableField(exist = false)
diff --git a/electripper-system/src/main/java/com/ruoyi/system/mapper/AsUserMapper.java b/electripper-system/src/main/java/com/ruoyi/system/mapper/AsUserMapper.java
index a316fb3..468b7b5 100644
--- a/electripper-system/src/main/java/com/ruoyi/system/mapper/AsUserMapper.java
+++ b/electripper-system/src/main/java/com/ruoyi/system/mapper/AsUserMapper.java
@@ -135,6 +135,15 @@ public interface AsUserMapper
      */
     public AsUser selectUserByPhone(String phone);
 
+    /**
+     * 通过用户手机号和appid查询用户
+     *
+     * @param phone 手机号
+     * @param appid appid
+     * @return 用户对象信息
+     */
+    public AsUser selectUserByPhoneAndAppId(@Param("phone") String phone, @Param("appid") String appid);
+
     AsUser selectUserByWxopenid(String openid);
 
     /**
@@ -161,4 +170,9 @@ public interface AsUserMapper
      * 获取用户总数
      */
     Integer selectAllCount(@Param("timeStart") String timeStart, @Param("timeEnd") String timeEnd);
+
+    /**
+     * 更新用户密码
+     */
+    int updateUserPwd(@Param("userId") Long userId, @Param("password") String password);
 }
diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/IAsUserService.java b/electripper-system/src/main/java/com/ruoyi/system/service/IAsUserService.java
index 0c2da42..8889328 100644
--- a/electripper-system/src/main/java/com/ruoyi/system/service/IAsUserService.java
+++ b/electripper-system/src/main/java/com/ruoyi/system/service/IAsUserService.java
@@ -179,6 +179,14 @@ public interface IAsUserService
      */
     AsUser selectUserByPhone(String phone);
 
+    /**
+     * 通过用户手机号和appid查询用户
+     *
+     * @param phone 手机号
+     * @return 用户对象信息
+     */
+    AsUser selectUserByPhoneAndAppId(String phone, String appid);
+
     /**
      * 通过openid查询用户
      *
@@ -230,4 +238,9 @@ public interface IAsUserService
      * 根据手机号快速搜索用户列表
      */
     List<LabelVo> fastSearch(String phonenumber);
+
+    /**
+     * 修改用户密码
+     */
+    void updateUserPwd(Long userId, String newPassword);
 }
diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/AsUserServiceImpl.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/AsUserServiceImpl.java
index c001e10..80fd45a 100644
--- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/AsUserServiceImpl.java
+++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/AsUserServiceImpl.java
@@ -436,6 +436,17 @@ public class AsUserServiceImpl implements IAsUserService
         return asUserMapper.selectUserByPhone(phone);
     }
 
+    /**
+     * 通过用户手机号和appid查询用户
+     *
+     * @param phone 手机号
+     * @return 用户对象信息
+     */
+    @Override
+    public AsUser selectUserByPhoneAndAppId(String phone, String appid) {
+        return asUserMapper.selectUserByPhoneAndAppId(phone,appid);
+    }
+
     /**
      * 通过openid查询用户
      *
@@ -551,4 +562,12 @@ public class AsUserServiceImpl implements IAsUserService
         return users;
     }
 
+    /**
+     * 更新用户密码
+     */
+    @Override
+    public void updateUserPwd(Long userId, String newPassword) {
+        asUserMapper.updateUserPwd(userId, newPassword);
+    }
+
 }
diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java
index aacc0f3..6ea2558 100644
--- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java
+++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java
@@ -342,9 +342,13 @@ public class CallbackServiceImpl implements CallbackService {
                 throw new ServiceException("该运营商【"+sysDept.getDeptName()+"】未绑定微信用户");
             }
             AsUser asUser1 = asUserMapper.selectUserById(sysDept.getAppUserId());
+            AsDevice asDevice = asDeviceMapper.selectAsDeviceBySn(order.getSn());
 
             JSONObject jsonObject = new JSONObject();
-            jsonObject.put("orderNo", order.getOrderNo());
+            jsonObject.put("order", order.getOrderNo());
+            jsonObject.put("cheno", asDevice.getVehicleNum());
+            jsonObject.put("snno", order.getSn());
+            jsonObject.put("fee", order.getPayFee());
 
             String phone = asUser1.getPhonenumber();
             SendSmsVo sendSmsVo = new SendSmsVo();
@@ -368,7 +372,7 @@ public class CallbackServiceImpl implements CallbackService {
             // 短信日志
             EtMsgLog etMsgLog = new EtMsgLog();
             etMsgLog.setPhone(phone);
-            etMsgLog.setContent("您有一笔订单:"+order.getOrderNo()+",用户已付款,可在小程序管理端查看。");
+            etMsgLog.setContent("您的订单:"+order.getOrderNo()+",车牌:"+asDevice.getVehicleNum()+",SN:"+order.getSn()+",用户已付款"+order.getPayFee()+"元,可在小程序管理端查看。");
             etMsgLog.setType(ServiceConstants.MSG_TYPE_USER_PAYMENT_NOTIFY);
             etMsgLog.setSignName(signName);
             etMsgLog.setTemplateCode(templateCode);
diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
index b36f2b4..e21ddc5 100644
--- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
+++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
@@ -97,8 +97,8 @@ public class SysDeptServiceImpl implements ISysDeptService
     @Value("${aliyun.signName}")
     private String signName;
 
-    @Value("${aliyun.templateCode}")
-    private String templateCode;
+    @Value("${aliyun.templateCode3}")
+    private String templateCode3;
 
     @Value("${aliyun.phone}")
     private String phone;
@@ -311,6 +311,17 @@ public class SysDeptServiceImpl implements ISysDeptService
             SysDept platform = deptMapper.selectDeptById(100L);
             dept.setAppid(platform.getAppid());
             dept.setAppSecret(platform.getAppSecret());
+            dept.setAppName(platform.getAppName());
+            dept.setDomain(platform.getDomain());
+        }
+        if (dept.getSeparateAccount().equals("N")) {
+            SysDept platform = deptMapper.selectDeptById(100L);
+            dept.setMerchantId(platform.getMerchantId());
+            dept.setApiV3Key(platform.getApiV3Key());
+            dept.setNotifyUrl(platform.getNotifyUrl());
+            dept.setPrivateKeyPath(platform.getPrivateKeyPath());
+            dept.setMerchantSerialNumber(platform.getMerchantSerialNumber());
+            dept.setRefundNotifyUrl(platform.getRefundNotifyUrl());
         }
         int i = deptMapper.insertDept(dept);
         Long[] areaIds = dept.getAreaIds();
@@ -539,7 +550,7 @@ public class SysDeptServiceImpl implements ISysDeptService
 
             SendSmsVo sendSmsVo = new SendSmsVo();
             sendSmsVo.setMobile(phone);
-            sendSmsVo.setTemplateCode(templateCode);
+            sendSmsVo.setTemplateCode(templateCode3);
             sendSmsVo.setParam(jsonObject.toJSONString());
             sendSmsVo.setSignName(signName);
             SendSmsResponse response = null;
@@ -554,10 +565,10 @@ public class SysDeptServiceImpl implements ISysDeptService
             // 短信日志
             EtMsgLog etMsgLog = new EtMsgLog();
             etMsgLog.setPhone(phone);
-            etMsgLog.setContent("运营商【"+deptName+"】有一笔提现申请,请注意查收!");
+            etMsgLog.setContent("用户"+deptName+",发起押金提现申请,请尽快审核!");
             etMsgLog.setType("2");
             etMsgLog.setSignName(signName);
-            etMsgLog.setTemplateCode(templateCode);
+            etMsgLog.setTemplateCode(templateCode3);
             int i = etMsgLogMapper.insertEtMsgLog(etMsgLog);
             if(i>0){
                 log.info("【提现申请】短信日志记录成功");
diff --git a/electripper-system/src/main/java/com/ruoyi/system/task/EtTask.java b/electripper-system/src/main/java/com/ruoyi/system/task/EtTask.java
index fb268bc..4c0d81f 100644
--- a/electripper-system/src/main/java/com/ruoyi/system/task/EtTask.java
+++ b/electripper-system/src/main/java/com/ruoyi/system/task/EtTask.java
@@ -1,8 +1,8 @@
 package com.ruoyi.system.task;
 
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson2.JSON;
-import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.constant.ServiceConstants;
 import com.ruoyi.common.core.domain.entity.AsUser;
@@ -10,7 +10,7 @@ import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.DateUtils;
-import com.ruoyi.common.utils.spring.SpringUtils;
+import com.ruoyi.common.utils.map.GeoUtils;
 import com.ruoyi.common.utils.uuid.IdUtils;
 import com.ruoyi.system.domain.*;
 import com.ruoyi.system.mapper.AsDeviceMapper;
@@ -30,7 +30,10 @@ import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
-import java.util.*;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.IntStream;
@@ -369,4 +372,28 @@ public class EtTask {
         }
     }
 
+    /**
+     *  开始骑行未结束的订单,10秒算一次距离
+     *  cron: 0 5 0 * * ?
+     */
+    public void computeDistance(){
+        log.info("-------------------【定时任务】计算订单距离开始-------------------");
+        EtOrder order = new EtOrder();
+        order.setType("1");
+        order.setStatus(ServiceConstants.ORDER_STATUS_RIDING);
+        List<EtOrder> orders = etOrderService.selectEtOrderList(order);
+        for(EtOrder etOrder:orders){
+            String tripRouteStr = etOrder.getTripRouteStr();
+            if(StrUtil.isNotBlank(tripRouteStr)){
+                double[][] doubles = GeoUtils.parseJsonTrack(tripRouteStr);
+                double v = GeoUtils.calculateTotalDistance(doubles);
+                etOrder.setDistance((int)Math.round(v));
+                int updateEtOrder = etOrderService.updateEtOrder(etOrder);
+                if(updateEtOrder>0){
+                    log.info("【定时任务】计算订单距离成功:【orderNo="+etOrder.getOrderNo()+"】");
+                }
+            }
+        }
+    }
+
 }
diff --git a/electripper-system/src/main/resources/mapper/system/AsDeviceMapper.xml b/electripper-system/src/main/resources/mapper/system/AsDeviceMapper.xml
index 3f2df8e..64491a2 100644
--- a/electripper-system/src/main/resources/mapper/system/AsDeviceMapper.xml
+++ b/electripper-system/src/main/resources/mapper/system/AsDeviceMapper.xml
@@ -70,6 +70,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         de.remaining_power, de.voltage, de.version, de.qrcode, de.longitude, de.latitude, de.is_area_out_outage, de.is_admin_unlocking, de.signal_strength, de.satellites, de.quality from et_device de
         left join et_area_dept ad on ad.area_id = de.area_id
         left join sys_dept d on d.dept_id = ad.dept_id
+        left join et_hardware_version hv on hv.id = de.hardware_version_id
         where 1 = 1
         <if test="deviceName != null  and deviceName != ''"> and de.device_name like concat('%', #{deviceName}, '%')</if>
         <if test="mac != null  and mac != ''"> and de.mac like concat('%', #{mac}, '%')</if>
@@ -79,7 +80,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <if test="deptId != null "> and d.dept_id = #{deptId}</if>
         <if test="modelId != null  and modelId != ''"> and de.model_id = #{modelId}</if>
         <if test="onlineStatus != null  and onlineStatus != ''"> and de.online_status = #{onlineStatus}</if>
-<!--        <if test="status != null  and status != ''"> and de.status = #{status}</if>-->
+        <if test="version != null  and version != ''"> and de.version = #{version}</if>
+        <if test="hardwareVersion != null  and hardwareVersion != ''"> and hv.version like concat('%', #{hardwareVersion}, '%') </if>
         <choose>
             <when test="status == '34'">
                 and (de.status = '3' or de.status = '4')
diff --git a/electripper-system/src/main/resources/mapper/system/AsUserMapper.xml b/electripper-system/src/main/resources/mapper/system/AsUserMapper.xml
index 676ae30..c9512e5 100644
--- a/electripper-system/src/main/resources/mapper/system/AsUserMapper.xml
+++ b/electripper-system/src/main/resources/mapper/system/AsUserMapper.xml
@@ -34,20 +34,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="areaId"       column="area_id"       />
         <result property="isAuthentication"       column="is_authentication"       />
         <result property="appName"       column="app_name"       />
+        <result property="appId"       column="appid"       />
     </resultMap>
 
 	<sql id="selectUserVo">
         select u.user_id, u.user_name, u.real_name, u.id_card, u.nick_name, u.email, u.avatar,
                u.phonenumber, u.balance, u.birthday, u.password, u.pay_password, u.sex, u.status,
                u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,u.wxopenid,
-               u.is_sign,u.role,u.sys_user_id,u.area_id,u.is_authentication,u.app_name
+               u.is_sign,u.role,u.sys_user_id,u.area_id,u.is_authentication,u.app_name,u.appid
         from et_user u
     </sql>
 
     <select id="selectUserList" parameterType="AsUser" resultMap="AsUserResult">
 		select u.user_id, u.nick_name, u.user_name, u.real_name,u.email, u.avatar, u.phonenumber, u.balance,
 		       u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
-		       u.wxopenid,u.is_sign,u.role,u.sys_user_id,u.area_id,u.is_authentication,u.app_name from et_user u
+		       u.wxopenid,u.is_sign,u.role,u.sys_user_id,u.area_id,u.is_authentication,u.app_name,u.appid from et_user u
 		where u.del_flag = '0'
 		<if test="userId != null and userId != 0">
 			AND u.user_id = #{userId}
@@ -124,6 +125,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		where u.phonenumber = #{phonenumber}
 	</select>
 
+	<select id="selectUserByPhoneAndAppId" parameterType="String" resultMap="AsUserResult">
+		<include refid="selectUserVo"/>
+		where u.phonenumber = #{phone} and u.appid = #{appid}
+	</select>
+
 	<select id="selectUserByWxopenid" parameterType="String" resultMap="AsUserResult">
 		<include refid="selectUserVo"/>
 		where u.wxopenid = #{openid}
@@ -193,6 +199,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			<if test="areaId != null">area_id,</if>
  			<if test="isAuthentication != null">is_authentication,</if>
  			<if test="appName != null and appName != ''">app_name,</if>
+ 			<if test="appId != null and appId != ''">appid,</if>
  			create_time
  		)values(
  			<if test="userId != null and userId != ''">#{userId},</if>
@@ -216,6 +223,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			<if test="areaId != null">#{areaId},</if>
  			<if test="isAuthentication != null">#{isAuthentication},</if>
  			<if test="appName != null and appName != ''">#{appName},</if>
+ 			<if test="appId != null and appId != ''">#{appId},</if>
  			sysdate()
  		)
 	</insert>
@@ -245,6 +253,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			<if test="areaId != null">area_id = #{areaId},</if>
  			<if test="isAuthentication != null">is_authentication = #{isAuthentication},</if>
  			<if test="appName != null">app_name = #{appName},</if>
+ 			<if test="appId != null">appid = #{appId},</if>
  			update_time = sysdate()
  		</set>
  		where user_id = #{userId}
@@ -262,6 +271,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  		update et_user set password = #{password} where user_name = #{userName}
 	</update>
 
+	<update id="updateUserPwd">
+		update et_user set password = #{password} where  user_id = #{userId}
+	</update>
+
 	<delete id="deleteUserById" parameterType="Long">
  		update et_user set del_flag = '2' where user_id = #{userId}
  	</delete>
diff --git a/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml b/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml
index c2f3154..7e15e0d 100644
--- a/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml
+++ b/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml
@@ -170,7 +170,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			<if test="merchantSerialNumber != null and merchantSerialNumber != ''">merchant_serial_number,</if>
  			<if test="refundNotifyUrl != null and refundNotifyUrl != ''">refund_notify_url,</if>
 		    <if test="appUserId != null and appUserId != ''">app_user_id,</if>
-		    <if test="handlingChargeType != null and handlingChargeType != ''">handling_charge_type,,</if>
+		    <if test="handlingChargeType != null and handlingChargeType != ''">handling_charge_type,</if>
  			create_time
  		)values(
  			<if test="deptId != null and deptId != 0">#{deptId},</if>