市民卡挂失任务
diff --git a/config/application-devel-pg-xkx.properties b/config/application-devel-pg-xkx.properties
index 0167251..3a19f2e 100644
--- a/config/application-devel-pg-xkx.properties
+++ b/config/application-devel-pg-xkx.properties
@@ -30,7 +30,8 @@
 #download.ynrcc.chkfile.cron =3 0/2 * * * ?
 #query.third.transdtl.result.cron=7 0/1 * * * ?
 #dayend.settletask.cron=0 0/2 * * * ?
-payapi.sourcetype.checker.scheduler=0 0/2 * * * ?
+#payapi.sourcetype.checker.scheduler=0 0/2 * * * ?
+citizencard.dolosstask.cron=3 0/1 * * * ?
 #############################################
 spring.cloud.consul.enabled=false
 spring.cloud.consul.host=172.28.201.70
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/bean/CitizencardLossResp.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/bean/CitizencardLossResp.java
new file mode 100644
index 0000000..09eda79
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/bean/CitizencardLossResp.java
@@ -0,0 +1,22 @@
+package com.supwisdom.dlpay.citizencard.bean;
+
+public class CitizencardLossResp {
+  private String CODE;
+  private String MESSAGE;
+
+  public String getCODE() {
+    return CODE;
+  }
+
+  public void setCODE(String CODE) {
+    this.CODE = CODE;
+  }
+
+  public String getMESSAGE() {
+    return MESSAGE;
+  }
+
+  public void setMESSAGE(String MESSAGE) {
+    this.MESSAGE = MESSAGE;
+  }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/dao/CitizencardLossApplyDao.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/dao/CitizencardLossApplyDao.java
new file mode 100644
index 0000000..f054ef1
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/dao/CitizencardLossApplyDao.java
@@ -0,0 +1,18 @@
+package com.supwisdom.dlpay.citizencard.dao;
+
+import com.supwisdom.dlpay.citizencard.domain.TCitizencardLossApply;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface CitizencardLossApplyDao extends JpaRepository<TCitizencardLossApply, String> {
+
+  @Query("from TCitizencardLossApply where status=:status order by refno asc")
+  List<TCitizencardLossApply> findCardlossApplyRecordsByStatus(@Param("status") String status);
+
+  TCitizencardLossApply getByRefno(String refno);
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/domain/TCitizencardLossApply.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/domain/TCitizencardLossApply.java
new file mode 100644
index 0000000..6063b0b
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/domain/TCitizencardLossApply.java
@@ -0,0 +1,142 @@
+package com.supwisdom.dlpay.citizencard.domain;
+
+import javax.persistence.*;
+import java.security.Timestamp;
+
+@Entity
+@Table(name = "TB_CITIZENCARD_LOSSAPPLY")
+public class TCitizencardLossApply {
+  @Id
+  @Column(name = "REFNO", length = 32, nullable = false)
+  private String refno;
+
+  @Column(name = "CARDNO", length = 32, nullable = false)
+  private String cardno;
+
+  @Column(name = "APPLYTIME", length = 14, nullable = false)
+  private String applytime; //申请挂失时间
+
+  @Column(name = "TERMTYPE", length = 20)
+  private String termtype; //申请终端 app-手机/manager-管理端/web-个人网页
+
+  @Column(name = "UID", length = 32)
+  private String uid; //与终端类型对应。手机的uid,操作员的operid,个人的登录id
+
+  @Column(name = "STATUS", length = 20, nullable = false)
+  private String status; //apply,success,fail
+
+  @Column(name = "ERRCODE", length = 20)
+  private String errcode;
+
+  @Column(name = "ERRMSG", length = 600)
+  private String errmsg;
+
+  @Column(name = "SENDTIME", length = 14)
+  private String sendtime; //请求挂失时间
+
+  @Column(name = "SENDCNT", precision = 9)
+  private Integer sendcnt=0;
+
+  @Version
+  @Column(name = "LASTSAVED")
+  private Timestamp lastsaved;
+
+  @Column(name = "tenantid", length = 20, nullable = false)
+  private String tenantId;
+
+  public String getRefno() {
+    return refno;
+  }
+
+  public void setRefno(String refno) {
+    this.refno = refno;
+  }
+
+  public String getCardno() {
+    return cardno;
+  }
+
+  public void setCardno(String cardno) {
+    this.cardno = cardno;
+  }
+
+  public String getApplytime() {
+    return applytime;
+  }
+
+  public void setApplytime(String applytime) {
+    this.applytime = applytime;
+  }
+
+  public String getTermtype() {
+    return termtype;
+  }
+
+  public void setTermtype(String termtype) {
+    this.termtype = termtype;
+  }
+
+  public String getUid() {
+    return uid;
+  }
+
+  public void setUid(String uid) {
+    this.uid = uid;
+  }
+
+  public String getStatus() {
+    return status;
+  }
+
+  public void setStatus(String status) {
+    this.status = status;
+  }
+
+  public String getErrcode() {
+    return errcode;
+  }
+
+  public void setErrcode(String errcode) {
+    this.errcode = errcode;
+  }
+
+  public String getErrmsg() {
+    return errmsg;
+  }
+
+  public void setErrmsg(String errmsg) {
+    this.errmsg = errmsg;
+  }
+
+  public String getSendtime() {
+    return sendtime;
+  }
+
+  public void setSendtime(String sendtime) {
+    this.sendtime = sendtime;
+  }
+
+  public Integer getSendcnt() {
+    return sendcnt;
+  }
+
+  public void setSendcnt(Integer sendcnt) {
+    this.sendcnt = sendcnt;
+  }
+
+  public Timestamp getLastsaved() {
+    return lastsaved;
+  }
+
+  public void setLastsaved(Timestamp lastsaved) {
+    this.lastsaved = lastsaved;
+  }
+
+  public String getTenantId() {
+    return tenantId;
+  }
+
+  public void setTenantId(String tenantId) {
+    this.tenantId = tenantId;
+  }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/service/CitizencardManagerService.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/service/CitizencardManagerService.java
new file mode 100644
index 0000000..c799ee2
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/service/CitizencardManagerService.java
@@ -0,0 +1,22 @@
+package com.supwisdom.dlpay.citizencard.service;
+
+import com.supwisdom.dlpay.citizencard.domain.TCitizencardLossApply;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+public interface CitizencardManagerService {
+
+  @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, readOnly = true)
+  List<TCitizencardLossApply> getNewApplyCitizencardLossRecords();
+
+  @Transactional(rollbackFor = Exception.class, readOnly = true)
+  TCitizencardLossApply getCitizencardLossApply(String refno);
+
+  @Transactional(rollbackFor = Exception.class)
+  TCitizencardLossApply saveOrUpdateCitizencardLossApply(TCitizencardLossApply lossApply);
+
+  @Transactional(rollbackFor = Exception.class)
+  TCitizencardLossApply doFinishCitizencardLoss(TCitizencardLossApply lossApply);
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/service/impl/CitizencardManagerServiceImpl.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/service/impl/CitizencardManagerServiceImpl.java
new file mode 100644
index 0000000..71101d8
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/service/impl/CitizencardManagerServiceImpl.java
@@ -0,0 +1,61 @@
+package com.supwisdom.dlpay.citizencard.service.impl;
+
+import com.supwisdom.dlpay.api.dao.CardDao;
+import com.supwisdom.dlpay.api.domain.TCard;
+import com.supwisdom.dlpay.citizencard.dao.CitizencardLossApplyDao;
+import com.supwisdom.dlpay.citizencard.domain.TCitizencardLossApply;
+import com.supwisdom.dlpay.citizencard.service.CitizencardManagerService;
+import com.supwisdom.dlpay.framework.service.SystemUtilService;
+import com.supwisdom.dlpay.framework.util.StringUtil;
+import com.supwisdom.dlpay.framework.util.TradeDict;
+import com.supwisdom.dlpay.util.ConstantUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class CitizencardManagerServiceImpl implements CitizencardManagerService {
+  @Autowired
+  private CitizencardLossApplyDao citizencardLossApplyDao;
+  @Autowired
+  private CardDao cardDao;
+  @Autowired
+  private SystemUtilService systemUtilService;
+
+  @Override
+  public List<TCitizencardLossApply> getNewApplyCitizencardLossRecords() {
+    List<TCitizencardLossApply> list = citizencardLossApplyDao.findCardlossApplyRecordsByStatus(ConstantUtil.CITIZENCARD_LOSSAPPLY_STATUS_APPLY);
+    if (null != list) {
+      return list;
+    }
+    return new ArrayList<>(0);
+  }
+
+  @Override
+  public TCitizencardLossApply getCitizencardLossApply(String refno) {
+    if(!StringUtil.isEmpty(refno)){
+      return citizencardLossApplyDao.getByRefno(refno.trim());
+    }
+    return null;
+  }
+
+  @Override
+  public TCitizencardLossApply saveOrUpdateCitizencardLossApply(TCitizencardLossApply lossApply) {
+    return citizencardLossApplyDao.save(lossApply);
+  }
+
+  @Override
+  public TCitizencardLossApply doFinishCitizencardLoss(TCitizencardLossApply lossApply) {
+    if (ConstantUtil.CITIZENCARD_LOSSAPPLY_STATUS_SUCCESS.equals(lossApply)) {
+      TCard cityCard = cardDao.findCardByCardnoAndCardtype(lossApply.getCardno(), ConstantUtil.CARDTYPE_CITIZENCARD);
+      if (null != cityCard && !TradeDict.STATUS_LOST.equals(cityCard.getTransStatus())) {
+        cityCard.setTransStatus(TradeDict.STATUS_LOST);
+        cityCard.setLastsaved(systemUtilService.getSysdatetime().getHostdatetime());
+        cardDao.save(cityCard);
+      }
+    }
+    return citizencardLossApplyDao.save(lossApply);
+  }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/task/CitizencardCardLossTask.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/task/CitizencardCardLossTask.java
new file mode 100644
index 0000000..4af5665
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/task/CitizencardCardLossTask.java
@@ -0,0 +1,119 @@
+package com.supwisdom.dlpay.citizencard.task;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.core.util.MultivaluedMapImpl;
+import com.supwisdom.dlpay.citizencard.bean.CitizencardLossResp;
+import com.supwisdom.dlpay.citizencard.domain.TCitizencardLossApply;
+import com.supwisdom.dlpay.citizencard.service.CitizencardManagerService;
+import com.supwisdom.dlpay.framework.service.SystemUtilService;
+import com.supwisdom.dlpay.framework.util.StringUtil;
+import com.supwisdom.dlpay.util.ConstantUtil;
+import net.javacrumbs.shedlock.core.SchedulerLock;
+import org.apache.http.HttpStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.List;
+
+/**
+ * 市民卡挂失申请异步调卡管系统接口挂失任务
+ */
+@Component
+public class CitizencardCardLossTask {
+  @Autowired
+  private CitizencardManagerService citizencardManagerService;
+  @Autowired
+  private SystemUtilService systemUtilService;
+
+  private Gson gson = new Gson();
+  private static final Logger logger = LoggerFactory.getLogger(CitizencardCardLossTask.class);
+
+  @Scheduled(cron = "${citizencard.dolosstask.cron}")
+  @SchedulerLock(name = "CitizencardCardLossTask", lockAtMostForString = "PT30M")
+  public void doCitizencardCardLossTask() {
+    try {
+      long t1 = System.currentTimeMillis();
+      List<TCitizencardLossApply> applyList = citizencardManagerService.getNewApplyCitizencardLossRecords();
+      String cardsysUrl = systemUtilService.getBusinessValue(ConstantUtil.CITIZENCARD_SYSTEM_URL);
+      if(!StringUtil.isEmpty(applyList) && StringUtil.isEmpty(cardsysUrl)){
+        logger.error("市民卡管系统地址未配置[BusinessParam=" + ConstantUtil.CITIZENCARD_SYSTEM_URL + "]");
+        return;
+      }
+
+      if (!StringUtil.isEmpty(applyList)) {
+        logger.info("执行市民卡挂失任务<<dlsmk.cardsystem.url=[" + cardsysUrl + "]>>:");
+      }
+      for (TCitizencardLossApply lossApply : applyList) {
+        doLossCard(lossApply, cardsysUrl);
+      }
+
+      if (!StringUtil.isEmpty(applyList)) {
+        long t2 = System.currentTimeMillis();
+        logger.info("执行市民卡挂失结束,处理" + applyList.size() + "条记录,耗时 " + (t2 - t1) + " ms");
+      }
+    } catch (Exception ex) {
+      logger.error("执行市民卡挂失报错!");
+      ex.printStackTrace();
+    }
+  }
+
+  private void doLossCard(TCitizencardLossApply lossApply, String url) {
+    try{
+      lossApply.setSendtime(systemUtilService.getSysdatetime().getHostdatetime());
+      lossApply.setSendcnt(lossApply.getSendcnt()+1);
+
+      Client c = Client.create();
+      c.setConnectTimeout(5*1000);
+      WebResource r = c.resource(url);
+      MultivaluedMap params = new MultivaluedMapImpl();
+      params.add("cardNo", lossApply.getCardno());
+      logger.info("====>> refno=[" + lossApply.getRefno() + "] cardloss send param=" + gson.toJson(params) + " === ");
+      ClientResponse respClient = r.type(MediaType.APPLICATION_JSON_TYPE).accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, params);
+      if (HttpStatus.SC_OK == respClient.getStatus()) {
+        String jsonStr = respClient.getEntity(String.class);
+        logger.info("<<==== refno=[" + lossApply.getRefno() + "] cardloss success return=[" + jsonStr + "]");
+        CitizencardLossResp lossResp = null;
+        try{
+          lossResp = gson.fromJson(jsonStr,CitizencardLossResp.class);
+        }catch (Exception ex){
+          logger.error("挂失接口返回数据解析错误!!!");
+          ex.printStackTrace();
+        }
+
+        if(null!=lossResp){
+          lossApply.setErrcode(lossResp.getCODE());
+          lossApply.setErrmsg(lossResp.getMESSAGE());
+          if("000000".equals(lossResp.getCODE())){
+            lossApply.setStatus(ConstantUtil.CITIZENCARD_LOSSAPPLY_STATUS_SUCCESS);
+          }else{
+            lossApply.setStatus(ConstantUtil.CITIZENCARD_LOSSAPPLY_STATUS_FAIL);
+          }
+        }else{
+          lossApply.setErrcode("-1");
+          lossApply.setErrmsg(jsonStr);
+          lossApply.setStatus(ConstantUtil.CITIZENCARD_LOSSAPPLY_STATUS_FAIL);
+        }
+      }else{
+        logger.error("<<==== refno=[" + lossApply.getRefno() + "] cardloss return status=" + respClient.getStatus() + "*************************");
+        lossApply.setErrcode("-99");
+        lossApply.setErrmsg("httpStatus=" + respClient.getStatus());
+      }
+
+      citizencardManagerService.doFinishCitizencardLoss(lossApply);
+    }catch (Exception e){
+      logger.error("请求卡管系统挂失报错!!!");
+      e.printStackTrace();
+    }
+  }
+
+
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/util/ConstantUtil.java b/payapi/src/main/java/com/supwisdom/dlpay/util/ConstantUtil.java
index 8dcf53c..6862e9d 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/util/ConstantUtil.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/util/ConstantUtil.java
@@ -72,4 +72,13 @@
   public static final String CHKDTL_RESOLVED_HANGUP="hangup"; //挂起
 
 
+  /**
+   * 市民卡挂失申请表状态
+   * */
+  public static final String CITIZENCARD_LOSSAPPLY_STATUS_APPLY = "apply"; //申请挂失
+  public static final String CITIZENCARD_LOSSAPPLY_STATUS_SUCCESS = "success"; //调用挂失接口成功
+  public static final String CITIZENCARD_LOSSAPPLY_STATUS_FAIL = "fail"; //调用挂失接口失败
+
+  public static final String CITIZENCARD_SYSTEM_URL = "dlsmk.cardsystem.url"; //大理市民卡管系统url
+
 }
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/app/bean/app_request_param.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/app/bean/app_request_param.kt
deleted file mode 100644
index d857281..0000000
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/app/bean/app_request_param.kt
+++ /dev/null
@@ -1,2 +0,0 @@
-package com.supwisdom.dlpay.app.bean
-
diff --git a/payapi/src/main/resources/application.properties b/payapi/src/main/resources/application.properties
index 16dfbda..0a2b535 100644
--- a/payapi/src/main/resources/application.properties
+++ b/payapi/src/main/resources/application.properties
@@ -30,10 +30,11 @@
 server.tomcat.uri-encoding=UTF-8
 ##################################################
 ## quartz task scheduler
-shopbalance.updater.cron=10/* * * * * ?
+shopbalance.updater.cron=*/10 * * * * ?
 dayend.settletask.cron=0 3/30 2-3 * * ?
 query.third.transdtl.result.cron=7 0/1 * * * ?
 payapi.sourcetype.checker.scheduler=7 3/10 * * * ?
+citizencard.dolosstask.cron=-
 ################################################
 # user password
 auth.password.bcrypt.length=10