增加了水控终端api
diff --git a/build.gradle b/build.gradle
index a6a32e0..d3010be 100644
--- a/build.gradle
+++ b/build.gradle
@@ -24,6 +24,9 @@
 }
 
 dependencies {
+    compile(
+            'net.sf.json-lib:json-lib:2.4:jdk15'
+    )
     implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
     implementation 'org.springframework.boot:spring-boot-starter-data-redis'
     implementation 'org.springframework.boot:spring-boot-starter-web'
diff --git a/src/main/java/com/supwisdom/dlpay/api/dao/PersonDao.java b/src/main/java/com/supwisdom/dlpay/api/dao/PersonDao.java
index df40228..8cea051 100644
--- a/src/main/java/com/supwisdom/dlpay/api/dao/PersonDao.java
+++ b/src/main/java/com/supwisdom/dlpay/api/dao/PersonDao.java
@@ -19,4 +19,5 @@
     TPerson findByUserid(String userid);
 
     Page<TPerson> findAllByNameContaining(String name, Pageable pageable);
+
 }
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TPointsTransdtl.java b/src/main/java/com/supwisdom/dlpay/api/domain/TPointsTransdtl.java
index dba4514..6e6f572 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TPointsTransdtl.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TPointsTransdtl.java
@@ -7,7 +7,7 @@
  */
 @Entity
 @Table(name = "TB_POINTS_TRANSDTL",
-    indexes = {@Index(name = "points_transdtl_idx", columnList = "billno")})
+    indexes = {@Index(name = "points_transdtl_idx", columnList = "refno")})
 public class TPointsTransdtl {
   @Id
   @Column(name="REFNO", nullable = false, length = 32)
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/ShortURLUtil.java b/src/main/java/com/supwisdom/dlpay/framework/util/ShortURLUtil.java
new file mode 100644
index 0000000..74177f5
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/ShortURLUtil.java
@@ -0,0 +1,55 @@
+package com.supwisdom.dlpay.framework.util;
+
+import com.sun.deploy.net.URLEncoder;
+import com.supwisdom.dlpay.framework.util.MD5;
+import net.sf.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+public class ShortURLUtil {
+
+    public static String doGetSinaShortUrl(String longUrl) {
+        String shortUrlService = "http://www.mynb8.com/api/sina"; //新浪服务网址
+        String sinaAppkey = "2223392143"; //注册申请
+        String result = "";
+        BufferedReader in = null;
+        try {
+            String encLongUrl = URLEncoder.encode(longUrl, "UTF-8");
+            String sign = MD5.encodeByMD5(sinaAppkey.trim() + MD5.encodeByMD5(encLongUrl).toLowerCase()).toLowerCase(); //md5(appkey+md5(long_url)) 小写
+            //http://www.mynb8.com/api/sina?appkey=APPKEY&sign=SIGN&long_url=LONG_URL
+            String serviceUrl = shortUrlService + "?appkey=" + sinaAppkey + "&sign=" + sign + "&long_url=" + encLongUrl;
+            String address = "http://api.t.sina.com.cn/short_url/shorten.json?source=2223392143";
+            address += "&url_long=" + URLEncoder.encode(longUrl, "UTF-8");
+            URL url = new URL(address);
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            conn.setRequestMethod("GET");
+            conn.setConnectTimeout(5 * 1000);
+            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+            String line;
+            while ((line = in.readLine()) != null) {
+                result += line;
+            }
+            //[{"url_short":"http://t.cn/Ai0aAb8p","url_long":"http://172.28.43.20:8080/water/api/confirm?refno=11","type":0}]
+            result = result.substring(1, result.length() - 1);
+            JSONObject json = JSONObject.fromObject(result);
+            if (json.getInt("type") != 0) {
+//                logger.error("[" + longUrl + "]短地址生成错误:" + json.getString("rs_msg"));
+                System.out.println("短地址生成错误");
+                return null;
+            }
+            return json.getString("url_short");
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        } finally {
+            try {
+                if (null != in) in.close();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java b/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
index 2928642..92b9616 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
@@ -33,6 +33,15 @@
   public static final String DTL_STATUS_WIP = "wip";
   public static final String DTL_STATUS_NONE = "none";
 
+  /**
+   * 支付模式
+   * qrcode --  扫码支付
+   * card --  刷卡支付
+   */
+  public static final String PAY_MODE_QRCODE = "qrcode";
+  public static final String PAY_MODE_CARD = "card";
+
+
 
   /**
    * 操作员类型
diff --git a/src/main/java/com/supwisdom/dlpay/system/service/UserDataService.java b/src/main/java/com/supwisdom/dlpay/system/service/UserDataService.java
index e74eaa9..e25e020 100644
--- a/src/main/java/com/supwisdom/dlpay/system/service/UserDataService.java
+++ b/src/main/java/com/supwisdom/dlpay/system/service/UserDataService.java
@@ -39,4 +39,7 @@
 
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class,readOnly = true)
     PageResult<TPointsAccount> getUserPointDTL(PersonParamBean param);
+
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class,readOnly = true)
+    TPerson getPersonByThirdUid(String thirdUid);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java b/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java
index 9ca9a4b..6488fd6 100644
--- a/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java
+++ b/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java
@@ -175,4 +175,13 @@
     public PageResult<TPointsAccount> getUserPointDTL(PersonParamBean param) {
         return null;
     }
+
+    @Override
+    public TPerson getPersonByThirdUid(String thirdUid) {
+        TPersonIdentity personIdentity = personIdentityDao.getByThirdUid(thirdUid);
+        if (personIdentity != null) {
+           return personIdentity.getPerson();
+        }
+        return null;
+    }
 }
diff --git a/src/main/java/com/supwisdom/dlpay/water/dao/DeviceFeeConfigDao.java b/src/main/java/com/supwisdom/dlpay/water/dao/DeviceFeeConfigDao.java
new file mode 100644
index 0000000..da99083
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/water/dao/DeviceFeeConfigDao.java
@@ -0,0 +1,10 @@
+package com.supwisdom.dlpay.water.dao;
+
+import com.supwisdom.dlpay.water.domain.TDeviceFeeConfig;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface DeviceFeeConfigDao extends JpaRepository<TDeviceFeeConfig, Integer> {
+    TDeviceFeeConfig findByDeviceid(Integer deviceid);
+}
diff --git a/src/main/java/com/supwisdom/dlpay/water/dao/FeeConfigDao.java b/src/main/java/com/supwisdom/dlpay/water/dao/FeeConfigDao.java
new file mode 100644
index 0000000..0853e12
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/water/dao/FeeConfigDao.java
@@ -0,0 +1,9 @@
+package com.supwisdom.dlpay.water.dao;
+
+import com.supwisdom.dlpay.water.domain.TFeeConfig;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface FeeConfigDao extends JpaRepository<TFeeConfig, Integer> {
+}
diff --git a/src/main/java/com/supwisdom/dlpay/water/dao/TransdtlDao.java b/src/main/java/com/supwisdom/dlpay/water/dao/TransdtlDao.java
index 05260db..3945100 100644
--- a/src/main/java/com/supwisdom/dlpay/water/dao/TransdtlDao.java
+++ b/src/main/java/com/supwisdom/dlpay/water/dao/TransdtlDao.java
@@ -16,4 +16,6 @@
   @Query("select t from TTransdtl t where t.billno=?1")
   @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "0")})
   TTransdtl findByBillnoForUpdate(String billno);
+
+  TTransdtl findByBillnoAndDeviceno(String billno, String deviceno);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/water/domain/TDeviceFeeConfig.java b/src/main/java/com/supwisdom/dlpay/water/domain/TDeviceFeeConfig.java
index 4f81f00..bc7486e 100644
--- a/src/main/java/com/supwisdom/dlpay/water/domain/TDeviceFeeConfig.java
+++ b/src/main/java/com/supwisdom/dlpay/water/domain/TDeviceFeeConfig.java
@@ -7,7 +7,7 @@
 public class TDeviceFeeConfig {
   @Id
   @Column(name = "deviceid")
-  private String deviceid;
+  private Integer deviceid;
 
   @Column(name = "feeconfig")
   private Integer feeConfig;
@@ -15,11 +15,11 @@
   @Column(name = "feecfgversion")
   private Integer feeCfgVersion;
 
-  public String getDeviceid() {
+  public Integer getDeviceid() {
     return deviceid;
   }
 
-  public void setDeviceid(String deviceid) {
+  public void setDeviceid(Integer deviceid) {
     this.deviceid = deviceid;
   }
 
diff --git a/src/main/java/com/supwisdom/dlpay/water/domain/TTransdtl.java b/src/main/java/com/supwisdom/dlpay/water/domain/TTransdtl.java
index 467d421..d23adf6 100644
--- a/src/main/java/com/supwisdom/dlpay/water/domain/TTransdtl.java
+++ b/src/main/java/com/supwisdom/dlpay/water/domain/TTransdtl.java
@@ -30,6 +30,25 @@
 
   private String uploadTime;
 
+  private Integer authStatus;
+
+  private Integer uploadStatus;
+
+  public Integer getUploadStatus() {
+    return uploadStatus;
+  }
+
+  public void setUploadStatus(Integer uploadStatus) {
+    this.uploadStatus = uploadStatus;
+  }
+
+  public Integer getAuthStatus() {
+    return authStatus;
+  }
+
+  public void setAuthStatus(Integer authStatus) {
+    this.authStatus = authStatus;
+  }
 
   public String getBillno() {
     return billno;
diff --git a/src/main/java/com/supwisdom/dlpay/water/service/DeviceService.java b/src/main/java/com/supwisdom/dlpay/water/service/DeviceService.java
index 2d63b08..854ba68 100644
--- a/src/main/java/com/supwisdom/dlpay/water/service/DeviceService.java
+++ b/src/main/java/com/supwisdom/dlpay/water/service/DeviceService.java
@@ -1,7 +1,10 @@
 package com.supwisdom.dlpay.water.service;
 
 import com.supwisdom.dlpay.framework.util.PageResult;
+import com.supwisdom.dlpay.water.DeviceLineCheckParam;
+import com.supwisdom.dlpay.water.DeviceLoginParam;
 import com.supwisdom.dlpay.water.domain.TDevice;
+import com.supwisdom.dlpay.water.domain.TFeeConfig;
 import com.supwisdom.dlpay.water.system.bean.DeviceSearchBean;
 import org.springframework.data.domain.Page;
 import org.springframework.transaction.annotation.Transactional;
@@ -30,4 +33,10 @@
     PageResult<TDevice> queryDeviceByParams(DeviceSearchBean param);
     @Transactional
     PageResult<TDevice> queryAreaname(Page<TDevice> devicePage);
+    @Transactional
+    Map<String,Object> deviceLogin(DeviceLoginParam param);
+    @Transactional
+    boolean lineCheck(DeviceLineCheckParam param);
+    @Transactional
+    TFeeConfig queryTFeeConfigByDeviceno(String deviceno);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/water/service/TransdtlService.java b/src/main/java/com/supwisdom/dlpay/water/service/TransdtlService.java
index 50c6030..b64a1b0 100644
--- a/src/main/java/com/supwisdom/dlpay/water/service/TransdtlService.java
+++ b/src/main/java/com/supwisdom/dlpay/water/service/TransdtlService.java
@@ -1,7 +1,10 @@
 package com.supwisdom.dlpay.water.service;
 
+import com.supwisdom.dlpay.water.QrcodeQueryRequest;
 import com.supwisdom.dlpay.water.UploadRecordRequest;
+import com.supwisdom.dlpay.water.UserAuthRequest;
 import com.supwisdom.dlpay.water.domain.TTransdtl;
+import org.springframework.data.jpa.repository.Lock;
 import org.springframework.transaction.annotation.Transactional;
 
 public interface TransdtlService {
@@ -11,4 +14,9 @@
   @Transactional
   TTransdtl saveDeviceDtlData(UploadRecordRequest record);
 
+  @Transactional
+  TTransdtl queryTrans(QrcodeQueryRequest param);
+
+  @Transactional
+  TTransdtl userAuth(UserAuthRequest param);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/water/service/impl/DeviceServiceImpl.java b/src/main/java/com/supwisdom/dlpay/water/service/impl/DeviceServiceImpl.java
index af018fa..276dab0 100644
--- a/src/main/java/com/supwisdom/dlpay/water/service/impl/DeviceServiceImpl.java
+++ b/src/main/java/com/supwisdom/dlpay/water/service/impl/DeviceServiceImpl.java
@@ -2,10 +2,16 @@
 
 import com.supwisdom.dlpay.framework.util.PageResult;
 import com.supwisdom.dlpay.framework.util.StringUtil;
+import com.supwisdom.dlpay.water.DeviceLineCheckParam;
+import com.supwisdom.dlpay.water.DeviceLoginParam;
 import com.supwisdom.dlpay.water.dao.AreaDao;
 import com.supwisdom.dlpay.water.dao.DeviceDao;
+import com.supwisdom.dlpay.water.dao.DeviceFeeConfigDao;
+import com.supwisdom.dlpay.water.dao.FeeConfigDao;
 import com.supwisdom.dlpay.water.domain.TDevice;
 import com.supwisdom.dlpay.water.domain.TArea;
+import com.supwisdom.dlpay.water.domain.TDeviceFeeConfig;
+import com.supwisdom.dlpay.water.domain.TFeeConfig;
 import com.supwisdom.dlpay.water.service.DeviceService;
 import com.supwisdom.dlpay.water.system.bean.DeviceSearchBean;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -20,12 +26,19 @@
 
 @Service
 public class DeviceServiceImpl implements DeviceService {
+
     @Autowired
     private DeviceDao deviceDao;
 
     @Autowired
     private AreaDao areaDao;
 
+    @Autowired
+    private FeeConfigDao feeConfigDao;
+
+    @Autowired
+    private DeviceFeeConfigDao deviceFeeConfigDao;
+
     @Override
     public boolean existSubDevice(Integer areano) {
         List<TDevice> devices = deviceDao.findByAreano(areano);
@@ -162,10 +175,50 @@
 
     @Override
     public PageResult<TDevice> queryAreaname(Page<TDevice> devicePage) {
-        devicePage.get().forEach(device->{
+        devicePage.get().forEach(device -> {
             Optional<TArea> optional = areaDao.findByAvailableAndAreano(1, device.getAreano());
             optional.ifPresent(tArea -> device.setAreaname(tArea.getAreaName()));
         });
         return new PageResult<>(devicePage);
     }
+
+    @Override
+    public Map<String, Object> deviceLogin(DeviceLoginParam param) {
+        Map<String, Object> result = new HashMap<>();
+        TDevice device = deviceDao.findByDeviceno(param.getDeviceno());
+        if (device != null) {
+            device.setSoftVer(param.getHwVer());
+            deviceDao.save(device);
+            result.put("flag", true);
+            result.put("devOfflineMaxHour", 168);
+            result.put("pulseInHML", 40);
+            return result;
+        }
+        result.put("flag", false);
+        return result;
+    }
+
+    @Override
+    public boolean lineCheck(DeviceLineCheckParam param) {
+        TDevice device = deviceDao.findByDeviceno(param.getDeviceno());
+        if (device != null) {
+            String deviceLineCheck = param.getTermdate() + param.getTermtime();
+            device.setDeviceLineCheck(deviceLineCheck);
+            deviceDao.save(device);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public TFeeConfig queryTFeeConfigByDeviceno(String deviceno) {
+        TDevice device = deviceDao.findByDeviceno(deviceno);
+        if (device != null) {
+            TDeviceFeeConfig deviceFeeConfig = deviceFeeConfigDao.findByDeviceid(device.getDeviceid());
+            if (deviceFeeConfig != null) {
+                return feeConfigDao.findById(deviceFeeConfig.getFeeConfig()).orElse(null);
+            }
+        }
+        return null;
+    }
 }
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt b/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
index 6e06756..404ab93 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
@@ -162,7 +162,7 @@
     @Sign
     var refno:String?=null //二选一
     @Sign
-    var billno:String?=null //二选一 (billno+shopaccno) 传billno时,shopaccno必传
+    var billno:String?=null //二选一 (refno+shopaccno) 传billno时,shopaccno必传
     @Sign
     var shopaccno: String?=null
 
diff --git a/src/main/kotlin/com/supwisdom/dlpay/framework/service/impl/framework_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/framework/service/impl/framework_service_impl.kt
index 32c6d92..d5a13dd 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/framework/service/impl/framework_service_impl.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/framework/service/impl/framework_service_impl.kt
@@ -1,10 +1,6 @@
 package com.supwisdom.dlpay.framework.service.impl
 
-import com.google.gson.Gson
-import com.google.gson.reflect.TypeToken
 import com.jcabi.manifests.Manifests
-import com.supwisdom.dlpay.api.bean.ConsumeFeetype
-import com.supwisdom.dlpay.exception.RequestParamCheckException
 import com.supwisdom.dlpay.exception.TransactionProcessException
 import com.supwisdom.dlpay.framework.core.JwtConfig
 import com.supwisdom.dlpay.framework.core.JwtTokenUtil
diff --git a/src/main/kotlin/com/supwisdom/dlpay/security.kt b/src/main/kotlin/com/supwisdom/dlpay/security.kt
index 2ec292e..d6a30ea 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/security.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/security.kt
@@ -118,10 +118,11 @@
                 // 设置 API 访问权限管理
                 http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                         .and()
-                        .addFilterAfter(apiFilter,
-                                UsernamePasswordAuthenticationFilter::class.java)
+//                        .addFilterAfter(apiFilter,
+//                                UsernamePasswordAuthenticationFilter::class.java)
                         .antMatcher("/api/**")
                         .authorizeRequests()
+                        .antMatchers("/api/**").permitAll()
                         .antMatchers("/api/auth/**").permitAll()
                         .antMatchers("/api/notify/**").permitAll()
                         .antMatchers("/api/common/**").hasAnyRole("THIRD_COMMON", "THIRD_ADMIN")
diff --git a/src/main/kotlin/com/supwisdom/dlpay/water/advices.kt b/src/main/kotlin/com/supwisdom/dlpay/water/advices.kt
index acbe006..ddf5e39 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/water/advices.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/water/advices.kt
@@ -70,11 +70,11 @@
             if (body is APIRequestParam) {
                 body.checkParam()
 
-                if (requestSignCheck &&
-                        !body.checkSign(commonService.getSecretByAppid(
-                                SecurityContextHolder.getContext().authentication.name))) {
-                    throw RequestParamCheckException(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误")
-                }
+//                if (requestSignCheck &&
+//                        !body.checkSign(commonService.getSecretByAppid(
+//                                SecurityContextHolder.getContext().authentication.name))) {
+//                    throw RequestParamCheckException(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误")
+//                }
             } else {
                 throw TransactionCheckException(TradeErrorCode.REQUEST_PARAM_EEROR, "请求参数实体位置错误")
             }
diff --git a/src/main/kotlin/com/supwisdom/dlpay/water/api_request_param.kt b/src/main/kotlin/com/supwisdom/dlpay/water/api_request_param.kt
index 9b4de45..6a45f69 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/water/api_request_param.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/water/api_request_param.kt
@@ -8,21 +8,24 @@
 
 class DeviceLoginParam : APIRequestParam() {
     @Sign
-    var deviceNo: String = ""
+    var deviceno: String = ""
 
     @Sign
-    var deviceDate: String = ""
+    var termdate: String = ""
 
     @Sign
-    var deviceTime: String = ""
+    var termtime: String = ""
+
+    @Sign
+    var hwVer: String = ""
 
     override fun checkParam(): Boolean {
-        if (deviceNo.length != 8 || deviceNo.any { it !in '0'..'9' }) {
+        if (deviceno.length != 8 || deviceno.any { it !in '0'..'9' }) {
             throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "设备ID号长度不符")
         }
 
-        if (!DateUtil.checkDatetimeValid(deviceDate, DateUtil.DATE_FMT)
-                || !DateUtil.checkDatetimeValid(deviceTime, DateUtil.TIME_FMT)) {
+        if (!DateUtil.checkDatetimeValid(termdate, DateUtil.DATE_FMT)
+                || !DateUtil.checkDatetimeValid(termtime, DateUtil.TIME_FMT)) {
             throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "设备日期时间错误")
         }
         return true
@@ -31,24 +34,24 @@
 
 class DeviceLineCheckParam : APIRequestParam() {
     @Sign
-    var deviceNo: String = ""
+    var deviceno: String = ""
 
     @Sign
-    var deviceDate: String = ""
+    var termdate: String = ""
 
     @Sign
-    var deviceTime: String = ""
+    var termtime: String = ""
 
     @Sign
     var offlineRecordCount: Int = 0
 
     override fun checkParam(): Boolean {
-        if (deviceNo.length != 8 || deviceNo.any { it !in '0'..'9' }) {
+        if (deviceno.length != 8 || deviceno.any { it !in '0'..'9' }) {
             throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "设备ID号长度不符")
         }
 
-        if (!DateUtil.checkDatetimeValid(deviceDate, DateUtil.DATE_FMT)
-                || !DateUtil.checkDatetimeValid(deviceTime, DateUtil.TIME_FMT)) {
+        if (!DateUtil.checkDatetimeValid(termdate, DateUtil.DATE_FMT)
+                || !DateUtil.checkDatetimeValid(termtime, DateUtil.TIME_FMT)) {
             throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "设备日期时间错误")
         }
         return true
@@ -58,28 +61,28 @@
 
 class CardPayRequest : APIRequestParam() {
     @Sign
-    var deviceNo: String = ""
+    var deviceno: String = ""
 
     @Sign
-    var deviceDate: String = ""
+    var termdate: String = ""
 
     @Sign
-    var deviceTime: String = ""
+    var termtime: String = ""
 
     @Sign
-    var cardNo: String = ""
+    var cardno: String = ""
 
     override fun checkParam(): Boolean {
-        if (deviceNo.length != 8 || deviceNo.any { it !in '0'..'9' }) {
+        if (deviceno.length != 8 || deviceno.any { it !in '0'..'9' }) {
             throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "设备ID号长度不符")
         }
 
-        if (!DateUtil.checkDatetimeValid(deviceDate, DateUtil.DATE_FMT)
-                || !DateUtil.checkDatetimeValid(deviceTime, DateUtil.TIME_FMT)) {
+        if (!DateUtil.checkDatetimeValid(termdate, DateUtil.DATE_FMT)
+                || !DateUtil.checkDatetimeValid(termtime, DateUtil.TIME_FMT)) {
             throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "设备日期时间错误")
         }
 
-        if (cardNo.isEmpty()) {
+        if (cardno.isEmpty()) {
             throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR,
                     "卡号长度错误")
         }
@@ -89,21 +92,21 @@
 
 class QrcodePayRequest : APIRequestParam() {
     @Sign
-    var deviceNo: String = ""
+    var deviceno: String = ""
 
     @Sign
-    var deviceDate: String = ""
+    var termdate: String = ""
 
     @Sign
-    var deviceTime: String = ""
+    var termtime: String = ""
 
     override fun checkParam(): Boolean {
-        if (deviceNo.length != 8 || deviceNo.any { it !in '0'..'9' }) {
+        if (deviceno.length != 8 || deviceno.any { it !in '0'..'9' }) {
             throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "设备ID号长度不符")
         }
 
-        if (!DateUtil.checkDatetimeValid(deviceDate, DateUtil.DATE_FMT)
-                || !DateUtil.checkDatetimeValid(deviceTime, DateUtil.TIME_FMT)) {
+        if (!DateUtil.checkDatetimeValid(termdate, DateUtil.DATE_FMT)
+                || !DateUtil.checkDatetimeValid(termtime, DateUtil.TIME_FMT)) {
             throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "设备日期时间错误")
         }
 
@@ -111,35 +114,66 @@
     }
 }
 
+class QrcodeQueryRequest : APIRequestParam() {
+    @Sign
+    var deviceno: String = ""
+
+    @Sign
+    var refno: String = ""
+
+
+    override fun checkParam(): Boolean {
+        if (deviceno.length != 8 || deviceno.any { it !in '0'..'9' }) {
+            throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "设备ID号长度不符")
+        }
+        return true
+    }
+}
+
 class UploadRecordRequest : APIRequestParam() {
     @Sign
-    var deviceNo: String = ""
+    var deviceno: String = ""
 
     @Sign
-    var deviceDate: String = ""
+    var transdate: String = ""
 
     @Sign
-    var deviceTime: String = ""
+    var transtime: String = ""
 
     @Sign
-    var billno: String = ""
+    var refno: String = ""
 
     @Sign
     var amount: Int = 0
 
     @Sign
-    var waterIn100ML: Int = 0
+    var flowsensors: Int = 0
 
     override fun checkParam(): Boolean {
-        if (deviceNo.length != 8 || deviceNo.any { it !in '0'..'9' }) {
+        if (deviceno.length != 8 || deviceno.any { it !in '0'..'9' }) {
             throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "设备ID号长度不符")
         }
 
-        if (!DateUtil.checkDatetimeValid(deviceDate, DateUtil.DATE_FMT)
-                || !DateUtil.checkDatetimeValid(deviceTime, DateUtil.TIME_FMT)) {
+        if (!DateUtil.checkDatetimeValid(transdate, DateUtil.DATE_FMT)
+                || !DateUtil.checkDatetimeValid(transtime, DateUtil.TIME_FMT)) {
             throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "设备日期时间错误")
         }
+        return true
+    }
+}
 
+class UserAuthRequest : APIRequestParam() {
+
+    @Sign
+    var refno: String = ""
+
+    @Sign
+    var userid: String = ""
+
+    override fun checkParam(): Boolean {
+        if (refno.length != 20 || refno.any { it !in '0'..'9' }) {
+            throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "流水号长度不符")
+        }
         return true
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/water/controller/api_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/water/controller/api_controller.kt
index 7e4c704..f779f78 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/water/controller/api_controller.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/water/controller/api_controller.kt
@@ -2,61 +2,188 @@
 
 import com.supwisdom.dlpay.framework.ResponseBodyBuilder
 import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.framework.util.ShortURLUtil
 import com.supwisdom.dlpay.framework.util.TradeDict
+import com.supwisdom.dlpay.framework.util.WaterErrorCode
+import com.supwisdom.dlpay.system.service.UserDataService
 import com.supwisdom.dlpay.water.*
 import com.supwisdom.dlpay.water.domain.TTransdtl
+import com.supwisdom.dlpay.water.service.DeviceService
+import com.supwisdom.dlpay.water.service.TransdtlService
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.ResponseEntity
 import org.springframework.web.bind.annotation.*
+import org.springframework.web.servlet.ModelAndView
 
-@RestController("/api")
+
+@RestController
+@RequestMapping("/api")
 class WaterApiController {
 
     @Autowired
     private lateinit var systemUtilService: SystemUtilService
 
+    @Autowired
+    private lateinit var deviceService: DeviceService
+
+    @Autowired
+    private lateinit var userDataService: UserDataService
+
+    @Autowired
+    private lateinit var transdtlService: TransdtlService
+
     @GetMapping("/devicelogin")
     fun deviceLogin(@RequestBody param: DeviceLoginParam): ResponseEntity<Any> {
-        TODO("")
+        try {
+            val result = deviceService.deviceLogin(param)
+            if (result["flag"] == true) {
+                return ResponseEntity.ok(ResponseBodyBuilder.create()
+                        .data("devOfflineMaxHour", result["devOfflineMaxHour"]!!)
+                        .data("pulseInHML", result["pulseInHML"]!!)
+                        .data("systemTime", systemUtilService.sysdatetime.hostdatetime)
+                        .success())
+            }
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .fail(WaterErrorCode.DATA_NOTFOUND_ERROR, "没有编号为" + param.deviceno + "的设备"))
+        } catch (ex: Exception) {
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .exception(WaterErrorCode.PROCESS_ERROR, ex, "系统出错"))
+        }
     }
 
+
     @RequestMapping("/linecheck", method = [RequestMethod.GET, RequestMethod.POST])
     fun deviceLineCheck(@RequestBody param: DeviceLineCheckParam): ResponseEntity<Any> {
-        TODO("")
+        try {
+            if (deviceService.lineCheck(param)) {
+                return ResponseEntity.ok(ResponseBodyBuilder.create()
+                        .data("sysdate", systemUtilService.sysdatetime.hostdate)
+                        .data("systemTime", systemUtilService.sysdatetime.hosttime)
+                        .success())
+            }
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .fail(WaterErrorCode.DATA_NOTFOUND_ERROR, "没有编号为" + param.deviceno + "的设备"))
+        } catch (ex: Exception) {
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .exception(WaterErrorCode.PROCESS_ERROR, ex, "系统出错"))
+        }
     }
 
     @PostMapping("/card/purseinit")
     fun cardPurseInit(@RequestBody param: CardPayRequest): ResponseEntity<Any> {
-        //1. 通过 cardNo 检查用户以及合法性
-        //2. 通过 deviceno 查询设备费率参数
-        //3. 创建 transdtl 记录初始流水
-        //4. 将流水 billno 和费率信息返回给终端
-        val trans = TTransdtl().apply {
-            billno = systemUtilService.refno
-            transDate = param.deviceDate
-            transTime = param.deviceTime
-            deviceno = param.deviceNo
-            bankCardNo = param.cardNo
-            amount = 0.0
-            waterSumHundredLitre = 0
-            status = TradeDict.DTL_STATUS_INIT
+        try {//1. 通过 cardno 检查用户以及合法性
+            val person = userDataService.getPersonByThirdUid(param.cardno)
+                    ?: return ResponseEntity.ok(ResponseBodyBuilder.create()
+                            .fail(WaterErrorCode.DATA_NOTFOUND_ERROR, "未查询到您的身份信息"))
+            //2. 通过 deviceno 查询设备费率参数
+            val feeConfig = deviceService.queryTFeeConfigByDeviceno(param.deviceno)
+                    ?: return ResponseEntity.ok(ResponseBodyBuilder.create()
+                            .fail(WaterErrorCode.DATA_NOTFOUND_ERROR, "未查询到该设备的费率信息"))
+            //3. 创建 transdtl 记录初始流水
+            val trans = TTransdtl().apply {
+                billno = systemUtilService.refno
+                mode = TradeDict.PAY_MODE_CARD
+                transDate = param.termdate
+                transTime = param.termtime
+                deviceno = param.deviceno
+                userid = person.userid
+                bankCardNo = param.cardno
+                amount = 0.0
+                waterSumHundredLitre = 0
+                status = TradeDict.DTL_STATUS_INIT
+                authStatus = 1
+                uploadStatus = 0
+            }
+            val savedTrans = transdtlService.createNewTransdtl(trans)
+            //4. 将流水 refno 和费率信息返回给终端
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .data("refno", savedTrans.billno)
+                    .data("feeamount", feeConfig.amount)
+                    .data("waterlimit", feeConfig.maxWaterLitre)
+                    .data("feeunit", 0)
+                    .success())
+        } catch (ex: Exception) {
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .exception(WaterErrorCode.PROCESS_ERROR, ex, "系统出错"))
         }
-
-        return ResponseEntity.ok(ResponseBodyBuilder.create()
-                .data("billno", trans.billno)
-                .data("feeamount", 1)
-                .data("max_litre", 50)
-                .success())
     }
 
     @PostMapping("/qrcode/init")
     fun qrcodePayInit(@RequestBody param: QrcodePayRequest): ResponseEntity<Any> {
-        TODO("")
+        try {//1. 创建并记录初始流水
+            val trans = TTransdtl().apply {
+                billno = systemUtilService.refno
+                mode = TradeDict.PAY_MODE_QRCODE
+                transDate = param.termdate
+                transTime = param.termtime
+                deviceno = param.deviceno
+                amount = 0.0
+                waterSumHundredLitre = 0
+                status = TradeDict.DTL_STATUS_INIT
+                authStatus = 0
+                uploadStatus = 0
+            }
+            val savedTrans = transdtlService.createNewTransdtl(trans)
+            //2.将流水号及认证地址返回给终端
+            //将认证url转为短码
+            val url = ShortURLUtil.doGetSinaShortUrl(
+                    "http://172.28.43.20:8080/water/api/confirm?refno=" + savedTrans.billno)
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .data("refno", savedTrans.billno)
+                    .data("url", url)
+                    .data("vaildtime", 180)
+                    .success())
+        } catch (ex: Exception) {
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .exception(WaterErrorCode.PROCESS_ERROR, ex, "系统出错"))
+        }
+    }
+
+    @GetMapping("/qrcode/query")
+    fun qrcodeQuery(@RequestBody param: QrcodeQueryRequest): ResponseEntity<Any> {
+        try {
+            val feeConfig = deviceService.queryTFeeConfigByDeviceno(param.deviceno)
+                    ?: return ResponseEntity.ok(ResponseBodyBuilder.create()
+                            .fail(WaterErrorCode.DATA_NOTFOUND_ERROR, "未查询到该设备的费率信息"))
+            val trans = transdtlService.queryTrans(param)
+                    ?: return ResponseEntity.ok(ResponseBodyBuilder.create()
+                            .fail(WaterErrorCode.DATA_NOTFOUND_ERROR, "未查询到该流水号"))
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .data("refno", trans.billno)
+                    .data("authstatus", trans.authStatus)
+                    .data("paystatus", 2)
+                    .data("feeamount", feeConfig.amount)
+                    .data("feeunit", 0)
+                    .data("paidAmount", 0)
+                    .success())
+        } catch (ex: Exception) {
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .exception(WaterErrorCode.PROCESS_ERROR, ex, "系统出错"))
+        }
+    }
+
+    @GetMapping("/confirm")
+    fun confirmView(): ModelAndView {
+        return ModelAndView("/system/confirm/confirm")
+    }
+
+    @PostMapping("/auth")
+    @ResponseBody
+    fun auth(@RequestBody param: UserAuthRequest): ResponseEntity<Any> {
+        return try {
+            transdtlService.userAuth(param)
+            ResponseEntity.ok(ResponseBodyBuilder.create().success())
+        } catch (ex: Exception) {
+            ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .exception(WaterErrorCode.PROCESS_ERROR, ex, "系统出错,认证失败"))
+        }
     }
 
     @PostMapping("/uploadrecord")
     fun transdtlUpload(@RequestBody param: UploadRecordRequest): ResponseEntity<Any> {
-        // 1. 根据 billno 查询 transdtl , 并加锁
-        TODO("")
+        // 1. 根据 refno 查询 transdtl , 并加锁
+        val dtl = transdtlService.saveDeviceDtlData(param)
+        return ResponseEntity.ok(ResponseBodyBuilder.create().data("refno", dtl.billno)
+                .success())
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/water/controller/water_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/water/controller/water_controller.kt
index d8fbcdd..ca1750b 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/water/controller/water_controller.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/water/controller/water_controller.kt
@@ -246,7 +246,7 @@
         }
     }
 
-    @GetMapping("/device/devino/{devino}")
+    @GetMapping("/device/devino/{deviceid}")
     @ResponseBody
     fun checkDevino(@PathVariable deviceid: Int): ResponseEntity<Any> {
         try {
diff --git a/src/main/kotlin/com/supwisdom/dlpay/water/service/transdtl_service.kt b/src/main/kotlin/com/supwisdom/dlpay/water/service/transdtl_service.kt
index e359f81..099779a 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/water/service/transdtl_service.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/water/service/transdtl_service.kt
@@ -1,8 +1,11 @@
 package com.supwisdom.dlpay.water.service
 
 import com.supwisdom.dlpay.exception.TransactionProcessException
+import com.supwisdom.dlpay.framework.util.TradeDict
 import com.supwisdom.dlpay.framework.util.WaterErrorCode
+import com.supwisdom.dlpay.water.QrcodeQueryRequest
 import com.supwisdom.dlpay.water.UploadRecordRequest
+import com.supwisdom.dlpay.water.UserAuthRequest
 import com.supwisdom.dlpay.water.dao.TransdtlDao
 import com.supwisdom.dlpay.water.domain.TTransdtl
 import org.springframework.beans.factory.annotation.Autowired
@@ -19,11 +22,28 @@
     }
 
     override fun saveDeviceDtlData(record: UploadRecordRequest): TTransdtl {
-        val dtl = transdtlDao.findByBillnoForUpdate(record.billno)
+        val dtl = transdtlDao.findByBillnoForUpdate(record.refno)
                 ?: throw TransactionProcessException(WaterErrorCode.DATA_NOTFOUND_ERROR,
                         "交易订单号不存在")
         dtl.amount = record.amount / 100.0
-        dtl.waterSumHundredLitre = record.waterIn100ML
+        dtl.waterSumHundredLitre = record.flowsensors
+        dtl.uploadTime = record.transdate + record.transtime
+        dtl.uploadStatus = 1
+        dtl.status = TradeDict.DTL_STATUS_WIP
+        transdtlDao.save(dtl)
+        return dtl
+    }
+
+    override fun queryTrans(param: QrcodeQueryRequest?): TTransdtl {
+        return transdtlDao.findByBillnoAndDeviceno(param!!.refno, param.deviceno)
+    }
+
+    override fun userAuth(param: UserAuthRequest?): TTransdtl {
+        val dtl = transdtlDao.findById(param!!.refno).orElse(null)
+                ?: throw TransactionProcessException(WaterErrorCode.DATA_NOTFOUND_ERROR,
+                        "交易订单号不存在")
+        dtl.userid = param.userid
+        dtl.authStatus = 1
         transdtlDao.save(dtl)
         return dtl
     }
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index e263110..e80789e 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -23,7 +23,7 @@
 spring.thymeleaf.cache=false
 spring.thymeleaf.enabled=true
 #################################################
-#server.servlet.context-path=/water
+server.servlet.context-path=/water
 ################################################
 # user password
 auth.password.bcrypt.length=10
diff --git a/src/main/resources/db/migration/V1.3__init_data.sql b/src/main/resources/db/migration/V1.3__init_data.sql
index 307edb1..aaa02e7 100644
--- a/src/main/resources/db/migration/V1.3__init_data.sql
+++ b/src/main/resources/db/migration/V1.3__init_data.sql
@@ -4,3 +4,5 @@
 INSERT INTO "public"."tb_role_function"("id", "functionid", "permissions", "roleid") VALUES ('6', 6, NULL, 'd1yctWs5+ks0iQN3m9bUvRHus6HbKbrs');
 INSERT INTO "public"."tb_role_function"("id", "functionid", "permissions", "roleid") VALUES ('7', 7, NULL, 'd1yctWs5+ks0iQN3m9bUvRHus6HbKbrs');
 
+CREATE SEQUENCE "public"."seq_refno" INCREMENT 1MINVALUE  1MAXVALUE 9223372036854775807 START 1 CACHE 1;
+ALTER SEQUENCE "public"."seq_refno" OWNER TO "watermanager";
\ No newline at end of file
diff --git a/src/main/resources/static/custom/module/admin.js b/src/main/resources/static/custom/module/admin.js
old mode 100755
new mode 100644
index e6ad642..cbdbc36
--- a/src/main/resources/static/custom/module/admin.js
+++ b/src/main/resources/static/custom/module/admin.js
@@ -1,373 +1,387 @@
-layui.define(['layer'], function (exports) {

-    var layer = layui.layer;

-    var popupRightIndex, popupCenterIndex, popupCenterParam;

-

-    var admin = {

-        isRefresh: false,

-        // 设置侧栏折叠

-        flexible: function (expand) {

-            var isExapnd = $('.layui-layout-admin').hasClass('admin-nav-mini');

-            if (isExapnd == !expand) {

-                return;

-            }

-            if (expand) {

-                $('.layui-layout-admin').removeClass('admin-nav-mini');

-            } else {

-                $('.layui-layout-admin').addClass('admin-nav-mini');

-            }

-        },

-        // 设置导航栏选中

-        activeNav: function (url) {

-            $('.layui-layout-admin .layui-side .layui-nav .layui-nav-item .layui-nav-child dd').removeClass('layui-this');

-            $('.layui-layout-admin .layui-side .layui-nav .layui-nav-item').removeClass('layui-this');

-            if (url && url != '') {

-                $('.layui-layout-admin .layui-side .layui-nav .layui-nav-item').removeClass('layui-nav-itemed');

-                var $a = $('.layui-layout-admin .layui-side .layui-nav a[href="#!' + url + '"]');

-                $a.parent('li').addClass('layui-this');

-                $a.parent('dd').addClass('layui-this');

-                $a.parent('dd').parent('.layui-nav-child').parent('.layui-nav-item').addClass('layui-nav-itemed');

-            }

-        },

-        // 右侧弹出

-        popupRight: function (path) {

-            var param = new Object();

-            param.path = path;

-            param.id = 'adminPopupR';

-            param.title = false;

-            param.anim = 2;

-            param.isOutAnim = false;

-            param.closeBtn = false;

-            param.offset = 'r';

-            param.shadeClose = true;

-            param.area = '336px';

-            param.skin = 'layui-layer-adminRight';

-            param.end = function () {

-                layer.closeAll('tips');

-            };

-            popupRightIndex = admin.open(param);

-            return popupRightIndex;

-        },

-        // 关闭右侧弹出

-        closePopupRight: function () {

-            layer.close(popupRightIndex);

-        },

-        // 中间弹出

-        popupCenter: function (param) {

-            param.id = 'adminPopupC';

-            popupCenterParam = param;

-            popupCenterIndex = admin.open(param);

-            return popupCenterIndex;

-        },

-        // 关闭中间弹出并且触发finish回调

-        finishPopupCenter: function () {

-            layer.close(popupCenterIndex);

-            popupCenterParam.finish ? popupCenterParam.finish() : '';

-        },

-        // 关闭中间弹出

-        closePopupCenter: function () {

-            layer.close(popupCenterIndex);

-        },

-        // 封装layer.open

-        open: function (param) {

-            var sCallBack = param.success;

-            param.type = 1;

-            param.area = param.area ? param.area : '450px';

-            param.offset = param.offset ? param.offset : '120px';

-            param.resize ? param.resize : false;

-            param.shade ? param.shade : .2;

-            param.success = function (layero, index) {

-                sCallBack ? sCallBack(layero, index) : '';

-                admin.ajax({

-                    url: param.path,

-                    type: 'GET',

-                    dataType: 'html',

-                    success: function (result, status, xhr) {

-                        $(layero).children('.layui-layer-content').html(result);

-                    }

-                });

-            };

-            return layer.open(param);

-        },

-        

-        go:function(url,data,success,error){

-        	  $.ajax({

-        		  url: url,

-        		  data: data,

-        		  async: false,

-        		  dataType: 'json',

-        		  type: 'post',

-        		  success: success,

-                  error:error

-        	  })

-        },

-        dgo:function(url,data,success,error){

-      	  $.ajax({

-      		  url: url,

-      		  data: data,

-      		  async: false,

-      		  dataType: 'json',

-      		  type: 'get',

-      		  success: success,

-              error:error

-      	  })

-      },

-        // 封装ajax请求,返回数据类型为json

-        req: function (url, data, success, method) {

-            admin.ajax({

-                url: url,

-                data: data,

-                async: false,

-                type: method,

-                dataType: 'json',

-                success: success

-            });

-        },

-        // 封装ajax请求

-        ajax: function (param) {

-        	console.log(param);

-            var successCallback = param.success;

-            param.success = function (result, status, xhr) {

-                // 判断登录过期和没有权限

-                var jsonRs;

-                if ('json' == param.dataType.toLowerCase()) {

-                    jsonRs = result;

-                } else if ('html' == param.dataType.toLowerCase() || 'text' == param.dataType.toLowerCase()) {

-                    jsonRs = admin.parseJSON(result);

-                }

-                if (jsonRs) {

-                    if (jsonRs.code == 401) {

-                        layer.msg(jsonRs.msg, {icon: 2, time: 1500}, function () {

-                            location.replace('/login');

-                        }, 1000);

-                        return;

-                    } else if ('html' == param.dataType.toLowerCase() && jsonRs.code == 403) {

-                        layer.msg(jsonRs.msg, {icon: 2});

-                    }

-                }

-                successCallback(result, status, xhr);

-            };

-            param.error = function (xhr) {

-                //{code: xhr.status, msg: xhr.statusText}

-                param.success(xhr.responseText,xhr.status,xhr);

-            };

-            $.ajax(param);

-        },

-        // 显示加载动画

-        showLoading: function (element) {

-            $(element).append('<i class="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop admin-loading"></i>');

-        },

-        // 移除加载动画

-        removeLoading: function (element) {

-            $(element + '>.admin-loading').remove();

-        },

-        // 缓存临时数据

-        putTempData: function (key, value) {

-            if (value) {

-                layui.sessionData('tempData', {key: key, value: value});

-            } else {

-                layui.sessionData('tempData', {key: key, remove: true});

-            }

-        },

-        // 获取缓存临时数据

-        getTempData: function (key) {

-            return layui.sessionData('tempData')[key];

-        },

-        // 滑动选项卡

-        rollPage: function (d) {

-            var $tabTitle = $('.layui-layout-admin .layui-body .layui-tab .layui-tab-title');

-            var left = $tabTitle.scrollLeft();

-            if ('left' === d) {

-                $tabTitle.scrollLeft(left - 120);

-            } else if ('auto' === d) {

-                var autoLeft = 0;

-                $tabTitle.children("li").each(function () {

-                    if ($(this).hasClass('layui-this')) {

-                        return false;

-                    } else {

-                        autoLeft += $(this).outerWidth();

-                    }

-                });

-                $tabTitle.scrollLeft(autoLeft - 47);

-            } else {

-                $tabTitle.scrollLeft(left + 120);

-            }

-        },

-        // 刷新主题部分

-        refresh: function () {

-            admin.isRefresh = true;

-            Q.refresh();

-        },

-        // 判断是否为json

-        parseJSON: function (str) {

-            if (typeof str == 'string') {

-                try {

-                    var obj = JSON.parse(str);

-                    if (typeof obj == 'object' && obj) {

-                        return obj;

-                    }

-                } catch (e) {

-                }

-            }

-        },

-        formatDate:function (str) {

-            if (str == null || str == "") {

-                return;

-            }

-            switch (str.length) {

-                case 8:

-                    str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8);

-                    return str;

-                case 12:

-                    str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8) + " " + str.substring(8, 10)

-                        + ":" + str.substring(10, 12);

-                    return str;

-                case 14:

-                    str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8) + " " + str.substring(8, 10)

-                        + ":" + str.substring(10, 12) + ":" + str.substring(12, 14);

-                    return str;

-                default:

-                    return str;

-            }

-        }

-    };

-

-    // ewAdmin提供的事件

-    admin.events = {

-        // 折叠侧导航

-        flexible: function (e) {

-            var expand = $('.layui-layout-admin').hasClass('admin-nav-mini');

-            admin.flexible(expand);

-        },

-        // 刷新主体部分

-        refresh: function () {

-            admin.refresh();

-        },

-        //后退

-        back: function () {

-            history.back();

-        },

-        // 设置主题

-        theme: function () {

-            admin.popupRight('home/theme');

-        },

-        // 全屏

-        fullScreen: function (e) {

-            var ac = 'layui-icon-screen-full', ic = 'layui-icon-screen-restore';

-            var ti = $(this).find('i');

-

-            var isFullscreen = document.fullscreenElement || document.msFullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || false;

-            if (isFullscreen) {

-                var efs = document.exitFullscreen || document.webkitExitFullscreen || document.mozCancelFullScreen || document.msExitFullscreen;

-                if (efs) {

-                    efs.call(document);

-                } else if (window.ActiveXObject) {

-                    var ws = new ActiveXObject('WScript.Shell');

-                    ws && ws.SendKeys('{F11}');

-                }

-                ti.addClass(ac).removeClass(ic);

-            } else {

-                var el = document.documentElement;

-                var rfs = el.requestFullscreen || el.webkitRequestFullscreen || el.mozRequestFullScreen || el.msRequestFullscreen;

-                if (rfs) {

-                    rfs.call(el);

-                } else if (window.ActiveXObject) {

-                    var ws = new ActiveXObject('WScript.Shell');

-                    ws && ws.SendKeys('{F11}');

-                }

-                ti.addClass(ic).removeClass(ac);

-            }

-        },

-        // 左滑动tab

-        leftPage: function () {

-            admin.rollPage("left");

-        },

-        // 右滑动tab

-        rightPage: function () {

-            admin.rollPage();

-        },

-        // 关闭当前选项卡

-        closeThisTabs: function () {

-            var $title = $('.layui-layout-admin .layui-body .layui-tab .layui-tab-title');

-            if ($title.find('li').first().hasClass('layui-this')) {

-                return;

-            }

-            $title.find('li.layui-this').find(".layui-tab-close").trigger("click");

-        },

-        // 关闭其他选项卡

-        closeOtherTabs: function () {

-            $('.layui-layout-admin .layui-body .layui-tab .layui-tab-title li:gt(0):not(.layui-this)').find('.layui-tab-close').trigger('click');

-        },

-        // 关闭所有选项卡

-        closeAllTabs: function () {

-            $('.layui-layout-admin .layui-body .layui-tab .layui-tab-title li:gt(0)').find('.layui-tab-close').trigger('click');

-        },

-        // 关闭所有弹窗

-        closeDialog: function () {

-            layer.closeAll('page');

-        },

-        //刷新字典

-        refreshDict: function (){

-            layer.confirm('确定要刷新数据字典吗?', {

-                    btn: ['确定', '取消']

-                }, function (index, layero) {

-                    layer.closeAll('dialog');  //加入这个信息点击确定 会关闭这个消息框

-                    admin.dgo("/dictrefresh", {}, function (data) {

-                        if (data.code == 200) {

-                            layer.msg("刷新数据字典成功!", {icon: 1, time: 1000});

-                            DictPoolToolkit().initAll("/dictpool");

-                        } else if (data.code == 401) {

-                            layer.msg(data.msg, {icon: 2, time: 1500}, function () {

-                                location.replace('/login');

-                            }, 1000);

-                            return;

-                        } else {

-                            layer.msg(data.msg, {icon: 2, time: 1500});

-                        }

-                    }, function () {

-                        layer.msg("数据字典刷新失败,访问服务器失败!", {icon: 2, time: 1500});

-                    });

-                });

-        }

-    };

-

-    // 所有ew-event

-    $('body').on('click', '*[ew-event]', function () {

-        var event = $(this).attr('ew-event');

-        var te = admin.events[event];

-        te && te.call(this, $(this));

-    });

-

-    // 移动设备遮罩层点击事件

-    $('.site-mobile-shade').click(function () {

-        admin.flexible(true);

-    });

-

-    // 侧导航折叠状态下鼠标经过显示提示

-    $('body').on('mouseenter', '.layui-layout-admin.admin-nav-mini .layui-side .layui-nav .layui-nav-item>a', function () {

-        var tipText = $(this).find('cite').text();

-        if (document.body.clientWidth > 750) {

-            layer.tips(tipText, this);

-        }

-    }).on('mouseleave', '.layui-layout-admin.admin-nav-mini .layui-side .layui-nav .layui-nav-item>a', function () {

-        layer.closeAll('tips');

-    });

-

-    // 侧导航折叠状态下点击展开

-    $('body').on('click', '.layui-layout-admin.admin-nav-mini .layui-side .layui-nav .layui-nav-item>a', function () {

-        if (document.body.clientWidth > 750) {

-            layer.closeAll('tips');

-            admin.flexible(true);

-        }

-    });

-

-    // 所有lay-tips处理

-    $('body').on('mouseenter', '*[lay-tips]', function () {

-        var tipText = $(this).attr('lay-tips');

-        var dt = $(this).attr('lay-direction');

-        layer.tips(tipText, this, {tips: dt || 1, time: -1});

-    }).on('mouseleave', '*[lay-tips]', function () {

-        layer.closeAll('tips');

-    });

-

-    exports('admin', admin);

-});

+layui.define(['layer'], function (exports) {
+    var layer = layui.layer;
+    var popupRightIndex, popupCenterIndex, popupCenterParam;
+    var baseUrl = window.location.pathname;
+
+    var admin = {
+        isRefresh: false,
+        // 设置侧栏折叠
+        flexible: function (expand) {
+            var isExapnd = $('.layui-layout-admin').hasClass('admin-nav-mini');
+            if (isExapnd == !expand) {
+                return;
+            }
+            if (expand) {
+                $('.layui-layout-admin').removeClass('admin-nav-mini');
+            } else {
+                $('.layui-layout-admin').addClass('admin-nav-mini');
+            }
+        },
+        // 设置导航栏选中
+        activeNav: function (url) {
+            $('.layui-layout-admin .layui-side .layui-nav .layui-nav-item .layui-nav-child dd').removeClass('layui-this');
+            $('.layui-layout-admin .layui-side .layui-nav .layui-nav-item').removeClass('layui-this');
+            if (url && url != '') {
+                $('.layui-layout-admin .layui-side .layui-nav .layui-nav-item').removeClass('layui-nav-itemed');
+                var $a = $('.layui-layout-admin .layui-side .layui-nav a[href="#!' + url + '"]');
+                $a.parent('li').addClass('layui-this');
+                $a.parent('dd').addClass('layui-this');
+                $a.parent('dd').parent('.layui-nav-child').parent('.layui-nav-item').addClass('layui-nav-itemed');
+            }
+        },
+        // 右侧弹出
+        popupRight: function (path) {
+            var param = new Object();
+            param.path = path;
+            param.id = 'adminPopupR';
+            param.title = false;
+            param.anim = 2;
+            param.isOutAnim = false;
+            param.closeBtn = false;
+            param.offset = 'r';
+            param.shadeClose = true;
+            param.area = '336px';
+            param.skin = 'layui-layer-adminRight';
+            param.end = function () {
+                layer.closeAll('tips');
+            };
+            popupRightIndex = admin.open(param);
+            return popupRightIndex;
+        },
+        // 关闭右侧弹出
+        closePopupRight: function () {
+            layer.close(popupRightIndex);
+        },
+        // 中间弹出
+        popupCenter: function (param) {
+            param.id = 'adminPopupC';
+            popupCenterParam = param;
+            popupCenterIndex = admin.open(param);
+            return popupCenterIndex;
+        },
+        // 关闭中间弹出并且触发finish回调
+        finishPopupCenter: function () {
+            layer.close(popupCenterIndex);
+            popupCenterParam.finish ? popupCenterParam.finish() : '';
+        },
+        // 关闭中间弹出
+        closePopupCenter: function () {
+            layer.close(popupCenterIndex);
+        },
+        // 封装layer.open
+        open: function (param) {
+            var sCallBack = param.success;
+            param.type = 1;
+            param.area = param.area ? param.area : '450px';
+            param.offset = param.offset ? param.offset : '120px';
+            param.resize ? param.resize : false;
+            param.shade ? param.shade : .2;
+            param.success = function (layero, index) {
+                sCallBack ? sCallBack(layero, index) : '';
+                admin.ajax({
+                    url: param.path,
+                    type: 'GET',
+                    dataType: 'html',
+                    success: function (result, status, xhr) {
+                        $(layero).children('.layui-layer-content').html(result);
+                    }
+                });
+            };
+            return layer.open(param);
+        },
+        
+        go:function(url,data,success,error){
+        	  $.ajax({
+        		  url: url,
+        		  data: data,
+        		  async: false,
+        		  dataType: 'json',
+        		  type: 'post',
+        		  success: success,
+                  error:error
+        	  })
+        },
+        dgo:function(url,data,success,error){
+      	  $.ajax({
+      		  url: url,
+      		  data: data,
+      		  async: false,
+      		  dataType: 'json',
+      		  type: 'get',
+      		  success: success,
+              error:error
+      	  })
+      },
+        // 封装ajax请求,返回数据类型为json
+        req: function (url, data, success, method) {
+            admin.ajax({
+                url: url,
+                data: data,
+                async: false,
+                type: method,
+                dataType: 'json',
+                success: success
+            });
+        },
+        // 封装ajax请求
+        ajax: function (param) {
+        	console.log(param);
+            var successCallback = param.success;
+            param.success = function (result, status, xhr) {
+                // 判断登录过期和没有权限
+                var jsonRs;
+                if ('json' == param.dataType.toLowerCase()) {
+                    jsonRs = result;
+                } else if ('html' == param.dataType.toLowerCase() || 'text' == param.dataType.toLowerCase()) {
+                    jsonRs = admin.parseJSON(result);
+                }
+                if (jsonRs) {
+                    if (jsonRs.code == 401) {
+                        layer.msg(jsonRs.msg, {icon: 2, time: 1500}, function () {
+                            location.replace('/login');
+                        }, 1000);
+                        return;
+                    } else if ('html' == param.dataType.toLowerCase() && jsonRs.code == 403) {
+                        layer.msg(jsonRs.msg, {icon: 2});
+                    }
+                }
+                successCallback(result, status, xhr);
+            };
+            param.error = function (xhr) {
+                //{code: xhr.status, msg: xhr.statusText}
+                param.success(xhr.responseText,xhr.status,xhr);
+            };
+            $.ajax(param);
+        },
+        // 显示加载动画
+        showLoading: function (element) {
+            $(element).append('<i class="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop admin-loading"></i>');
+        },
+        // 移除加载动画
+        removeLoading: function (element) {
+            $(element + '>.admin-loading').remove();
+        },
+        // 缓存临时数据
+        putTempData: function (key, value) {
+            if (value) {
+                layui.sessionData('tempData', {key: key, value: value});
+            } else {
+                layui.sessionData('tempData', {key: key, remove: true});
+            }
+        },
+        // 获取缓存临时数据
+        getTempData: function (key) {
+            return layui.sessionData('tempData')[key];
+        },
+        // 滑动选项卡
+        rollPage: function (d) {
+            var $tabTitle = $('.layui-layout-admin .layui-body .layui-tab .layui-tab-title');
+            var left = $tabTitle.scrollLeft();
+            if ('left' === d) {
+                $tabTitle.scrollLeft(left - 120);
+            } else if ('auto' === d) {
+                var autoLeft = 0;
+                $tabTitle.children("li").each(function () {
+                    if ($(this).hasClass('layui-this')) {
+                        return false;
+                    } else {
+                        autoLeft += $(this).outerWidth();
+                    }
+                });
+                $tabTitle.scrollLeft(autoLeft - 47);
+            } else {
+                $tabTitle.scrollLeft(left + 120);
+            }
+        },
+        // 刷新主题部分
+        refresh: function () {
+            admin.isRefresh = true;
+            Q.refresh();
+        },
+        // 判断是否为json
+        parseJSON: function (str) {
+            if (typeof str == 'string') {
+                try {
+                    var obj = JSON.parse(str);
+                    if (typeof obj == 'object' && obj) {
+                        return obj;
+                    }
+                } catch (e) {
+                }
+            }
+        },
+        formatDate:function (str) {
+            if (str == null || str == "") {
+                return;
+            }
+            switch (str.length) {
+                case 8:
+                    str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8);
+                    return str;
+                case 12:
+                    str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8) + " " + str.substring(8, 10)
+                        + ":" + str.substring(10, 12);
+                    return str;
+                case 14:
+                    str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8) + " " + str.substring(8, 10)
+                        + ":" + str.substring(10, 12) + ":" + str.substring(12, 14);
+                    return str;
+                default:
+                    return str;
+            }
+        },
+        errorBack: function (err) {
+            layer.closeAll('loading');
+            if (403 == err.status) {
+                layer.msg("无资源权限!", {icon: 2, time: 1500});
+                return;
+            }
+            if (200 == err.status) {
+                layer.msg("请求异常,请刷新页面重新操作", {icon: 2, time: 1500});
+                return;
+            } else {
+                layer.msg("请求服务器失败!", {icon: 2});
+            }
+        }
+    };
+
+    // ewAdmin提供的事件
+    admin.events = {
+        // 折叠侧导航
+        flexible: function (e) {
+            var expand = $('.layui-layout-admin').hasClass('admin-nav-mini');
+            admin.flexible(expand);
+        },
+        // 刷新主体部分
+        refresh: function () {
+            admin.refresh();
+        },
+        //后退
+        back: function () {
+            history.back();
+        },
+        // 设置主题
+        theme: function () {
+            admin.popupRight(baseUrl+'home/theme');
+        },
+        // 全屏
+        fullScreen: function (e) {
+            var ac = 'layui-icon-screen-full', ic = 'layui-icon-screen-restore';
+            var ti = $(this).find('i');
+
+            var isFullscreen = document.fullscreenElement || document.msFullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || false;
+            if (isFullscreen) {
+                var efs = document.exitFullscreen || document.webkitExitFullscreen || document.mozCancelFullScreen || document.msExitFullscreen;
+                if (efs) {
+                    efs.call(document);
+                } else if (window.ActiveXObject) {
+                    var ws = new ActiveXObject('WScript.Shell');
+                    ws && ws.SendKeys('{F11}');
+                }
+                ti.addClass(ac).removeClass(ic);
+            } else {
+                var el = document.documentElement;
+                var rfs = el.requestFullscreen || el.webkitRequestFullscreen || el.mozRequestFullScreen || el.msRequestFullscreen;
+                if (rfs) {
+                    rfs.call(el);
+                } else if (window.ActiveXObject) {
+                    var ws = new ActiveXObject('WScript.Shell');
+                    ws && ws.SendKeys('{F11}');
+                }
+                ti.addClass(ic).removeClass(ac);
+            }
+        },
+        // 左滑动tab
+        leftPage: function () {
+            admin.rollPage("left");
+        },
+        // 右滑动tab
+        rightPage: function () {
+            admin.rollPage();
+        },
+        // 关闭当前选项卡
+        closeThisTabs: function () {
+            var $title = $('.layui-layout-admin .layui-body .layui-tab .layui-tab-title');
+            if ($title.find('li').first().hasClass('layui-this')) {
+                return;
+            }
+            $title.find('li.layui-this').find(".layui-tab-close").trigger("click");
+        },
+        // 关闭其他选项卡
+        closeOtherTabs: function () {
+            $('.layui-layout-admin .layui-body .layui-tab .layui-tab-title li:gt(0):not(.layui-this)').find('.layui-tab-close').trigger('click');
+        },
+        // 关闭所有选项卡
+        closeAllTabs: function () {
+            $('.layui-layout-admin .layui-body .layui-tab .layui-tab-title li:gt(0)').find('.layui-tab-close').trigger('click');
+        },
+        // 关闭所有弹窗
+        closeDialog: function () {
+            layer.closeAll('page');
+        },
+        //刷新字典
+        refreshDict: function (){
+            layer.confirm('确定要刷新数据字典吗?', {
+                    btn: ['确定', '取消']
+                }, function (index, layero) {
+                    layer.closeAll('dialog');  //加入这个信息点击确定 会关闭这个消息框
+                    admin.dgo(baseUrl+"dictrefresh", {}, function (data) {
+                        if (data.code == 200) {
+                            layer.msg("刷新数据字典成功!", {icon: 1, time: 1000});
+                            DictPoolToolkit().initAll(baseUrl+"dictpool");
+                        } else if (data.code == 401) {
+                            layer.msg(data.msg, {icon: 2, time: 1500}, function () {
+                                location.replace('/login');
+                            }, 1000);
+                            return;
+                        } else {
+                            layer.msg(data.msg, {icon: 2, time: 1500});
+                        }
+                    }, function () {
+                        layer.msg("数据字典刷新失败,访问服务器失败!", {icon: 2, time: 1500});
+                    });
+                });
+        }
+    };
+
+    // 所有ew-event
+    $('body').on('click', '*[ew-event]', function () {
+        var event = $(this).attr('ew-event');
+        var te = admin.events[event];
+        te && te.call(this, $(this));
+    });
+
+    // 移动设备遮罩层点击事件
+    $('.site-mobile-shade').click(function () {
+        admin.flexible(true);
+    });
+
+    // 侧导航折叠状态下鼠标经过显示提示
+    $('body').on('mouseenter', '.layui-layout-admin.admin-nav-mini .layui-side .layui-nav .layui-nav-item>a', function () {
+        var tipText = $(this).find('cite').text();
+        if (document.body.clientWidth > 750) {
+            layer.tips(tipText, this);
+        }
+    }).on('mouseleave', '.layui-layout-admin.admin-nav-mini .layui-side .layui-nav .layui-nav-item>a', function () {
+        layer.closeAll('tips');
+    });
+
+    // 侧导航折叠状态下点击展开
+    $('body').on('click', '.layui-layout-admin.admin-nav-mini .layui-side .layui-nav .layui-nav-item>a', function () {
+        if (document.body.clientWidth > 750) {
+            layer.closeAll('tips');
+            admin.flexible(true);
+        }
+    });
+
+    // 所有lay-tips处理
+    $('body').on('mouseenter', '*[lay-tips]', function () {
+        var tipText = $(this).attr('lay-tips');
+        var dt = $(this).attr('lay-direction');
+        layer.tips(tipText, this, {tips: dt || 1, time: -1});
+    }).on('mouseleave', '*[lay-tips]', function () {
+        layer.closeAll('tips');
+    });
+
+    exports('admin', admin);
+});
diff --git a/src/main/resources/static/custom/module/index.js b/src/main/resources/static/custom/module/index.js
old mode 100755
new mode 100644
index 992d4d9..df14f67
--- a/src/main/resources/static/custom/module/index.js
+++ b/src/main/resources/static/custom/module/index.js
@@ -2,6 +2,7 @@
     var admin = layui.admin;
     var layer = layui.layer;
     var element = layui.element;
+    var baseUrl = window.location.pathname;
 
     var index = {
         pageTabs: true,  // 是否开启多标签
@@ -14,6 +15,12 @@
                 if ('javascript:;' != menuPath && '' != menuPath) {
                     var key = menuPath.replace(/[?:=&/]/g, '_');
                     $(this).attr('href', '#!' + key);
+                    if (menuPath.startsWith("/")) {
+                        menuPath = baseUrl + menuPath.substring(1);
+                    } else {
+                        menuPath = baseUrl + menuPath;
+                    }
+                    console.log(menuPath);
                     Q.reg(key, function () {
                         index.loadView({
                             menuId: key,
@@ -28,7 +35,7 @@
 
             // 主页
             Q.init({
-                index: 'home_console'
+                index: '_home_console'
             });
             // tab选项卡切换监听
             element.on('tab(admin-pagetabs)', function (data) {
@@ -134,7 +141,7 @@
             // 退出登录点击事件
             $('#btnLogout').click(function () {
                 layer.confirm('确定退出登录?', function () {
-                    location.replace('logout');
+                    location.replace(baseUrl+'logout');
                 });
             });
         }
diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html
index 1d2e6ef..4201180 100644
--- a/src/main/resources/templates/login.html
+++ b/src/main/resources/templates/login.html
@@ -93,7 +93,7 @@
             var field = obj.field;
             layer.load(2);
             $.ajax({
-                url: '/login/form',
+                url: '[[@{/login/form}]]',
                 data: field,
                 type: 'POST',
                 success: function (data) {
diff --git a/src/main/resources/templates/system/confirm/confirm.html b/src/main/resources/templates/system/confirm/confirm.html
new file mode 100644
index 0000000..062ffb0
--- /dev/null
+++ b/src/main/resources/templates/system/confirm/confirm.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
+<head>
+    <meta charset="UTF-8">
+    <title>Title</title>
+</head>
+<body>
+<button id="button-auth" style="margin:100px 100px auto;text-align: center;color: green;width: 200px;height: 80px;">确认</button>
+</body>
+<script type="text/javascript" th:src="@{/static/libs/jquery/jquery-3.2.1.min.js}"></script>
+<script>
+    /**
+     * @return {string}
+     */
+    function GetUrlRefnoPara() {
+        var url = document.location.toString();
+        var arrUrl = url.split("?");
+        var para = arrUrl[1].split("=");
+        return para[1]
+    }
+
+    /**
+     * @return {string}
+     */
+    function GetUserid() {
+        return "d1yctWs5+ks0iQN3m9bUvRHus6HbKbrs"
+    }
+    var allData = {
+        refno:GetUrlRefnoPara(),
+        userid:GetUserid()
+    }
+    $("#button-auth").click(function () {
+        $.ajax({
+            url: "[[@{/api/auth}]]",
+            type:"POST",
+            contentType:"application/json;charset=UTF-8",
+            data:JSON.stringify(allData),
+            success:function (data) {
+                if (data.retcode == 0) {
+                    alert("认证成功")
+                }else {
+                    alert(data.retmsg)
+                }
+            },
+            fail: function (data) {
+                alert(data.retmsg)
+            },
+            error:function (xhr) {
+                console.log(xhr)
+            }
+        })
+    })
+</script>
+</html>
+
diff --git a/src/main/resources/templates/system/device/form.html b/src/main/resources/templates/system/device/form.html
index ea0db7e..676124b 100644
--- a/src/main/resources/templates/system/device/form.html
+++ b/src/main/resources/templates/system/device/form.html
@@ -34,7 +34,7 @@
         var layer = layui.layer;
         var admin = layui.admin;
         var form = layui.form;
-        var url = '/device/add';
+        var url = '[[@{/device/add}]]';
         // 回显user数据
         var func = admin.getTempData('t_func');
         //  清除admin域中的数据
@@ -43,7 +43,7 @@
             $('input[name="deviceid"]').attr('readonly', 'readonly');
             form.val('form', func);
             $.ajax({
-                url: "/region/all",
+                url: "[[@{/region/all}]]",
                 type: "GET",
                 success: function (data) {
                     if (data.retcode == '0') {
@@ -65,7 +65,7 @@
         } else {
             form.render('select', 'form')
             $.ajax({
-                url: "/region/all",
+                url: "[[@{/region/all}]]",
                 type: "GET",
                 success: function (data) {
                     if (data.retcode == '0') {
@@ -133,7 +133,7 @@
                         admin.finishPopupCenter();
                     } else if (result.retcode == 401) {
                         layer.msg(result.msg, {icon: 2, time: 1500}, function () {
-                            location.replace('/login');
+                            location.replace('[[@{/login}]]');
                         }, 1000);
                         return;
                     } else {
diff --git a/src/main/resources/templates/system/device/index.html b/src/main/resources/templates/system/device/index.html
index 7561500..a6a0c55 100644
--- a/src/main/resources/templates/system/device/index.html
+++ b/src/main/resources/templates/system/device/index.html
@@ -60,7 +60,6 @@
         </div>
     </div>
 </div>
-<!--<script src="/static/libs/layui/layui.js"></script>-->
 <script>
 
     layui.use(['form', 'table', 'layer', 'admin', 'element'], function () {
@@ -69,7 +68,7 @@
         let admin = layui.admin;
         //  渲染区域选择框
         $.ajax({
-            url: '/region/all',
+            url: '[[@{/region/all}]]',
             type: 'GET',
             success: function (data) {
                 if (data.retcode == '0') {
@@ -88,7 +87,7 @@
         })
         //  渲染状态选择框
         $.ajax({
-            url: 'device/status',
+            url: '[[@{device/status}]]',
             type: 'GET',
             success: function (data) {
                 console.log(data)
@@ -109,7 +108,7 @@
         // 渲染表格
         table.render({
             elem: '#devicetable',
-            url: '/device/list',
+            url: '[[@{/device/list}]]',
             page: true,
             cols: [
                 [
@@ -147,7 +146,7 @@
                     areano: areano,
                     deviceStatus: status
                 },
-                url: "/device/search"
+                url: "[[@{/device/search}]]"
             });
         });
         $('#btn-add-device').click(function () {
@@ -160,7 +159,7 @@
             }
             admin.popupCenter({
                 title: title,
-                path: '/device/loadadd',
+                path: '[[@{/device/loadadd}]]',
                 finish: function () {
                     table.reload('devicetable', {});
                 }
@@ -172,7 +171,7 @@
             admin.popupCenter({
                 title: title,
                 area: ['400px', '600px'],
-                path: '/device/loadfunc'
+                path: '[[@{/device/loadfunc}]]'
             });
         };
         // 工具条点击事件
@@ -192,7 +191,7 @@
                 layer.close(i);
                 layer.load(2);
                 let token = $("meta[name='_csrf_token']").attr("value");
-                admin.go('/device/del', {
+                admin.go('[[@{/device/del}]]', {
                     deviceid: data.deviceid,
                     _csrf: token
                 }, function (data) {
diff --git a/src/main/resources/templates/system/dtl/shopdtl.html b/src/main/resources/templates/system/dtl/shopdtl.html
index 94fc668..82aa9ff 100644
--- a/src/main/resources/templates/system/dtl/shopdtl.html
+++ b/src/main/resources/templates/system/dtl/shopdtl.html
@@ -210,7 +210,7 @@
             page: true,
             cols: [
                 [
-                    {field: 'refno', title: '参考号', align: 'center', width: 200, sort: true},
+                    {field: 'billno', title: '参考号', align: 'center', width: 200, sort: true},
                     {field: 'accdate', title: '记账日期', align: 'center', width: 100, sort: true},
                     {field: 'transdesc', title: '交易描述', align: 'center', width: 175},
                     {field: 'shopname', title: '商户名称', align: 'center', width: 250},
diff --git a/src/main/resources/templates/system/dtl/userdtl.html b/src/main/resources/templates/system/dtl/userdtl.html
index e7ebaff..607d809 100644
--- a/src/main/resources/templates/system/dtl/userdtl.html
+++ b/src/main/resources/templates/system/dtl/userdtl.html
@@ -175,7 +175,7 @@
             page: true,
             cols: [
                 [
-                    {field: 'refno', title: '参考号', align: 'center', width: 200, sort: true},
+                    {field: 'billno', title: '参考号', align: 'center', width: 200, sort: true},
                     {field: 'accdate', title: '记账日期', align: 'center', width: 100, sort: true},
                     {field: 'transdesc', title: '交易描述', align: 'center', width: 175},
                     {field: 'userName', title: '姓名', align: 'center', width: 150},
diff --git a/src/main/resources/templates/system/region/form.html b/src/main/resources/templates/system/region/form.html
index fad5de3..1e253a2 100644
--- a/src/main/resources/templates/system/region/form.html
+++ b/src/main/resources/templates/system/region/form.html
@@ -40,7 +40,7 @@
         var layer = layui.layer;
         var admin = layui.admin;
         var form = layui.form;
-        var url = '/region/add';
+        var url = '[[@{/region/add}]]';
         // 回显user数据
         var func = admin.getTempData('t_func');
         //  清除admin域中的数据
@@ -98,7 +98,7 @@
                         admin.finishPopupCenter();
                     } else if (result.retcode == 401) {
                         layer.msg(result.msg, {icon: 2, time: 1500}, function () {
-                            location.replace('/login');
+                            location.replace('[[@{/login}]]');
                         }, 1000);
                         return;
                     } else {
diff --git a/src/main/resources/templates/system/region/index.html b/src/main/resources/templates/system/region/index.html
index ab23c76..0fc9002 100644
--- a/src/main/resources/templates/system/region/index.html
+++ b/src/main/resources/templates/system/region/index.html
@@ -46,7 +46,7 @@
         // 渲染表格
         table.render({
             elem: '#regiontable',
-            url: '/region/list/0',
+            url: '[[@{/region/list/0}]]',
             page: true,
             toolbar: true,
             cols: [
@@ -77,7 +77,7 @@
             let key = $('#search-value').val();
             table.reload('regiontable', {
                 where: {searchkey: key},
-                url: "/region/search"
+                url: "[[@{/region/search}]]"
             });
         });
         $('#btn-add-region').click(function () {
@@ -90,12 +90,12 @@
             }
             admin.popupCenter({
                 title: title,
-                path: '/region/loadadd',
+                path: '[[@{/region/loadadd}]]',
                 finish: function () {
                     table.reload('regiontable', {});
                     //  更新区域树
                     $.ajax({
-                        url: '/region/tree',
+                        url: '[[@{/region/tree}]]',
                         type: 'GET',
                         success: function (data) {
                             if (data.retcode == '0') {
@@ -126,7 +126,7 @@
             admin.popupCenter({
                 title: title,
                 area: ['400px', '600px'],
-                path: '/region/loadfunc'
+                path: '[[@{/region/loadfunc}]]'
             });
         };
         // 工具条点击事件
@@ -146,7 +146,7 @@
                 layer.close(i);
                 layer.load(2);
                 let token = $("meta[name='_csrf_token']").attr("value");
-                admin.go('/region/del', {
+                admin.go('[[@{/region/del}]]', {
                     areano: data.areano,
                     _csrf: token
                 }, function (data) {
@@ -155,7 +155,7 @@
                     if (data.retcode == 0) {
                         layer.msg(data.msg, {icon: 1});
                         $.ajax({
-                            url: '/region/tree',
+                            url: '[[@{/region/tree}]]',
                             type: 'GET',
                             success: function (data) {
                                 if (data.retcode == '0') {
@@ -179,7 +179,7 @@
                         });
                     } else if (data.retcode == 401) {
                         layer.msg(data.msg, {icon: 2, time: 1500}, function () {
-                            location.replace('/login');
+                            location.replace('[[@{/login}]]');
                         }, 1000);
                         return;
                     } else {
@@ -199,7 +199,7 @@
     //渲染数据
 
     $.ajax({
-        url: '/region/tree',
+        url: '[[@{/region/tree}]]',
         type: 'GET',
         success: function (data) {
             if (data.retcode == '0') {
@@ -217,7 +217,7 @@
                         , click: function (region) {
                             if (region.data.children.size != 0) {
                                 table.reload("regiontable", {
-                                    url: "/region/list/" + region.data.id
+                                    url: "[[@{/region/list/}]]" + region.data.id
                                     ,page: {
                                         curr: 1
                                     }