修改签约解约、二维码接口
diff --git a/backend/build.gradle b/backend/build.gradle
index 45c52ba..61a4f10 100644
--- a/backend/build.gradle
+++ b/backend/build.gradle
@@ -74,7 +74,7 @@
     compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.9.1'
     compile group: 'log4j', name: 'log4j', version: '1.2.17'
 
-    compile group: 'com.supwisdom', name: 'payapi-sdk', version: '1.0.25-4-g8c3fe54'
+    compile group: 'com.supwisdom', name: 'payapi-sdk', version: '1.0.26-1-g9a9f482'
     
     implementation 'org.hamcrest:hamcrest:2.1'
 }
diff --git a/backend/src/main/java/com/supwisdom/dlpay/portal/dao/impl/OutletsRepositoryImpl.java b/backend/src/main/java/com/supwisdom/dlpay/portal/dao/impl/OutletsRepositoryImpl.java
new file mode 100644
index 0000000..9349584
--- /dev/null
+++ b/backend/src/main/java/com/supwisdom/dlpay/portal/dao/impl/OutletsRepositoryImpl.java
@@ -0,0 +1,38 @@
+package com.supwisdom.dlpay.portal.dao.impl;
+
+import com.supwisdom.dlpay.framework.jpa.BaseRepository;
+import com.supwisdom.dlpay.framework.jpa.Finder;
+import com.supwisdom.dlpay.framework.jpa.page.Pagination;
+import com.supwisdom.dlpay.framework.util.StringUtil;
+import com.supwisdom.dlpay.portal.bean.OutletsSearchBean;
+import com.supwisdom.dlpay.portal.dao.OutletsRepository;
+import com.supwisdom.dlpay.portal.domain.TBOutlets;
+import org.hibernate.transform.Transformers;
+import org.jetbrains.annotations.NotNull;
+
+public class OutletsRepositoryImpl extends BaseRepository implements OutletsRepository {
+  @NotNull
+  @Override
+  public Pagination getOutletsList(@NotNull OutletsSearchBean bean) {
+    String name = bean.getName();
+    String address = bean.getAddress();
+    int pageno = bean.getPageno();
+    int pagesize = bean.getPagesize();
+    StringBuilder sql = new StringBuilder("select * from tb_outlets where 1=1");
+    if (!StringUtil.isEmpty(name)) {
+      sql.append(" and name like :name");
+    }
+    if (!StringUtil.isEmpty(address)) {
+      sql.append(" and address like :address");
+    }
+    sql.append(" order by outletsno desc");
+    Finder f = Finder.create(sql.toString());
+    if (!StringUtil.isEmpty(name)) {
+      f.setParameter("name", "%" + name.trim() + "%");
+    }
+    if (!StringUtil.isEmpty(address)) {
+      f.setParameter("address", "%" + address.trim() + "%");
+    }
+    return findNative(f, Transformers.aliasToBean(TBOutlets.class), pageno, pagesize);
+  }
+}
diff --git a/backend/src/main/java/com/supwisdom/dlpay/portal/domain/TBOutlets.java b/backend/src/main/java/com/supwisdom/dlpay/portal/domain/TBOutlets.java
index a459cc8..0493441 100644
--- a/backend/src/main/java/com/supwisdom/dlpay/portal/domain/TBOutlets.java
+++ b/backend/src/main/java/com/supwisdom/dlpay/portal/domain/TBOutlets.java
@@ -6,7 +6,7 @@
 
 @Entity
 @Table(name = "tb_outlets",
-    indexes = {@Index(name = "outlets_idx1", columnList = "outlesno"),
+    indexes = {@Index(name = "outlets_idx1", columnList = "outletsno"),
         @Index(name = "outlets_idx2", columnList = "name"),
         @Index(name = "outlets_idx3", columnList = "address")})
 public class TBOutlets {
@@ -16,8 +16,8 @@
   @Column(name = "id", nullable = false, length = 32)
   private String id;
 
-  @Column(name = "outlesno")
-  private String outlesno;
+  @Column(name = "outletsno")
+  private String outletsno;
 
   @Column(name = "name",length = 100)
   private String name;
@@ -31,9 +31,11 @@
   @Column(name = "endtime", length = 6)
   private String endtime;
 
-  @Column(name = "location",length = 20)
+  @Column(name = "location",length = 30)
   private String location;
 
+  @Column(name = "createtime",length = 14)
+  private String createtime;
 
   @Column(name = "businescope", length = 100)
   private String businescope;
@@ -49,12 +51,12 @@
     this.id = id;
   }
 
-  public String getOutlesno() {
-    return outlesno;
+  public String getOutletsno() {
+    return outletsno;
   }
 
-  public void setOutlesno(String outlesno) {
-    this.outlesno = outlesno;
+  public void setOutletsno(String outletsno) {
+    this.outletsno = outletsno;
   }
 
   public String getName() {
@@ -112,4 +114,12 @@
   public void setTel(String tel) {
     this.tel = tel;
   }
+
+  public String getCreatetime() {
+    return createtime;
+  }
+
+  public void setCreatetime(String createtime) {
+    this.createtime = createtime;
+  }
 }
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt
index bef3e3c..45f42cd 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt
@@ -517,69 +517,42 @@
         })
         if (cardResponse.retcode != 0) {
             logger.error { "查询卡片[${cardno}]信息失败:${cardResponse.retmsg}" }
-            return JsonResult.error("银行卡号有误")
+            return JsonResult.error("查询银行卡信息失败,请检查卡号是否正确")
         }
         val card = cardResponse.card
-        if (card.userid.isNullOrEmpty() || card.status != TradeDict.STATUS_NORMAL) {
-            return JsonResult.error("银行卡号信息有误")
-        }
-        val personResponse = userProxy.queryPerson(card.userid)
-        if (personResponse.retcode != 0) {
-            logger.error { "查询用户[${card.userid}]信息失败:${personResponse.retmsg}" }
-            return JsonResult.error("查询用户信息失败,请稍后重试")
-        }
-        val person = personResponse.person
-        if (person.name != name) {
-            return JsonResult.error("绑定信息有误[姓名]")
-        }
-        if (person.idtype != idtype || person.idno != idno) {
-            return JsonResult.error("绑定信息有误[证件类型/证件号]")
-        }
         val exsitUser = mobileApiService.findUserById(card.userid)
         if (exsitUser != null) {
             return JsonResult.error("该银行卡号已被绑定,若您本人绑定,请先解除绑定,若非本人,请联系客服")
         }
-        var signed = ""
-        //call api
-        var resp = citizencardPayService.bindCard(cardno, name, idtype, idno, phone)
-        if (resp.code != "0000") {
-            return JsonResult.error(resp.message)
+        val bindCardResult = userProxy.bindCard(BindCardParam().apply{
+            this.cardno = cardno
+            this.name = name
+            this.idtype = idtype
+            this.idno = idno
+            this.phone = user.phone
+        })
+        if (bindCardResult["retcode"] != 0) {
+            logger.error { "绑卡失败,${bindCardResult["retmsg"]}" }
+            return JsonResult.error("绑卡失败,${bindCardResult["retmsg"]}")
         }
-        var needupdate = false
-        if (resp.sinstatus == YnrccUtil.TRANSTYPE_SIGNCARD) {
-            signed = TradeDict.STATUS_YES
-            if (!card.signed) {
-                card.signed = true
-                val response = userProxy.updateCardSign(card.cardno, true)
-                if (response.retcode != 0) {
-                    logger.error { "更新卡片签约状态失败:${response.retmsg}" }
-                    return JsonResult.error("绑卡失败,请稍后重试")
-                }
-            }
-            user.signedtime = DateUtil.getNow();
+        val signed = bindCardResult["signed"] as String
+        if (TradeDict.STATUS_YES == signed) {
+            user.signedtime = DateUtil.getNow()
             mobileApiService.saveUser(user)
-            needupdate = true;
-
         }
         if (user.userid.isNullOrEmpty()) {
-            user.userid = person.userid
+            user.userid = card.userid
             user.bindtime = DateUtil.getNow()
-            needupdate = true
-        }
-        if (needupdate) {
             mobileApiService.saveUser(user)
         }
         var payseted = false
         if (!user.paypwd.isNullOrEmpty()) {
             payseted = true
         }
-
         return JsonResult.ok("OK").put("personid", card.userid)
                 ?.put("paypwdset", payseted)
                 ?.put("phonex", StringUtil.phoneReplace(phone))
                 ?.put("signed", signed)!!
-
-
     }
 
     /**
@@ -749,43 +722,19 @@
         if (user.phone.isNullOrEmpty()) {
             return JsonResult.error("用户不存在,请注册")
         }
-        var signed: String
         if (!user.userid.isNullOrEmpty()) {
-            val cardResponse = userProxy.queryCard(QueryCardParam().apply {
-                this.userid = user.userid
-                this.cardtype = ConstantUtil.CARDTYPE_BANKCARD
-            })
-            if (cardResponse.retcode != 0) {
-                logger.error { "查询用户[${user.userid}]卡片信息失败:${cardResponse.retmsg}" }
-                return JsonResult.error("卡片不存在,请重新绑定")
-            }
-            val card = cardResponse.card
-            val personResponse = userProxy.queryPerson(card.userid)
-            if (personResponse.retcode != 0) {
-                logger.error { "查询用户[${card.userid}]信息失败:${personResponse.retmsg}" }
-                return JsonResult.error("查询用户信息失败,请稍后重试")
-            }
-            val person = personResponse.person
-            //call sign api
-            val captcha = agree//此处为验证码,暂由此参数代替
-            var resp = citizencardPayService.signCard(card.cardno, person.name, person.idtype, person.idno, user.phone!!, YnrccUtil.TRANSTYPE_SIGNCARD, captcha)
-            if (resp.code != "0000") {
-                return JsonResult.error(resp.message)
-            }
-            card.signed = true
-            user.signedtime = DateUtil.getNow()
-            val response = userProxy.updateCardSign(card.cardno, true)
+            val response = userProxy.signbxy(user.userid, agree, user.phone)
             if (response.retcode != 0) {
-                logger.error { "更新卡片签约状态失败:${response.retmsg}" }
-                return JsonResult.error("签约银行协议失败,请稍后重试")
+                logger.error { "用户签约失败:${response.retmsg}" }
+                return JsonResult.error("签约失败,${response.retmsg}")
             }
+            user.signedtime = DateUtil.getNow()
             mobileApiService.saveUser(user)
-            signed = TradeDict.STATUS_YES
+            return JsonResult.ok("ok")
+                    .put("signed", TradeDict.STATUS_YES)!!
         } else {
             return JsonResult.error("请先绑定银行卡")
         }
-        return JsonResult.ok("ok")
-                .put("signed", signed)!!
     }
 
     /**
@@ -1096,12 +1045,24 @@
         val p = SecurityContextHolder.getContext().authentication
         val user = mobileApiService.findUserById(p.name)
                 ?: return JsonResult.error("用户不存在,请注册")
-        val resp = qrcodeService.encodeCode(user.uid)
-        return if (resp.retcode == 0) {
-            JsonResult.ok("ok").put("qrcode", resp.retmsg)!!
-        } else {
-            JsonResult.error(resp.retmsg)
+        if(TradeDict.STATUS_NORMAL!=user.status){
+            return JsonResult.error("用户状态异常")
         }
+        if(user.userid.isNullOrEmpty()){
+            return JsonResult.error("用户未绑定身份")
+        }
+        val qrcodeResult = userProxy.qrcode(QrcodeParam().apply {
+            this.uid = user.uid
+            this.userid = user.userid
+            this.rsapublic = user.rsapublic
+            this.secertkey = user.secertkey
+        })
+        if (qrcodeResult["retcode"] != 0) {
+            logger.error { "生成二维码失败,${qrcodeResult["retmsg"]}" }
+            return JsonResult.error("生成二维码失败,${qrcodeResult["retmsg"]}")
+        }
+        val qrcode = qrcodeResult["qrcode"] as String
+        return JsonResult.ok("ok").put("qrcode", qrcode)!!
     }
 
     /**
@@ -1109,45 +1070,43 @@
      * 解除银行协议
      * */
     @RequestMapping("/unsignbxy")
-    fun unSignbxy(): JsonResult {
+    fun unSignbxy(paypwd: String): JsonResult {
         val p = SecurityContextHolder.getContext().authentication
         val user = mobileApiService.findUserById(p.name)
                 ?: return JsonResult.error("用户不存在,请注册")
-        var signed: String
+        if (user.paypwd.isNullOrEmpty()) {
+            return JsonResult.error("支付密码未设置,请先设置")
+        }
+        val paypwdtimes = user.checkPaypwdtime()
+        if (paypwdtimes == -1) {
+            return JsonResult.error("支付密码错误次数过多,请30分钟后再试")
+        } else if (paypwdtimes == 1) {
+            mobileApiService.saveUser(user)
+        }
+        val encoder = BCryptPasswordEncoder()
+        if (!encoder.matches(paypwd, user.paypwd)) {
+            user.updatePaypwderror(false).also {
+                if (it) mobileApiService.saveUser(user)
+            }
+            return JsonResult.error("支付密码错误")
+        } else {
+            user.updatePaypwderror(true).also {
+                if (it) mobileApiService.saveUser(user)
+            }
+        }
         if (!user.userid.isNullOrEmpty()) {
-            val cardResponse = userProxy.queryCard(QueryCardParam().apply {
-                this.userid = user.userid
-                this.cardtype = ConstantUtil.CARDTYPE_BANKCARD
-            })
-            if (cardResponse.retcode != 0) {
-                logger.error { "查询用户[${user.userid}]卡片信息失败:${cardResponse.retmsg}" }
-                return JsonResult.error(-1, "银行卡不存在,不能解除代扣协议")
-            }
-            val card = cardResponse.card
-            //call sign api
-            val personResponse = userProxy.queryPerson(card.userid)
-            if (personResponse.retcode != 0) {
-                logger.error { "查询用户[${card.userid}]信息失败:${personResponse.retmsg}" }
-                return JsonResult.error("查询用户信息失败,请稍后重试")
-            }
-            val person = personResponse.person
-            val captcha = ""//此处为验证码,暂由此参数代替
-            var resp = citizencardPayService.signCard(card.cardno, person.name, person.idtype, person.idno, user.phone!!, YnrccUtil.TRANSTYPE_UNSIGNCARD, captcha)
-            if (resp.code != "0000") {
-                return JsonResult.error(resp.message)
-            }
-            card.signed = false
-            val response = userProxy.updateCardSign(card.cardno, false)
+            val response = userProxy.unsignbxy(user.userid, user.phone)
             if (response.retcode != 0) {
-                logger.error { "更新卡片签约状态失败:${response.retmsg}" }
-                return JsonResult.error("解除银行协议失败,请稍后重试")
+                logger.error { "用户解约失败:${response.retmsg}" }
+                return JsonResult.error("解约失败,${response.retmsg}")
             }
-            signed = TradeDict.STATUS_NO
+            user.userid = null
+            mobileApiService.saveUser(user)
+            return JsonResult.ok("ok")
+                    .put("signed", TradeDict.STATUS_NO)!!
         } else {
             return JsonResult.error("未绑定银行卡,不能解除代扣协议")
         }
-        return JsonResult.ok("ok")
-                .put("signed", signed)!!
     }
 
     /**
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt
index d5c5219..f4bd861 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt
@@ -46,6 +46,8 @@
     lateinit var uploadPicService: UploadPicService
     @Autowired
     lateinit var advisoryService: AdvisoryService
+    @Autowired
+    lateinit var outletsService: OutletsService
     val logger = KotlinLogging.logger { }
 
     @RequestMapping("/test")
@@ -392,4 +394,35 @@
             JsonResult.error("删除问答异常")
         }
     }
+
+    /**
+     * 保存网点
+     */
+    @RequestMapping(value = ["/outlets/save"], method = [RequestMethod.POST])
+    fun saveOutlets(@RequestBody outlets: TBOutlets): JsonResult? {
+        return try {
+            outletsService.saveOutlets(outlets)
+            JsonResult.ok()
+        } catch (e: Exception) {
+            logger.error { e.message }
+            JsonResult.error("保存网点异常")
+        }
+    }
+
+    /**
+     * 查询网点
+     */
+    @RequestMapping(value = ["/outlets/list"], method = [RequestMethod.GET])
+    fun getAdvisoryList(bean: OutletsSearchBean): JsonResult? {
+        return try {
+            val page = outletsService.getOutletsList(bean)
+            if (page.list == null || page.list.size == 0) {
+                return JsonResult.ok().put("msg", "无数据")
+            }
+            return JsonResult.ok().put("page", page)
+        } catch (e: Exception) {
+            logger.error { e.message }
+            JsonResult.error("查询网点列表异常")
+        }
+    }
 }
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/bean/OutletsSearchBean.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/bean/OutletsSearchBean.kt
new file mode 100644
index 0000000..e8b05fc
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/bean/OutletsSearchBean.kt
@@ -0,0 +1,8 @@
+package com.supwisdom.dlpay.portal.bean
+
+class OutletsSearchBean {
+    var name: String = ""
+    var address: String = ""
+    var pageno: Int = 1
+    var pagesize: Int = 10
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/OutletsDao.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/OutletsDao.kt
new file mode 100644
index 0000000..55c66cd
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/OutletsDao.kt
@@ -0,0 +1,10 @@
+package com.supwisdom.dlpay.portal.dao
+
+import com.supwisdom.dlpay.portal.domain.TBOutlets
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.stereotype.Repository
+
+@Repository
+interface OutletsDao :JpaRepository<TBOutlets,String>,OutletsRepository{
+
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/OutletsRepository.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/OutletsRepository.kt
new file mode 100644
index 0000000..23ecaf5
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/OutletsRepository.kt
@@ -0,0 +1,8 @@
+package com.supwisdom.dlpay.portal.dao
+
+import com.supwisdom.dlpay.framework.jpa.page.Pagination
+import com.supwisdom.dlpay.portal.bean.OutletsSearchBean
+
+interface OutletsRepository {
+    fun getOutletsList(bean: OutletsSearchBean): Pagination
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/OutletsServiceImpl.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/OutletsServiceImpl.kt
new file mode 100644
index 0000000..84b47ae
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/OutletsServiceImpl.kt
@@ -0,0 +1,40 @@
+package com.supwisdom.dlpay.portal.service.Impl
+
+import com.supwisdom.dlpay.framework.dao.BusinessparaDao
+import com.supwisdom.dlpay.framework.jpa.page.Pagination
+import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.framework.util.StringUtil
+import com.supwisdom.dlpay.portal.bean.OutletsSearchBean
+import com.supwisdom.dlpay.portal.dao.OutletsDao
+import com.supwisdom.dlpay.portal.domain.TBOutlets
+import com.supwisdom.dlpay.portal.service.OutletsService
+import com.supwisdom.dlpay.portal.util.PortalConstant
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Service
+
+@Service
+class OutletsServiceImpl : OutletsService {
+    @Autowired
+    lateinit var outletsDao: OutletsDao
+    @Autowired
+    lateinit var businessparaDao: BusinessparaDao
+    @Autowired
+    lateinit var systemUtilService: SystemUtilService
+
+    override fun saveOutlets(outlets: TBOutlets) {
+        if (StringUtil.isEmpty(outlets.id)) {
+            val currentNoBusiness = businessparaDao.findByParakey(PortalConstant.SYSPARA_OUTLETS_CURRENTNO)
+                    ?: throw RuntimeException("网点编号参数未配置")
+            val currentNo = currentNoBusiness.paraval.toInt()
+            currentNoBusiness.paraval = (currentNo + 1).toString()
+            businessparaDao.save(currentNoBusiness)
+            outlets.createtime = systemUtilService.sysdatetime.hostdatetime
+            outlets.outletsno = String.format("%06d", currentNo)
+        }
+        outletsDao.save(outlets)
+    }
+
+    override fun getOutletsList(bean: OutletsSearchBean): Pagination {
+        return outletsDao.getOutletsList(bean)
+    }
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/OutletsService.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/OutletsService.kt
new file mode 100644
index 0000000..927daf1
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/OutletsService.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.dlpay.portal.service
+
+import com.supwisdom.dlpay.framework.jpa.page.Pagination
+import com.supwisdom.dlpay.portal.bean.OutletsSearchBean
+import com.supwisdom.dlpay.portal.domain.TBOutlets
+import org.springframework.transaction.annotation.Transactional
+
+interface OutletsService {
+    @Transactional
+    fun saveOutlets(outlets: TBOutlets)
+    @Transactional
+    fun getOutletsList(bean: OutletsSearchBean): Pagination
+}
\ No newline at end of file