From: Xia Kaixiang Date: Wed, 31 Jul 2019 07:44:51 +0000 (+0800) Subject: 卡管初始化TXT文件导入接口 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=d8c4d7e1e22a5286c58fd0ea6247d829d75e859a;p=epayment%2Ffood_payapi.git 卡管初始化TXT文件导入接口 --- diff --git a/payapi/build.gradle b/payapi/build.gradle index ed8ce9b1..d5c3abf4 100644 --- a/payapi/build.gradle +++ b/payapi/build.gradle @@ -89,6 +89,7 @@ dependencies { implementation files('libs/sms.jar') // implementation files('libs/ojdbc6.jar') implementation 'commons-dbcp:commons-dbcp:1.4' + implementation 'commons-beanutils:commons-beanutils:1.9.3' implementation project(':payapi-common') /*支付宝SDK*/ diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/CitycardTempDao.java b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/CitycardTempDao.java new file mode 100644 index 00000000..fb00e85d --- /dev/null +++ b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/CitycardTempDao.java @@ -0,0 +1,15 @@ +package com.supwisdom.dlpay.api.dao; + +import com.supwisdom.dlpay.api.domain.TCitycardTemp; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface CitycardTempDao extends JpaRepository { + @Query("from TCitycardTemp where id=?1 ") + List findbyTempid(String tempid); + + @Query("from TCitycardTemp where lastsaved>=?1 order by lastsaved ") + List findbyUpdtime(String updtime); +} 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 new file mode 100644 index 00000000..7d7f4547 --- /dev/null +++ b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TCitycardTemp.java @@ -0,0 +1,188 @@ +package com.supwisdom.dlpay.api.domain; + +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; + +@Entity +@Table(name = "TB_CITYCARD_TEMP") +public class TCitycardTemp { + @Id + @GenericGenerator(name = "idGenerator", strategy = "uuid") + @GeneratedValue(generator = "idGenerator") + @Column(name = "ID", nullable = false, length = 32) + private String id; + + @Column(name = "CARDNO", length = 32) + private String cardno; + + @Column(name = "CARDPHYID", length = 20) + private String cardphyid; + + @Column(name = "EXPIREDATE", length = 8) + private String expiredate; + + @Column(name = "CARDSTATUS", length = 10) + private String cardstatus; + + @Column(name = "BANKCARDNO", length = 32) + private String bankcardno; + + @Column(name = "USERNAME", length = 200) + private String username; + + @Column(name = "SEX", length = 10) + private String sex; + + @Column(name = "IDTYPE", length = 10) + private String idtype; + + @Column(name = "IDNO", length = 60) + private String idno; + + @Column(name = "MOBILE", length = 30) + private String mobile; + + @Column(name = "EMAIL", length = 60) + private String email; + + @Column(name = "STATUS", length = 20) + private String status; + + @Column(name = "REMARK", length = 600) + private String remark; + + @Column(name = "LASTSAVED", length = 14) + private String lastsaved; + + @Column(name = "tenantid", length = 20) + private String tenantid = ""; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCardno() { + return cardno; + } + + public void setCardno(String cardno) { + this.cardno = cardno; + } + + public String getCardphyid() { + return cardphyid; + } + + public void setCardphyid(String cardphyid) { + this.cardphyid = cardphyid; + } + + public String getExpiredate() { + return expiredate; + } + + public void setExpiredate(String expiredate) { + this.expiredate = expiredate; + } + + public String getCardstatus() { + return cardstatus; + } + + public void setCardstatus(String cardstatus) { + this.cardstatus = cardstatus; + } + + public String getBankcardno() { + return bankcardno; + } + + public void setBankcardno(String bankcardno) { + this.bankcardno = bankcardno; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getSex() { + return sex; + } + + public void setSex(String sex) { + this.sex = sex; + } + + public String getIdtype() { + return idtype; + } + + public void setIdtype(String idtype) { + this.idtype = idtype; + } + + public String getIdno() { + return idno; + } + + public void setIdno(String idno) { + this.idno = idno; + } + + public String getMobile() { + return mobile; + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getLastsaved() { + return lastsaved; + } + + public void setLastsaved(String 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/framework/util/StringUtil.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/StringUtil.java index 2657b515..15569412 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 @@ -3,6 +3,7 @@ package com.supwisdom.dlpay.framework.util; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.beanutils.BeanUtils; public class StringUtil { /** @@ -166,4 +167,16 @@ public class StringUtil { return url+"/"+path; } } + + public static void transforToBean(List fields, List columns, Object bean) throws Exception { + if (null == fields) throw new Exception("fields is null"); + if (null == columns) throw new Exception("columns is null"); + if (fields.size() < columns.size()) throw new Exception("错误的列定义"); + Map data = new HashMap<>(0); + for (int i = 0; i < fields.size(); i++) { + data.put(fields.get(i), columns.get(i)); + } + BeanUtils.populate(bean, data); + return; + } } 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 80a9ca96..db41364e 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 @@ -1,17 +1,22 @@ package com.supwisdom.dlpay.api.controller import com.google.gson.Gson +import com.supwisdom.dlpay.api.bean.DaliDatasyncDetail import com.supwisdom.dlpay.api.bean.DaliDatasyncErrorDetail import com.supwisdom.dlpay.api.bean.DaliDatasyncParam import com.supwisdom.dlpay.api.exception.RequestParamCheckException import com.supwisdom.dlpay.api.service.DaliDatasyncService import com.supwisdom.dlpay.framework.ResponseBodyBuilder import com.supwisdom.dlpay.framework.service.SystemUtilService +import com.supwisdom.dlpay.framework.util.DateUtil import com.supwisdom.dlpay.framework.util.StringUtil import com.supwisdom.dlpay.framework.util.SysparaUtil +import mu.KotlinLogging import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.* +import java.io.* +import java.nio.charset.Charset @RequestMapping("/api/common") @RestController @@ -21,6 +26,8 @@ class DaliDatasyncApiController { @Autowired lateinit var daliDatasyncService: DaliDatasyncService + private val logger = KotlinLogging.logger { } + /** * ============================================================================ * 大理卡管系统推送市民卡信息同步接口 @@ -65,12 +72,27 @@ class DaliDatasyncApiController { errcode = "2001" errmsg = e1.message ?: "明细数据关键字段为空" }) + + try { + daliDatasyncService.saveUpdateUserinfoErrors(detail, e1.message ?: "明细数据关键字段为空") //记录失败数据 + } catch (e3: Exception) { + logger.error("保存错误同步数据失败" + Gson().toJson(detail)) + e3.printStackTrace() + } + } catch (e2: Exception) { errlist.add(DaliDatasyncErrorDetail().apply { cardno = detail.cardno errcode = "3000" errmsg = e2.message ?: "明细处理错误" }) + + try { + daliDatasyncService.saveUpdateUserinfoErrors(detail, e2.message ?: e2.javaClass.name) //记录失败数据 + } catch (e4: Exception) { + logger.error("保存错误同步数据失败" + Gson().toJson(detail)) + e4.printStackTrace() + } } } @@ -90,4 +112,134 @@ class DaliDatasyncApiController { } } + /** + * ============================================================================ + * 大理卡管系统第一次初始化数据txt导入接口 + * ============================================================================ + * */ + @GetMapping("/import") + fun importDaliInitData(@RequestParam("filename") filename: String): ResponseEntity { + if (StringUtil.isEmpty(filename)) { + return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(30001, "请输入初始化数据txt文件全路径名")) + } else if (!filename.endsWith(".txt")) { + return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(30001, "请输入初始化数据txt文件")) + } + + try { + val txtFile = File(filename) + val batchSize = 1000 + var sumCount = 0 + var failCount = 0 + + txtFile.bufferedReader(Charset.forName("GBK")).use { reader -> + val header = reader.readLine() + val fields = header.split("|") + + var datalist = ArrayList() + while (true) { + val line = reader.readLine() ?: break + if (StringUtil.isEmpty(line)) continue + val column = line.split("|") + val bean = DaliDatasyncDetail() + StringUtil.transforToBean(fields, column, bean) + datalist.add(bean) + sumCount++ + if (datalist.size >= batchSize) { + val fcnt = doBatchSaveData(datalist) //保存 + failCount += fcnt + datalist.clear() + } + } + + //保存最后的不足batchSize的记录 + if (datalist.size > 0) { + val fcnt = doBatchSaveData(datalist) //保存 + failCount += fcnt + } + } + + return ResponseEntity.ok(ResponseBodyBuilder.create() + .data("totalcnt", sumCount) + .data("failcnt", failCount) + .data("successcnt", sumCount - failCount) + .success("导入请求成功")) + + } catch (ex: Exception) { + ex.printStackTrace() + return ResponseEntity.ok(ResponseBodyBuilder.create() + .exception(4000, ex, "处理异常!" + (ex.message ?: ex.javaClass.name))) + } + + } + + private fun doBatchSaveData(list: ArrayList): Int { + try { + daliDatasyncService.doBatchSaveOrUpdateUserInfos(list) + return 0 //批量保存成功,无失败 + } catch (e1: Exception) { + } + + //批量保存有异常,逐笔保存 + var failcnt = 0 + for (bean in list) { + try { + bean.checkParam() + daliDatasyncService.doUpdateUserInfos(bean) + } catch (e2: Exception) { + failcnt++ + try { + daliDatasyncService.saveUpdateUserinfoErrors(bean, e2.message ?: e2.javaClass.name) + } catch (e3: Exception) { + logger.error("初始化txt文件保存错误同步数据失败" + Gson().toJson(bean)) + e3.printStackTrace() + } + continue + } + } + return failcnt + } + + /** + * ============================================================================ + * 大理卡管系统错误同步信息补处理 + * ============================================================================ + * */ + @GetMapping("/dealerror") + fun doDealErrorRecord(@RequestParam(name = "tempid", required = false, defaultValue = "") tempid: String, + @RequestParam(name = "updtime", required = false, defaultValue = "") updtime: String): ResponseEntity { + if (StringUtil.isEmpty(tempid) && !DateUtil.checkDatetimeValid(updtime, DateUtil.DATETIME_FMT)) { + return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(99, "请求参数错误[tempid和updtime不能同时为空]")) + } + + try { + var totalcnt = 0 + var failcnt = 0 + var detailMsg = "" + daliDatasyncService.getErrorUpdateUserinfos(tempid, updtime).forEach { + totalcnt++ + try { + daliDatasyncService.dealErrorRecord(it) + } catch (e1: Exception) { + failcnt++ + detailMsg += ("${it.cardno}同步出错:" + (e1.message ?: e1.javaClass.name) + "\n") + } + } + + return ResponseEntity.ok(ResponseBodyBuilder.create() + .data("totalcnt", totalcnt) + .data("failcnt", failcnt) + .data("successcnt", totalcnt - failcnt) + .data("detailmsg", detailMsg) + .success("导入成功")) + } catch (ex: Exception) { + ex.printStackTrace() + return ResponseEntity.ok(ResponseBodyBuilder.create() + .exception(99, ex, "处理异常!" + (ex.message ?: ex.javaClass.name))) + } + } + + } diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/dali_datasync_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/dali_datasync_service.kt index d5a960f4..1356d46b 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/dali_datasync_service.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/dali_datasync_service.kt @@ -2,12 +2,25 @@ package com.supwisdom.dlpay.api.service import com.supwisdom.dlpay.api.bean.DaliDatasyncDetail import com.supwisdom.dlpay.api.domain.TCard +import com.supwisdom.dlpay.api.domain.TCitycardTemp import org.springframework.transaction.annotation.Propagation import org.springframework.transaction.annotation.Transactional -interface DaliDatasyncService{ +interface DaliDatasyncService { - @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class)) + @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class]) fun doUpdateUserInfos(bean: DaliDatasyncDetail): Boolean + @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class]) + fun doBatchSaveOrUpdateUserInfos(userlist: ArrayList): Boolean + + @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class]) + fun saveUpdateUserinfoErrors(bean: DaliDatasyncDetail, errmsg: String) + + @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class], readOnly = true) + fun getErrorUpdateUserinfos(tmpid: String, updtime: String): List + + @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class]) + fun dealErrorRecord(temp: TCitycardTemp) + } \ No newline at end of file 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 cc4cf566..59833f66 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 @@ -3,9 +3,11 @@ package com.supwisdom.dlpay.api.service.impl import com.supwisdom.dlpay.api.bean.DaliDatasyncDetail import com.supwisdom.dlpay.api.dao.AccountDao import com.supwisdom.dlpay.api.dao.CardDao +import com.supwisdom.dlpay.api.dao.CitycardTempDao import com.supwisdom.dlpay.api.dao.PersonDao import com.supwisdom.dlpay.api.domain.TAccount import com.supwisdom.dlpay.api.domain.TCard +import com.supwisdom.dlpay.api.domain.TCitycardTemp import com.supwisdom.dlpay.api.domain.TPerson import com.supwisdom.dlpay.api.service.DaliDatasyncService import com.supwisdom.dlpay.api.types.IDTypes @@ -26,6 +28,8 @@ class DaliDatasyncServiceImpl : DaliDatasyncService { @Autowired lateinit var cardDao: CardDao @Autowired + lateinit var citycardTempDao: CitycardTempDao + @Autowired lateinit var systemUtilService: SystemUtilService override fun doUpdateUserInfos(bean: DaliDatasyncDetail): Boolean { @@ -79,7 +83,7 @@ class DaliDatasyncServiceImpl : DaliDatasyncService { person = personDao.save(person) } } else { - //修改 + //新增 person = TPerson().apply { name = bean.username this.sex = sex @@ -110,8 +114,8 @@ class DaliDatasyncServiceImpl : DaliDatasyncService { lastdayDpsamt = 0.00 opendate = systime.hostdate } - account.generateTac() account.tenantid = TenantContext.getTenantSchema() + account.generateTac() accountDao.save(account) } @@ -125,25 +129,25 @@ class DaliDatasyncServiceImpl : DaliDatasyncService { } //fixme: bean.cardstatus 判断修改状态 - if(TradeDict.STATUS_CLOSED == cardStatus){ + if (TradeDict.STATUS_CLOSED == cardStatus) { //注销卡片 - if(cityCard.status != TradeDict.STATUS_CLOSED){ + if (cityCard.status != TradeDict.STATUS_CLOSED) { cardUpdateFlag = true cityCard.status = TradeDict.STATUS_CLOSED } - }else{ + } else { //卡片的其他状态,代表交易状态 - if(TradeDict.STATUS_NORMAL != cityCard.transStatus){ + if (TradeDict.STATUS_NORMAL != cityCard.transStatus) { cardUpdateFlag = true cityCard.status = TradeDict.STATUS_NORMAL } - if(cardStatus != cityCard.transStatus){ + if (cardStatus != cityCard.transStatus) { cardUpdateFlag = true - cityCard.transStatus=cardStatus + cityCard.transStatus = cardStatus } } - if(cardUpdateFlag){ + if (cardUpdateFlag) { cityCard.lastsaved = systime.hostdatetime cardDao.save(cityCard) //更新 } @@ -201,4 +205,60 @@ class DaliDatasyncServiceImpl : DaliDatasyncService { return true } + override fun doBatchSaveOrUpdateUserInfos(userlist: ArrayList): Boolean { + for (bean in userlist) { + bean.checkParam() + doUpdateUserInfos(bean) + } + return true + } + + override fun saveUpdateUserinfoErrors(bean: DaliDatasyncDetail, errmsg: String) { + citycardTempDao.save(TCitycardTemp().apply { + this.cardno = bean.cardno + this.cardphyid = bean.cardphyid + this.expiredate = bean.expiredate + this.cardstatus = bean.cardstatus + this.bankcardno = bean.bankcardno + this.username = bean.username + this.sex = bean.sex + this.idtype = bean.idtype + this.idno = bean.idno + this.mobile = bean.mobile + this.email = bean.email + this.status = TradeDict.DTL_STATUS_FAIL + this.remark = errmsg + this.lastsaved = systemUtilService.sysdatetime.hostdatetime + this.tenantid = TenantContext.getTenantSchema() + }) + } + + override fun getErrorUpdateUserinfos(tmpid: String, updtime: String): List { + if (!StringUtil.isEmpty(tmpid)) { + return citycardTempDao.findbyTempid(tmpid.trim()) ?: ArrayList() + } else { + return citycardTempDao.findbyUpdtime(updtime) ?: ArrayList() + } + } + + override fun dealErrorRecord(temp: TCitycardTemp) { + val bean = DaliDatasyncDetail().apply { + this.cardno = temp.cardno + this.cardphyid = temp.cardphyid + this.expiredate = temp.expiredate + this.cardstatus = temp.cardstatus + this.bankcardno = temp.bankcardno + this.username = temp.username + this.sex = temp.sex + this.idtype = temp.idtype + this.idno = temp.idno + this.mobile = temp.mobile + this.email = temp.email + } + bean.checkParam() + if (doUpdateUserInfos(bean)) { + citycardTempDao.delete(temp) //删除 + } + } + } \ No newline at end of file diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java index 2c4ca84a..2b788c20 100644 --- a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java @@ -435,8 +435,9 @@ public class YnrccApiController { private void parseFile(String filePath, OutputStream output) { int lineno = 1; + BufferedReader reader = null; try { - BufferedReader reader = new BufferedReader( + reader = new BufferedReader( new InputStreamReader( new FileInputStream(filePath), "GBK")); String header = reader.readLine(); @@ -488,6 +489,13 @@ public class YnrccApiController { } catch (IOException e) { e.printStackTrace(); throw new IllegalArgumentException("对账文件数据格式错误,行数 " + lineno + " 。"); + } finally { + try { + if (null != reader) { + reader.close(); + } + } catch (Exception ex) { + } } }