卡管信息接收接口完善
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 41dba29..02e6bf9 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
@@ -28,7 +28,7 @@
   private String status; //normal/closed
 
   @Column(name = "TRANS_STATUS", nullable = false, length = 20)
-  private String transStatus; //normal/loss/frozen/locked
+  private String transStatus; //normal/loss/frozen/locked/abnormal/unuse
 
   @Column(name = "EXPIREDATE", length = 20)
   private String expiredate;
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
index 4676ca5..1e026eb 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
@@ -8,12 +8,16 @@
    * locked -- 锁定、冻结
    * frozen -- 冻结
    * lost -- 挂失
+   * unuse -- 未使用,未启用
+   * abnormal -- 异常
    */
   public static final String STATUS_NORMAL = "normal";
   public static final String STATUS_CLOSED = "closed";
   public static final String STATUS_LOCKED = "locked";
   public static final String STATUS_LOST = "lost";
   public static final String STATUS_FROZEN = "frozen";
+  public static final String STATUS_UNUSE = "unuse";
+  public static final String STATUS_ABNORMAL = "abnormal";
 
   public static final String STATUS_YES = "yes";
   public static final String STATUS_NO = "no";
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 2b19d6f..5eef7e5 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
@@ -8,6 +8,7 @@
 
 class DaliDatasyncParam {
     var app_id: String = ""
+    val trans_code: String = ""
     var data: String = ""
     var count: Int = 0
     var timestamp: String = ""
@@ -18,6 +19,9 @@
         if (StringUtil.isEmpty(app_id)) {
             throw RequestParamCheckException("请求参数错误[应用ID为空]")
         }
+        if(StringUtil.isEmpty(trans_code)){
+            throw RequestParamCheckException("请求参数错误[交易类型为空]")
+        }
         if (StringUtil.isEmpty(data)) {
             throw RequestParamCheckException("请求参数错误[业务参数报文为空]")
         }
@@ -37,7 +41,7 @@
     }
 
     fun checkSign(key: String): Boolean {
-        val signData = "app_id=$app_id&count=$count&data=$data&timestamp=$timestamp"
+        val signData = "app_id=$app_id&count=$count&data=$data&timestamp=$timestamp&trans_code=$trans_code"
         return sign.equals(HmacUtil.HMACSHA256(signData, key), true)
     }
 
@@ -60,6 +64,7 @@
     var cardstatus: String = ""
     var bankcardno: String? = null
     var username: String = ""
+    var sex: String? = null
     var idtype: String = ""
     var idno: String = ""
     var mobile: String? = null
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/dali_datasync_api_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/dali_datasync_api_controller.kt
index 248c831..80a9ca9 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/dali_datasync_api_controller.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/dali_datasync_api_controller.kt
@@ -35,24 +35,27 @@
             val deskey = systemUtilService.getSysparaValue(SysparaUtil.DLCARDMANAGER_DESKEY)
             if (StringUtil.isEmpty(appid) || StringUtil.isEmpty(appkey) || StringUtil.isEmpty(deskey)) {
                 return ResponseEntity.ok(ResponseBodyBuilder.create()
+                        .data("trans_code", param.trans_code)
                         .fail(1000, "系统参数未配置"))
             } else if (appid != param.app_id) {
                 throw RequestParamCheckException("请求参数错误[应用ID错误]")
             }
             if (!param.checkSign(appkey)) {
                 return ResponseEntity.ok(ResponseBodyBuilder.create()
+                        .data("trans_code", param.trans_code)
                         .fail(2001, "签名错误"))
             }
 
             val datalist = param.decData(deskey)
             if (param.count != datalist.size) {
                 return ResponseEntity.ok(ResponseBodyBuilder.create()
+                        .data("trans_code", param.trans_code)
                         .fail(2002, "请求参数错误[数据条数不匹配]"))
             }
 
             var errlist = ArrayList<DaliDatasyncErrorDetail>(0)
 
