市民卡信息新增公交卡类型
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TCard.java b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TCard.java
index 02e6bf9..d21ff59 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TCard.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TCard.java
@@ -30,6 +30,9 @@
   @Column(name = "TRANS_STATUS", nullable = false, length = 20)
   private String transStatus; //normal/loss/frozen/locked/abnormal/unuse
 
+  @Column(name = "BUS_CARD_TYPE", length = 20)
+  private String busCardType; //市民卡的公交卡类型
+
   @Column(name = "EXPIREDATE", length = 20)
   private String expiredate;
 
@@ -49,12 +52,13 @@
   public TCard() {
   }
 
-  public TCard(String cardno, String cardtype, String cardphyid, String status, String transStatus, String expiredate, Boolean signed, String userid, String lastsaved) {
+  public TCard(String cardno, String cardtype, String cardphyid, String status, String transStatus, String busCardType, String expiredate, Boolean signed, String userid, String lastsaved) {
     this.cardno = cardno;
     this.cardtype = cardtype;
     this.cardphyid = cardphyid;
     this.status = status;
     this.transStatus = transStatus;
+    this.busCardType = busCardType;
     this.expiredate = expiredate;
     this.signed = signed;
     this.userid = userid;
@@ -109,6 +113,14 @@
     this.transStatus = transStatus;
   }
 
+  public String getBusCardType() {
+    return busCardType;
+  }
+
+  public void setBusCardType(String busCardType) {
+    this.busCardType = busCardType;
+  }
+
   public String getExpiredate() {
     return expiredate;
   }
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TCitycardTemp.java b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TCitycardTemp.java
index 7d7f454..97a48d7 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TCitycardTemp.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TCitycardTemp.java
@@ -46,6 +46,9 @@
   @Column(name = "EMAIL", length = 60)
   private String email;
 
+  @Column(name = "BUS_CARD_TYPE", length = 20)
+  private String busCardType;
+
   @Column(name = "STATUS", length = 20)
   private String status;
 
@@ -185,4 +188,12 @@
   public void setTenantid(String tenantid) {
     this.tenantid = tenantid;
   }
+
+  public String getBusCardType() {
+    return busCardType;
+  }
+
+  public void setBusCardType(String busCardType) {
+    this.busCardType = busCardType;
+  }
 }
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/Dictionary.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/Dictionary.java
index 9eac02d..6798ebc 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/Dictionary.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/Dictionary.java
@@ -8,6 +8,7 @@
   public static final String SEX = "sexList";
   public static final String ACCOUNT_STATUS = "accountStatusList";
   public static final String DTLTYPES = "dtltypeList";
+  public static final String BUSCARDTYPES = "busCardTypeList";
 
   /////////////////////////////////////
   public static final String SOURCE_TYPE = "sourcetypeList";
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/StringUtil.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/StringUtil.java
index ff4084c..180679b 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/StringUtil.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/StringUtil.java
@@ -272,5 +272,16 @@
 //    return bankCard.charAt(bankCard.length() - 1) == bit;
   }
 
+  /**
+   * 根据卡号创建8位16进制卡物理ID
+   * */
+  public static String createCardphyid(int cardno) {
+    String hex = Integer.toHexString(cardno);
+    while (hex.length() < 8) {
+      hex = "0" + hex;
+    }
+    return hex.toUpperCase();
+  }
+
 
 }
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/system/bean/CitizenCardShowBean.java b/payapi/src/main/java/com/supwisdom/dlpay/system/bean/CitizenCardShowBean.java
index 5f4961b..17fd877 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/system/bean/CitizenCardShowBean.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/system/bean/CitizenCardShowBean.java
@@ -18,6 +18,7 @@
   private String mobile;
   private String email;
   private String sex;