-            datalist.forEach {detail->
+            datalist.forEach { detail ->
                 try {
                     detail.checkParam()
                     daliDatasyncService.doUpdateUserInfos(detail)
@@ -60,27 +63,29 @@
                     errlist.add(DaliDatasyncErrorDetail().apply {
                         cardno = detail.cardno
                         errcode = "2001"
-                        errmsg = e1.message?:"明细数据关键字段为空"
+                        errmsg = e1.message ?: "明细数据关键字段为空"
                     })
-                }catch (e2: Exception){
+                } catch (e2: Exception) {
                     errlist.add(DaliDatasyncErrorDetail().apply {
                         cardno = detail.cardno
                         errcode = "3000"
-                        errmsg = e2.message?:"明细处理错误"
+                        errmsg = e2.message ?: "明细处理错误"
                     })
                 }
             }
 
-            return when(StringUtil.isEmpty(errlist)){
+            return when (StringUtil.isEmpty(errlist)) {
                 true -> ResponseEntity.ok(mapOf("retcode" to "0000", "retmsg" to "SUCCESS", "resultcode" to "0000", "resultmsg" to ""))
-                false -> ResponseEntity.ok(mapOf("retcode" to "0000", "retmsg" to "请求成功接收", "resultcode" to "4000", "resultmsg" to "明细数据处理有错", "data" to Gson().toJson(errlist)))
+                false -> ResponseEntity.ok(mapOf("retcode" to "0000", "retmsg" to "请求成功接收", "resultcode" to "4000", "trans_code" to param.trans_code, "resultmsg" to "明细数据处理有错", "data" to Gson().toJson(errlist)))
             }
         } catch (ex: RequestParamCheckException) {
             return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .data("trans_code", param.trans_code)
                     .fail(2001, ex.message ?: "请求参数错误"))
         } catch (e: Exception) {
             e.printStackTrace()
             return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .data("trans_code", param.trans_code)
                     .fail(4000, "系统处理错误"))
         }
     }
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 df5ed08..cc4cf56 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
@@ -8,6 +8,7 @@
 import com.supwisdom.dlpay.api.domain.TCard
 import com.supwisdom.dlpay.api.domain.TPerson
 import com.supwisdom.dlpay.api.service.DaliDatasyncService
+import com.supwisdom.dlpay.api.types.IDTypes
 import com.supwisdom.dlpay.exception.TransactionProcessException
 import com.supwisdom.dlpay.framework.service.SystemUtilService
 import com.supwisdom.dlpay.framework.tenant.TenantContext
@@ -32,20 +33,58 @@
         val lowfreeLimit = systemUtilService.getSysparaValueAsDouble(SysparaUtil.NOPASS_LIMIT, SysparaUtil.DEFAULT_NOPASS_LIMIT)
         val daylimit = systemUtilService.getSysparaValueAsDouble(SysparaUtil.DAY_PAY_LIMIT, SysparaUtil.DEFAULT_DAY_PAY_LIMIT)
 
+        //字典转换
+        val idType = when (bean.idtype.trim()) {
+            "0" -> IDTypes.IDCARD.data  //身份证
+            "1" -> IDTypes.RESIDENCE_BOOKLET.data //户口簿
+            "2" -> IDTypes.PASSPORT.data //护照
+            "3" -> IDTypes.HK_MACAU_PASS.data //港澳居民来往内地通行证
+            "4" -> IDTypes.TAIWAN_PASS.data //台湾同胞来往内地通行证
+            "5" -> IDTypes.FOREIGNER_RESIDENCE_PERMIT.data //外国人居留证
+            "6" -> IDTypes.MILITARY_IDCARD.data //军官证
+            "7" -> IDTypes.SOLDIER_IDCARD.data //士兵证
+            else -> IDTypes.OTHERS.data //其他
+        }
+        val sex = bean.sex?.let {
+            when (it) {
+                "1" -> "male"
+                "2" -> "female"
+                else -> "unknown"
+            }
+        } ?: "unknown"
+        val cardStatus = when (bean.cardstatus) {
+            "0" -> TradeDict.STATUS_UNUSE //未启用
+            "1" -> TradeDict.STATUS_NORMAL //正常
+            "9" -> TradeDict.STATUS_CLOSED //注销
+            "2" -> TradeDict.STATUS_ABNORMAL //异常
+            else -> TradeDict.STATUS_ABNORMAL //异常
+        }
+
         val systime = systemUtilService.sysdatetime