+  private String buscardtype;
 
   public String getCid() {
     return cid;
@@ -154,4 +155,12 @@
   public void setSex(String sex) {
     this.sex = sex;
   }
+
+  public String getBuscardtype() {
+    return buscardtype;
+  }
+
+  public void setBuscardtype(String buscardtype) {
+    this.buscardtype = buscardtype;
+  }
 }
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/system/controller/UserController.java b/payapi/src/main/java/com/supwisdom/dlpay/system/controller/UserController.java
index eb36de9..4c35709 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/system/controller/UserController.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/system/controller/UserController.java
@@ -210,9 +210,10 @@
                                    @RequestParam(value = "idtype", required = false) String idtype,
                                    @RequestParam(value = "idno", required = false) String idno,
                                    @RequestParam(value = "mobile", required = false) String mobile,
-                                   @RequestParam(value = "email", required = false) String email) {
+                                   @RequestParam(value = "email", required = false) String email,
+                                   @RequestParam(value = "buscardtype", required = false) String buscardtype) {
     try {
-      if (userDataService.doSaveNewCitizenCard(cardno, cardphyid, expiredate, cardstatus, bankcardno, signstatus, username, sex, idtype, idno, mobile, email)) {
+      if (userDataService.doSaveNewCitizenCard(cardno, cardphyid, expiredate, cardstatus, bankcardno, signstatus, username, sex, idtype, idno, mobile, email, buscardtype)) {
         return JsonResult.ok("新增成功!");
       } else {
         return JsonResult.error("新增失败!");
@@ -264,9 +265,10 @@
                                    @RequestParam(value = "idtype", required = false) String idtype,
                                    @RequestParam(value = "idno", required = false) String idno,
                                    @RequestParam(value = "mobile", required = false) String mobile,
-                                   @RequestParam(value = "email", required = false) String email) {
+                                   @RequestParam(value = "email", required = false) String email,
+                                   @RequestParam(value = "buscardtype", required = false) String buscardtype) {
     try {
-      if (userDataService.doUpdateCitizenCard(cid, bkid, cardno, cardphyid, expiredate, cardstatus, bankcardno, signstatus, username, sex, idtype, idno, mobile, email)) {
+      if (userDataService.doUpdateCitizenCard(cid, bkid, cardno, cardphyid, expiredate, cardstatus, bankcardno, signstatus, username, sex, idtype, idno, mobile, email, buscardtype)) {
         return JsonResult.ok("修改成功!");
       } else {
         return JsonResult.error("修改失败!");
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/system/service/UserDataService.java b/payapi/src/main/java/com/supwisdom/dlpay/system/service/UserDataService.java
index 8cc7a5b..e463ae5 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/system/service/UserDataService.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/system/service/UserDataService.java
@@ -50,12 +50,12 @@
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
     boolean doSaveNewCitizenCard(String cardno, String cardphyid, String expiredate, String cardstatus, String bankcardno,
                                  String signstatus, String username, String sex, String idtype, String idno, String mobile,
-                                 String email) throws Exception;
+                                 String email, String buscardtype) throws Exception;
 
 
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
     boolean doUpdateCitizenCard(String cid, String bkid, String cardno, String cardphyid, String expiredate, String cardstatus,
                                 String bankcardno, String signstatus, String username, String sex, String idtype, String idno,
-                                String mobile, String email) throws Exception;
+                                String mobile, String email, String buscardtype) throws Exception;
 
 }
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java b/payapi/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java
index 01105f8..a7ed10e 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java
@@ -196,7 +196,7 @@
 
   @Override
   public PageResult<CitizenCardShowBean> getUserCitizenCardPage(CitizenCardSearchBean param, int pageNo, int pageSize) {
-    StringBuffer querySql = new StringBuffer("select t.id as cid,t.cardno,t.cardtype,t.cardphyid,case when t.status='closed' then 'closed' else t.trans_status end as status,t.expiredate,a.id as bkid,a.cardno as bankcardno,a.signed,t.lastsaved,t.userid,p.name as username,p.idtype,p.idno,p.mobile,p.email,p.sex \n" +
+    StringBuffer querySql = new StringBuffer("select t.id as cid,t.cardno,t.cardtype,t.cardphyid,case when t.status='closed' then 'closed' else t.trans_status end as status,t.expiredate,a.id as bkid,a.cardno as bankcardno,a.signed,t.lastsaved,t.userid,p.name as username,p.idtype,p.idno,p.mobile,p.email,p.sex,t.bus_card_type as buscardtype \n" +
         "from tb_card t left join tb_card a on a.cardtype='bankcard' and a.cardphyid=t.cardphyid and a.userid=t.userid left join tb_person p on p.userid=t.userid \n" +
         "where t.cardtype='citizencard' ");
     StringBuffer countSql = new StringBuffer("select count(t.id) as cnt \n" +
@@ -255,7 +255,7 @@
 
   private boolean checkCitizenCardData(String cardno, String cardphyid, String expiredate, String cardstatus, String bankcardno,
                                        String signstatus, String username, String sex, String idtype, String idno, String mobile,
-                                       String email) throws WebCheckException {
+                                       String email, String buscardtype) throws WebCheckException {
     if (StringUtil.isEmpty(cardno)) throw new WebCheckException("市民卡号不能为空");
     if (!StringUtil.isNumber(cardno.trim())) throw new WebCheckException("请正确填写市民卡号");
 
@@ -290,14 +290,15 @@
 
     if (!StringUtil.isEmpty(mobile) && !StringUtil.isMobile(mobile.trim())) throw new WebCheckException("请正确填写手机号");
     if (!StringUtil.isEmpty(email) && !StringUtil.isEmail(email.trim())) throw new WebCheckException("请正确填写电子邮箱");
+    if (StringUtil.isEmpty(buscardtype)) throw new WebCheckException("请选择公交卡类型");
     return true;
   }
 
   @Override
   public boolean doSaveNewCitizenCard(String cardno, String cardphyid, String expiredate, String cardstatus, String bankcardno,
                                       String signstatus, String username, String sex, String idtype, String idno, String mobile,
-                                      String email) throws Exception {
-    if (checkCitizenCardData(cardno, cardphyid, expiredate, cardstatus, bankcardno, signstatus, username, sex, idtype, idno, mobile, email)) {
+                                      String email, String buscardtype) throws Exception {
+    if (checkCitizenCardData(cardno, cardphyid, expiredate, cardstatus, bankcardno, signstatus, username, sex, idtype, idno, mobile, email, buscardtype)) {
       double maxbal = systemUtilService.getSysparaValueAsDouble(SysparaUtil.BALANCE_LIMIT, SysparaUtil.DEFAULT_BALANCE_LIMIT);
       double lowfreeLimit = systemUtilService.getSysparaValueAsDouble(SysparaUtil.NOPASS_LIMIT, SysparaUtil.DEFAULT_NOPASS_LIMIT);
       double daylimit = systemUtilService.getSysparaValueAsDouble(SysparaUtil.DAY_PAY_LIMIT, SysparaUtil.DEFAULT_DAY_PAY_LIMIT);
@@ -385,6 +386,7 @@
       cityCard.setUserid(person.getUserid());
       cityCard.setLastsaved(dt.getHostdatetime());
       cityCard.setTenantid(person.getTenantid());
+      cityCard.setBusCardType(buscardtype.trim());
       cardDao.save(cityCard);
 
       bankCard = new TCard(); //新增银行卡
@@ -404,6 +406,7 @@
       if (TradeDict.STATUS_NORMAL.equals(bankCard.getStatus())) {
         cardDao.closedBankcardStatusByUserid(bankCard.getUserid());  //注销其他银行卡
       }
+      bankCard.setBusCardType(buscardtype.trim());
       cardDao.save(bankCard);
       return true;
     }
@@ -418,7 +421,7 @@
   @Override
   public boolean doUpdateCitizenCard(String cid, String bkid, String cardno, String cardphyid, String expiredate, String cardstatus,
                                      String bankcardno, String signstatus, String username, String sex, String idtype, String idno,
-                                     String mobile, String email) throws Exception {
+                                     String mobile, String email, String buscardtype) throws Exception {
     TCard cityCard = findCardById(cid);
     TCard bankCard = findCardById(bkid);
     if (null == cityCard || null == bankCard ||
@@ -431,7 +434,7 @@
     TPerson person = personDao.findByUserid(cityCard.getUserid());
     if(null==person) throw new WebCheckException("请求参数错误,请重新查询!");
 
-    if (checkCitizenCardData(cardno, cardphyid, expiredate, cardstatus, bankcardno, signstatus, username, sex, idtype, idno, mobile, email)) {
+    if (checkCitizenCardData(cardno, cardphyid, expiredate, cardstatus, bankcardno, signstatus, username, sex, idtype, idno, mobile, email, buscardtype)) {
       TPerson owner = null; //市民卡拥有者
       SystemDateTime dt = systemUtilService.getSysdatetime();
       if(idtype.trim().equals(person.getIdtype()) && idno.trim().equals(person.getIdno())){
@@ -539,7 +542,10 @@
         cityCard.setUserid(owner.getUserid());
         cardUpdate = true;
       }
-
+      if (!buscardtype.trim().equals(cityCard.getBusCardType())) {
+        cityCard.setBusCardType(buscardtype.trim());
+        cardUpdate = true;
+      }
       if(cardUpdate){
         cityCard.setLastsaved(dt.getHostdatetime());
         cardDao.save(cityCard);
@@ -569,6 +575,10 @@
         bankCard.setUserid(cityCard.getUserid());
         bankcardUpdate = true;
       }
+      if (!buscardtype.trim().equals(bankCard.getBusCardType())) {
+        bankCard.setBusCardType(buscardtype.trim());
+        bankcardUpdate = true;
+      }
 
       if(bankcardUpdate){
         bankCard.setLastsaved(dt.getHostdatetime());
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/citizencard_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/citizencard_service_impl.kt
index 1dbd5c7..0d97656 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/citizencard_service_impl.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/citizencard_service_impl.kt
@@ -236,10 +236,7 @@
             return if (200 == respClient.status) {
                 val jsonStr = respClient.getEntity(String::class.java)
                 logger.error("refno=[$refno], url=[$url], return=[$jsonStr]")
-//                resp = Gson().fromJson(jsonStr, DlpayResp::class.java)
-                resp = DlpayResp().apply {
-                    code="0000"
-                }
+                resp = Gson().fromJson(jsonStr, DlpayResp::class.java)
                 resp
             } else {
                 resp.code = "99"
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
index 5eef7e5..21edbe8 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
@@ -59,7 +59,7 @@
 
 class DaliDatasyncDetail {
     var cardno: String = ""
-    var cardphyid: String = ""
+    var cardphyid: String? = null //fixme:物理卡号可能为空!
     var expiredate: String = ""
     var cardstatus: String = ""
     var bankcardno: String? = null
@@ -69,10 +69,12 @@
     var idno: String = ""
     var mobile: String? = null
     var email: String? = null
+    var cardType: String = ""
 
     fun checkParam(): Boolean {
         if (StringUtil.isEmpty(idtype) || StringUtil.isEmpty(idno) || StringUtil.isEmpty(username)) throw RequestParamCheckException("用户明细数据关键字段为空")
-        if (StringUtil.isEmpty(cardno) || StringUtil.isEmpty(cardphyid) || StringUtil.isEmpty(expiredate) || StringUtil.isEmpty(cardstatus)) throw RequestParamCheckException("卡片明细数据关键字段为空")
+        if (StringUtil.isEmpty(cardno) || StringUtil.isEmpty(expiredate) || StringUtil.isEmpty(cardstatus)) throw RequestParamCheckException("卡片明细数据关键字段为空")
+        if (StringUtil.isEmpty(cardType)) throw RequestParamCheckException("卡片的公交卡类型字段值为空")
         return true
     }
 }
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
index 6779e80..657b64d 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
@@ -234,8 +234,6 @@
         val dtl = transactionService.wip(param.refno)
         val service = createAgentService<DtlStatus>(TradeDict.PAYTYPE_CITIZEN_CARD)
         val resp = service.pay(dtl)
-        resp.code = AgentCode.SUCCESS
-        resp.agentRefno = systemUtilService.refno
         when (resp.code) {
             AgentCode.SUCCESS ->
                 transactionService.success(dtl.refno, resp.agentRefno, false).let {
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/card_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/card_service_impl.kt
index 9a0c135..79dbbb9 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/card_service_impl.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/card_service_impl.kt
@@ -6,7 +6,11 @@
 import com.supwisdom.dlpay.api.domain.TCard
 import com.supwisdom.dlpay.api.domain.TPerson
 import com.supwisdom.dlpay.api.service.CardService
+import com.supwisdom.dlpay.citizencard.dao.CitizencardLossApplyDao
+import com.supwisdom.dlpay.citizencard.domain.TCitizencardLossApply
 import com.supwisdom.dlpay.exception.TransactionProcessException
+import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.framework.util.Constants
 import com.supwisdom.dlpay.framework.util.StringUtil
 import com.supwisdom.dlpay.framework.util.TradeDict
 import com.supwisdom.dlpay.framework.util.TradeErrorCode
@@ -24,6 +28,10 @@
     lateinit var cardDao: CardDao
     @Autowired
     lateinit var personDao: PersonDao
+    @Autowired
+    lateinit var citizencardLossApplyDao:CitizencardLossApplyDao
+    @Autowired
+    lateinit var systemUtilService: SystemUtilService
 
     @PersistenceContext
     private lateinit var entityManager: EntityManager
@@ -163,9 +171,9 @@
 
     override fun getCardByCardNoOrUserid(param: QueryCardParam): TCard? {
         if (!StringUtil.isEmpty(param.cardno)) {
-            return cardDao.findCardByCardnoAndCardtype(param.cardno,param.cardtype)
+            return cardDao.findCardByCardnoAndCardtype(param.cardno, param.cardtype)
         }else if (!StringUtil.isEmpty(param.userid)) {
-            return cardDao.findCardByUseridAndCardtype(param.userid,param.cardtype)
+            return cardDao.findCardByUseridAndCardtype(param.userid, param.cardtype)
         }
         return null
     }
@@ -193,7 +201,23 @@
         val card = cardDao.findCardByCardnoAndCardtype(cardno, ConstantUtil.CARDTYPE_BANKCARD)
                 ?: return result
         card.transStatus = status
+        card.lastsaved = systemUtilService.sysdatetime.hostdatetime
         cardDao.save(card)
+        if (TradeDict.STATUS_LOST == status) {
+            //保存挂失申请,异步通知卡管系统
+            cardDao.findBankcardByCitizencard(card.userid, ConstantUtil.CARDTYPE_CITIZENCARD, card.cardphyid)?.let { cityCard ->
+                citizencardLossApplyDao.save(TCitizencardLossApply().apply {
+                    this.refno = systemUtilService.refno
+                    this.cardno = cityCard.cardno //银行卡对应的市民卡号
+                    this.applytime = systemUtilService.sysdatetime.hostdatetime
+                    this.termtype = "app"
+                    this.status = ConstantUtil.CITIZENCARD_LOSSAPPLY_STATUS_APPLY
+                    this.sendcnt = 0
+                    this.lastsaved = systemUtilService.sysdatetime.sysdate
+                    this.tenantId = card.tenantid ?: Constants.DEFAULT_TENANTID
+                })
+            }
+        }
         return result.apply {
             this.retcode = 0
             this.retmsg = "ok"
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/dali_datasync_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/dali_datasync_service_impl.kt
index 96b13f8..ff32235 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/dali_datasync_service_impl.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/dali_datasync_service_impl.kt
@@ -146,7 +146,7 @@
                     cityCard.status = TradeDict.STATUS_CLOSED
                 }
             } else {
-                //卡片的其他状态,代表交易状态
+                //卡片的其他状态,代表交易状态。主状态改为正常,交易状态覆盖
                 if (TradeDict.STATUS_NORMAL != cityCard.transStatus) {
                     cardUpdateFlag = true
                     cityCard.status = TradeDict.STATUS_NORMAL
@@ -157,6 +157,12 @@
                 }
             }
 
+            //fixme: 公交卡类型
+            if (bean.cardType.trim() != cityCard.busCardType) {
+                cardUpdateFlag = true
+                cityCard.busCardType = bean.cardType.trim()
+            }
+
             if (cardUpdateFlag) {
                 cityCard.lastsaved = systime.hostdatetime
                 cardDao.save(cityCard) //更新
@@ -165,7 +171,10 @@
             cityCard = TCard().apply {
                 cardno = bean.cardno.trim()
                 cardtype = ConstantUtil.CARDTYPE_CITIZENCARD
-                cardphyid = bean.cardphyid.trim()
+                cardphyid = when (bean.cardphyid.isNullOrBlank()) {
+                    true -> bean.cardno.trim()
+                    false -> bean.cardphyid!!.trim()
+                }
                 status = when (TradeDict.STATUS_CLOSED == cardStatus) {
                     true -> TradeDict.STATUS_CLOSED
                     false -> TradeDict.STATUS_NORMAL
@@ -174,6 +183,7 @@
                     true -> TradeDict.STATUS_ABNORMAL
                     false -> cardStatus
                 }
+                busCardType = bean.cardType.trim()
                 expiredate = bean.expiredate.trim()
                 signed = false
                 userid = person.userid
@@ -189,12 +199,19 @@
                 bankCard = TCard().apply {
                     cardno = bean.bankcardno!!.trim()
                     cardtype = ConstantUtil.CARDTYPE_BANKCARD
-                    cardphyid = bean.cardphyid.trim()
+                    cardphyid = when (bean.cardphyid.isNullOrBlank()) {
+                        true -> bean.cardno.trim()
+                        false -> bean.cardphyid!!.trim()
+                    }
                     status = when (TradeDict.STATUS_CLOSED == cardStatus) {
                         true -> TradeDict.STATUS_CLOSED
                         false -> TradeDict.STATUS_NORMAL
                     }
-                    transStatus = TradeDict.STATUS_NORMAL
+                    transStatus = when (TradeDict.STATUS_CLOSED == cardStatus) {
+                        true -> TradeDict.STATUS_ABNORMAL
+                        false -> cardStatus
+                    }
+                    busCardType = bean.cardType.trim()
                     expiredate = "21991231"
                     signed = false
                     userid = person.userid
@@ -209,6 +226,36 @@
                 if (bankCard.userid != person.userid) {
                     throw TransactionProcessException(3000, "银行卡已被人绑定")
                 }
+
+                var bankUpdate = false
+                if (TradeDict.STATUS_CLOSED == cardStatus) {
+                    //注销卡片
+                    if (bankCard.status != TradeDict.STATUS_CLOSED) {
+                        bankUpdate = true
+                        bankCard.status = TradeDict.STATUS_CLOSED
+                    }
+                } else {
+                    //卡片的其他状态,代表交易状态。主状态改为正常,交易状态覆盖
+                    if (TradeDict.STATUS_NORMAL != bankCard.transStatus) {
+                        bankUpdate = true
+                        bankCard.status = TradeDict.STATUS_NORMAL
+                    }
+                    if (cardStatus != bankCard.transStatus) {
+                        bankUpdate = true
+                        bankCard.transStatus = cardStatus
+                    }
+                }
+
+                //fixme: 公交卡类型
+                if (bean.cardType.trim() != bankCard.busCardType) {
+                    bankUpdate = true
+                    bankCard.busCardType = bean.cardType.trim()
+                }
+
+                if(bankUpdate){
+                    bankCard.lastsaved = systime.hostdatetime
+                    cardDao.save(bankCard) //更新
+                }
             }
         }
 
@@ -236,6 +283,7 @@
             this.idno = bean.idno
             this.mobile = bean.mobile
             this.email = bean.email
+            this.busCardType = bean.cardType
             this.status = TradeDict.DTL_STATUS_FAIL
             this.remark = errmsg
             this.lastsaved = systemUtilService.sysdatetime.hostdatetime
@@ -264,6 +312,7 @@
             this.idno = temp.idno
             this.mobile = temp.mobile
             this.email = temp.email
+            this.cardType = temp.busCardType
         }
         bean.checkParam()
         if (doUpdateUserInfos(bean)) {
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/qrcode_srvice_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/qrcode_srvice_impl.kt
index b195422..38b6374 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/qrcode_srvice_impl.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/qrcode_srvice_impl.kt
@@ -4,6 +4,7 @@
 import com.supwisdom.dlpay.api.bean.ApiResponse
 import com.supwisdom.dlpay.api.bean.DoorQrcodeResponse
 import com.supwisdom.dlpay.api.bean.QrcodeParam
+import com.supwisdom.dlpay.api.service.CardService
 import com.supwisdom.dlpay.api.service.QRCodeService
 import com.supwisdom.dlpay.api.service.UserService
 import com.supwisdom.dlpay.framework.service.SystemUtilService
@@ -27,6 +28,8 @@
     @Autowired
     lateinit var userService: UserService
     @Autowired
+    lateinit var cardService: CardService
+    @Autowired
     lateinit var redisTemplate: RedisTemplate<String, String>
 
     val logger = KotlinLogging.logger { }
@@ -51,6 +54,17 @@
             resp.retmsg = "用户未绑定身份"
             return resp
         }
+        val bankCard = cardService.getBankcardByUserid(muser.userid!!)
+        if (null == bankCard) {
+            resp.retcode = 1
+            resp.retmsg = "用户未绑定银行卡"
+            return resp
+        } else if (!bankCard.signed) {
+            resp.retcode = 1
+            resp.retmsg = "银行卡未签约"
+            return resp
+        }
+
         val totp = QrCodeTotpUtil.generateTOTP(muser.secertkey)
         val rowdata = QrcodeRawData()
         rowdata.userid = muser.userid
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt
index 299fd7f..8de6f1e 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt
@@ -6,6 +6,8 @@
 import com.supwisdom.dlpay.api.service.QRCodeService
 import com.supwisdom.dlpay.api.service.UserService
 import com.supwisdom.dlpay.api.util.MobileNumberCheck
+import com.supwisdom.dlpay.citizencard.domain.TCitizencardLossApply
+import com.supwisdom.dlpay.citizencard.service.CitizencardManagerService
 import com.supwisdom.dlpay.framework.core.JwtConfig
 import com.supwisdom.dlpay.framework.core.JwtTokenUtil
 import com.supwisdom.dlpay.framework.domain.JwtRedis
@@ -267,6 +269,10 @@
     lateinit var jwtConfig: JwtConfig
     @Autowired
     lateinit var qrcodeService:QRCodeService
+    @Autowired
+    lateinit var citizencardManagerService: CitizencardManagerService
+    @Autowired
+    lateinit var systemUtilService: SystemUtilService
     val logger = KotlinLogging.logger { }
 
     @RequestMapping("/idtypes")
@@ -850,6 +856,19 @@
         }
         card.transStatus = TradeDict.STATUS_LOST
         mobileApiService.saveCard(card)
+        mobileApiService.findCardByUseridAndCardphyid(card.userid, ConstantUtil.CARDTYPE_CITIZENCARD, card.cardphyid)?.let { cityCard ->
+            citizencardManagerService.saveOrUpdateCitizencardLossApply(TCitizencardLossApply().apply {
+                this.refno = systemUtilService.refno
+                this.cardno = cityCard.cardno //银行卡对应的市民卡号
+                this.applytime = systemUtilService.sysdatetime.hostdatetime
+                this.termtype = "app"
+                this.uid = user.uid
+                this.status = ConstantUtil.CITIZENCARD_LOSSAPPLY_STATUS_APPLY
+                this.sendcnt = 0
+                this.lastsaved = systemUtilService.sysdatetime.sysdate
+                this.tenantId = card.tenantid ?: Constants.DEFAULT_TENANTID
+            })
+        }
         return JsonResult.ok("ok")
     }
 
diff --git a/payapi/src/main/resources/static/libs/custom.js b/payapi/src/main/resources/static/libs/custom.js
index 0307a2d..8c81562 100644
--- a/payapi/src/main/resources/static/libs/custom.js
+++ b/payapi/src/main/resources/static/libs/custom.js
@@ -67,6 +67,7 @@
                     .addNewDict("accountStatusList")
                     .addNewDict("allSubjectList")
                     .addNewDict("transcodeList")
+                    .addNewDict("busCardTypeList")
             },
             getDict: function (dictType) {
                 var dict, that = this;
diff --git a/payapi/src/main/resources/templates/system/user/addcard.html b/payapi/src/main/resources/templates/system/user/addcard.html
index 0151106..1fb8fc1 100644
--- a/payapi/src/main/resources/templates/system/user/addcard.html
+++ b/payapi/src/main/resources/templates/system/user/addcard.html
@@ -120,6 +120,21 @@
         </div>
     </div>
 
+    <div class="layui-form-item">
+        <div class="layui-inline">
+            <label class="layui-form-label"><span style="color: red;">*</span>公交卡类型</label>
+            <div class="layui-input-inline">
+                <select name="buscardtype" class="layui-input layui-select" lay-verify="required">
+                    <option value="80" selected>80_普通卡</option>
+                    <option value="81" selected>81_学生卡</option>
+                    <option value="82" selected>82_老年卡</option>
+                    <option value="83" selected>83_爱心卡</option>
+                    <option value="84" selected>84_阳光卡</option>
+                </select>
+            </div>
+        </div>
+    </div>
+
     <div class="layui-form-item model-form-footer">
         <button class="layui-btn" lay-filter="citizencard-add-form-submit" lay-submit  id="citizencard-add-ok">保存</button>
         <button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">取消</button>
diff --git a/payapi/src/main/resources/templates/system/user/card.html b/payapi/src/main/resources/templates/system/user/card.html
index 251daa4..1759183 100644
--- a/payapi/src/main/resources/templates/system/user/card.html
+++ b/payapi/src/main/resources/templates/system/user/card.html
@@ -81,12 +81,18 @@
             url: '[[@{/user/cardlist}]]',
             page: true,
             toolbar: '#citizencard-table-toolbar',
+            defaultToolbar: ['filter'],
             cols: [
                 [
                     {type:'radio', align: 'center', width: 35, fixed: 'left'},
                     {field:'cardno',title:'市民卡号', align: 'center', width: 120, fixed: 'left', sort: true},
                     {field:'cardphyid',title:'物理卡号', align: 'center', width: 120, fixed: 'left'},
                     {
+                        field: 'buscardtype', title: '公交卡类型', align: 'center', width: 100, templet: function (d) {
+                          return getTempDictValue('busCardTypeList', d.buscardtype);
+                        }
+                    },
+                    {
                         field: 'expiredate', title: '有效期', align: 'center', width: 120, templet: function (d) {
                             return dateFormat('' + d.expiredate);
                         }
diff --git a/payapi/src/main/resources/templates/system/user/updatecard.html b/payapi/src/main/resources/templates/system/user/updatecard.html
index 7e1cb74..49d0002 100644
--- a/payapi/src/main/resources/templates/system/user/updatecard.html
+++ b/payapi/src/main/resources/templates/system/user/updatecard.html
@@ -122,6 +122,21 @@
         </div>
     </div>
 
+    <div class="layui-form-item">
+        <div class="layui-inline">
+            <label class="layui-form-label"><span style="color: red;">*</span>公交卡类型</label>
+            <div class="layui-input-inline">
+                <select name="buscardtype" class="layui-input layui-select" lay-verify="required">
+                    <option value="80" selected>80_普通卡</option>
+                    <option value="81" selected>81_学生卡</option>
+                    <option value="82" selected>82_老年卡</option>
+                    <option value="83" selected>83_爱心卡</option>
+                    <option value="84" selected>84_阳光卡</option>
+                </select>
+            </div>
+        </div>
+    </div>
+
     <div class="layui-form-item model-form-footer">
         <button class="layui-btn" lay-filter="citizencard-modify-form-submit" lay-submit  id="citizencard-modify-ok">保存</button>
         <button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">取消</button>
@@ -159,7 +174,8 @@
                 idtype:cardBean.idtype,
                 idno:cardBean.idno,
                 mobile:cardBean.mobile,
-                email:cardBean.email
+                email:cardBean.email,
+                buscardtype:cardBean.buscardtype
             });
         }