-        var person = personDao.findByIdentity(bean.idtype.trim(), bean.idno.trim())
+        var person = personDao.findByIdentity(idType.toString(), bean.idno.trim())
         if (null != person) {
+            //更新
+            var updateFlag = false
+            if (person.sex != sex) {
+                updateFlag = true
+                person.sex = sex
+            }
             if (person.name != bean.username) {
+                updateFlag = true
                 person.name = bean.username
-                person.lastsaved = systime.hostdatetime
-                person = personDao.save(person)
                 accountDao.updateAccnameByUserid(person.name, person.userid)
             }
+            if (updateFlag) {
+                person.lastsaved = systime.hostdatetime
+                person = personDao.save(person)
+            }
         } else {
+            //修改
             person = TPerson().apply {
                 name = bean.username
+                this.sex = sex
                 status = TradeDict.STATUS_NORMAL
-                idtype = bean.idtype.trim()
+                idtype = idType.toString()
                 idno = bean.idno.trim()
                 email = bean.email
                 mobile = bean.mobile
@@ -79,19 +118,48 @@
         var cityCard = cardDao.findCardByCardnoAndCardtype(bean.cardno.trim(), ConstantUtil.CARDTYPE_CITIZENCARD)
         if (null != cityCard) {
             //仅修改有效期和状态
+            var cardUpdateFlag = false
             if (cityCard.expiredate != bean.expiredate.trim()) {
+                cardUpdateFlag = true
                 cityCard.expiredate = bean.expiredate.trim()
             }
-            //fixme: bean.cardstatus 判断修改状态
 
-            cardDao.save(cityCard)
+            //fixme: bean.cardstatus 判断修改状态
+            if(TradeDict.STATUS_CLOSED == cardStatus){
+                //注销卡片
+                if(cityCard.status != TradeDict.STATUS_CLOSED){
+                    cardUpdateFlag = true
+                    cityCard.status = TradeDict.STATUS_CLOSED
+                }
+            }else{
+                //卡片的其他状态,代表交易状态
+                if(TradeDict.STATUS_NORMAL != cityCard.transStatus){
+                    cardUpdateFlag = true
+                    cityCard.status = TradeDict.STATUS_NORMAL
+                }
+                if(cardStatus != cityCard.transStatus){
+                    cardUpdateFlag = true
+                    cityCard.transStatus=cardStatus
+                }
+            }
+
+            if(cardUpdateFlag){
+                cityCard.lastsaved = systime.hostdatetime
+                cardDao.save(cityCard) //更新
+            }
         } else {
             cityCard = TCard().apply {
                 cardno = bean.cardno.trim()
                 cardtype = ConstantUtil.CARDTYPE_CITIZENCARD
                 cardphyid = bean.cardphyid.trim()
-                status = TradeDict.STATUS_NORMAL // fixme: bean.cardstatus 判断
-                transStatus = TradeDict.STATUS_NORMAL
+                status = when (TradeDict.STATUS_CLOSED == cardStatus) {
+                    true -> TradeDict.STATUS_CLOSED
+                    false -> TradeDict.STATUS_NORMAL
+                }
+                transStatus = when (TradeDict.STATUS_CLOSED == cardStatus) {
+                    true -> TradeDict.STATUS_ABNORMAL
+                    false -> cardStatus
+                }
                 expiredate = bean.expiredate.trim()
                 signed = false
                 userid = person.userid
@@ -107,18 +175,22 @@
                 bankCard = TCard().apply {
                     cardno = bean.bankcardno!!.trim()
                     cardtype = ConstantUtil.CARDTYPE_BANKCARD
-                    cardphyid = ""
-                    status = TradeDict.STATUS_NORMAL // fixme: bean.cardstatus 判断
+                    cardphyid = bean.cardphyid.trim()
+                    status = when (TradeDict.STATUS_CLOSED == cardStatus) {
+                        true -> TradeDict.STATUS_CLOSED
+                        false -> TradeDict.STATUS_NORMAL
+                    }
                     transStatus = TradeDict.STATUS_NORMAL
                     expiredate = "21991231"
                     signed = false
                     userid = person.userid
                     lastsaved = systime.hostdatetime
                 }
-                cardDao.closedBankcardStatusByUserid(bankCard.userid)  //注销其他银行卡
+                if (TradeDict.STATUS_NORMAL == bankCard.status) {
+                    cardDao.closedBankcardStatusByUserid(bankCard.userid)  //注销其他银行卡
+                }
                 bankCard.tenantid = TenantContext.getTenantSchema()
                 cardDao.save(bankCard) //绑定新的银行卡
-
             } else {
                 if (bankCard.userid != person.userid) {
                     throw TransactionProcessException(3000, "银行卡已被人绑定")
diff --git a/payapi/src/main/resources/data.sql b/payapi/src/main/resources/data.sql
index 2bca5e2..da276c1 100644
--- a/payapi/src/main/resources/data.sql
+++ b/payapi/src/main/resources/data.sql
@@ -504,7 +504,20 @@
 VALUES ('23', 'wechat', 'wechat.refund.certpwd', '微信退款证书密码', NULL, 'f', '{tenantid}');
 
 INSERT INTO "tb_syspara" ("paraid", "displayflag", "editflag", "lastsaved", "paraname", "paraunit", "paraval", "remark", "valuetype", "tenantid")
-VALUES (1, 'yes', 1, '20190514165658', '账户最大余额默认值', '元', '10001', '账户开户时的默认账户最大余额', 'amount', '{tenantid}');
+VALUES (1, 'yes', 1, '20190514165658', '账户最大余额默认值', '元', '10000.0', '账户开户时的默认账户最大余额', 'amount', '{tenantid}');
+INSERT INTO "tb_syspara" ("paraid", "displayflag", "editflag", "lastsaved", "paraname", "paraunit", "paraval", "remark", "valuetype", "tenantid")
+VALUES (2, 'yes', 1, '20190514165658', '默认免密额度', '元', '100.0', '账户开户时的默认免密额度', 'amount', '{tenantid}');
+INSERT INTO "tb_syspara" ("paraid", "displayflag", "editflag", "lastsaved", "paraname", "paraunit", "paraval", "remark", "valuetype", "tenantid")
+VALUES (3, 'yes', 1, '20190514165658', '默认日累计额度', '元', '200.0', '账户余额支付时默认的日累计额度', 'amount', '{tenantid}');
+INSERT INTO "tb_syspara" ("paraid", "displayflag", "editflag", "lastsaved", "paraname", "paraunit", "paraval", "remark", "valuetype", "tenantid")
+VALUES (4, 'yes', 1, '20190514165658', '手机端用户过期时间', '秒', null, '手机端用户过期时间(秒)', 'decimal', '{tenantid}');
+
+VALUES (2019, 'yes', 1, '20190514165658', '与卡管系统对接的应用ID', null, null, '与卡管系统对接的app_id', 'string', '{tenantid}');
+INSERT INTO "tb_syspara" ("paraid", "displayflag", "editflag", "lastsaved", "paraname", "paraunit", "paraval", "remark", "valuetype", "tenantid")
+VALUES (2020, 'yes', 1, '20190514165658', '与卡管系统对接的签名秘钥', null, null, '与卡管系统对接的appkey', 'string', '{tenantid}');
+INSERT INTO "tb_syspara" ("paraid", "displayflag", "editflag", "lastsaved", "paraname", "paraunit", "paraval", "remark", "valuetype", "tenantid")
+VALUES (2021, 'yes', 1, '20190514165658', '与卡管系统对接的业务参数加密秘钥', null, null, '与卡管系统对接中业务参数加密的deskey', 'string', '{tenantid}');
+
 
 INSERT INTO "tb_task_lock" ("taskcode", "remark", "taskstatus", "tasktime", "tenantid")
 VALUES ('DAYENDSETTLETASK', '日终结算', '0', '20190619100600', '{tenantid}');
@@ -585,6 +598,8 @@
 INSERT INTO "tb_dictionary" ("id", "dictval", "dicttype", "dictcaption", "dicttypename", "tenantid")
 VALUES (30, 'shopmarket', 'dtltypeList', '商超消费', '流水类型', '{tenantid}');
 
+
+
 INSERT INTO TB_QRCODE_PATTERN(ID, PATTERN, SOURCETYPE, TENANTID)
 VALUES(1, '28\d{16}', 'alipay', '{tenantid}');
 INSERT INTO TB_QRCODE_PATTERN(ID, PATTERN, SOURCETYPE, TENANTID)