增加了异步扣费及定时任务扣费功能
diff --git a/build.gradle b/build.gradle
index a2789f4..7c8ec76 100644
--- a/build.gradle
+++ b/build.gradle
@@ -85,20 +85,22 @@
implementation group: 'com.sun.jersey', name: 'jersey-client', version: '1.19'
implementation group: 'javax.servlet', name: 'jstl', version: '1.2'
implementation group: 'taglibs', name: 'standard', version: '1.1.2'
- implementation group: 'commons-codec', name: 'commons-codec', version: '1.6'
+ implementation group: 'commons-codec', name: 'commons-codec', version: '1.13'
+ implementation 'net.javacrumbs.shedlock:shedlock-spring:2.5.0'
+ implementation 'net.javacrumbs.shedlock:shedlock-provider-redis-spring:2.5.0'
implementation files('libs/ojdbc6.jar')
annotationProcessor 'org.projectlombok:lombok:1.18.8'
compileOnly 'org.projectlombok:lombok:1.18.8'
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
- compile 'com.supwisdom:payapi-sdk:b5eceda'
+ compile 'com.supwisdom:payapi-sdk:a315360'
// providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.rest-assured:rest-assured:3.3.0'
testImplementation 'io.rest-assured:spring-mock-mvc:3.3.0'
- testImplementation 'org.hamcrest:hamcrest:2.1'
+ implementation 'org.hamcrest:hamcrest:2.1'
}
compileKotlin {
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TPersonIdentity.java b/src/main/java/com/supwisdom/dlpay/api/domain/TPersonIdentity.java
index f1e89d7..b61b293 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TPersonIdentity.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TPersonIdentity.java
@@ -31,10 +31,32 @@
@Column(name = "CREATETIME", length = 14)
private String createtime;
+ @Column(name = "COAMOUNT",precision = 10, scale = 2)
+ private Double coamount;
+
+ @Column(name = "ACCAMOUNT",precision = 10, scale = 2)
+ private Double accamount;
+
+ public Double getCoamount() {
+ return coamount;
+ }
+
+ public void setCoamount(Double coamount) {
+ this.coamount = coamount;
+ }
+
+ public Double getAccamount() {
+ return accamount;
+ }
+
+ public void setAccamount(Double accamount) {
+ this.accamount = accamount;
+ }
+
public TPersonIdentity() {
}
- public TPersonIdentity(String thirdUid, TPerson person, String status, Integer lossflag, Integer lockflag, String createtime,String cardphyId) {
+ public TPersonIdentity(String thirdUid, TPerson person, String status, Integer lossflag, Integer lockflag, String createtime,String cardphyId,Double coamount,Double accamount) {
this.thirdUid = thirdUid;
this.person = person;
this.status = status;
@@ -42,6 +64,8 @@
this.lockflag = lockflag;
this.createtime = createtime;
this.cardphyId = cardphyId;
+ this.coamount = coamount;
+ this.accamount = accamount;
}
public String getCardphyId() {
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/Constants.java b/src/main/java/com/supwisdom/dlpay/framework/util/Constants.java
index 17dd6bc..25cecd0 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/Constants.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/Constants.java
@@ -8,4 +8,5 @@
public static final String JWT_CLAIM_TENANTID = "tenantId";
public static final String JWT_CLAIM_UID = "uid";
public static final String JWT_CLAIM_AUTHORITIES = "authorities";
+ public static final String DTLTYPE_WATER = "water";
}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/Dictionary.java b/src/main/java/com/supwisdom/dlpay/framework/util/Dictionary.java
index 46377e9..6566a76 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/Dictionary.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/Dictionary.java
@@ -7,6 +7,7 @@
public static final String IDTYPE = "idtypeList";
public static final String SEX = "sexList";
public static final String ACCOUNT_STATUS = "accountStatusList";
+ public final static String WATER_DEVICE_STATUS = "device_status";
/////////////////////////////////////
public static final String SOURCE_TYPE = "sourcetypeList";
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java b/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java
index 3740b9a..b554784 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java
@@ -134,4 +134,6 @@
public static final int REQUEST_PARAM_EEROR = 300003; //请求参数错误
+ public static final int WAIT_QUERY_RESULT = 55555; //查询结果
+
}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/WaterBudinessConstants.java b/src/main/java/com/supwisdom/dlpay/framework/util/WaterBudinessConstants.java
index 1f24d3d..c7aa81c 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/WaterBudinessConstants.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/WaterBudinessConstants.java
@@ -3,5 +3,5 @@
public class WaterBudinessConstants {
public final static String waterAuthUrl = "water_auth_url";
public final static String waterSinaShortUrl = "water_sina_shorturl";
- public final static String waterDeviceStatus = "device_status";
+ public final static String WATER_SHOP_ACCNO = "water_shopaccno";
}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/WaterDeviceParam.java b/src/main/java/com/supwisdom/dlpay/framework/util/WaterDeviceParam.java
index 22534a9..8ad1e25 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/WaterDeviceParam.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/WaterDeviceParam.java
@@ -18,7 +18,7 @@
// 单位扣费流量
public static final String feeUnit = "feeunit";
// 交易号
- public static final String billNo = "billno";
+ public static final String cobillNo = "cobillno";
// 从第多少百毫升开始计费
public static final String feestart = "feestart";
// 二维码失效时间
@@ -31,4 +31,6 @@
public static final String payStatus = "paystatus";
// 订单已支付金额
public static final String paidAmount = "paidAmount";
+ // 立即扣费阈值
+ public static final String imdDecThreshold = "imdDecThreshold";
}
diff --git a/src/main/java/com/supwisdom/dlpay/system/service/UserDataService.java b/src/main/java/com/supwisdom/dlpay/system/service/UserDataService.java
index 0c067dc..b146230 100644
--- a/src/main/java/com/supwisdom/dlpay/system/service/UserDataService.java
+++ b/src/main/java/com/supwisdom/dlpay/system/service/UserDataService.java
@@ -42,4 +42,10 @@
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class,readOnly = true)
TPersonIdentity getPersonIdentityByThirdUid(String thirdUid);
+
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
+ TPersonIdentity updateCoamount(String thirdUid,Double amount);
+
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
+ TPersonIdentity updateAccamount(String thirdUid,Double amount);
}
diff --git a/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java b/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java
index e7f8fd5..a43a761 100644
--- a/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java
+++ b/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java
@@ -25,163 +25,185 @@
@Service
public class UserDataServiceImpl implements UserDataService {
- @Autowired
- private PersonDao personDao;
- @Autowired
- private AccountDao accountDao;
- @Autowired
- private PointsAccountDao pointsAccountDao;
- @Autowired
- private SystemUtilService systemUtilService;
- @Autowired
- private PersonIdentityDao personIdentityDao;
+ @Autowired
+ private PersonDao personDao;
+ @Autowired
+ private AccountDao accountDao;
+ @Autowired
+ private PointsAccountDao pointsAccountDao;
+ @Autowired
+ private SystemUtilService systemUtilService;
+ @Autowired
+ private PersonIdentityDao personIdentityDao;
- @Override
- public PageResult<TPerson> getPersonsByKey(PersonParamBean param) {
- Pageable pageable = PageRequest.of(param.getPageNo() - 1, param.getPageSize()
- , Sort.by(Sort.Direction.DESC, "lastsaved"));
- if (!StringUtil.isEmpty(param.getName())) {
- return new PageResult<>(personDao.findAllByNameContaining(param.getName(), pageable));
- }
- return new PageResult<>(personDao.findAll(pageable));
- }
-
- @Override
- public PageResult<TAccount> getAccountsByKey(PersonParamBean param) {
- Pageable pageable = PageRequest.of(param.getPageNo() - 1, param.getPageSize());
- if (!StringUtil.isEmpty(param.getName())) {
- return new PageResult<>(accountDao.findAllByAccnameContaining(param.getName(), pageable));
- }
- return new PageResult<>(accountDao.findAll(pageable));
- }
-
- @Override
- public PageResult<TPointsAccount> getPointsByKey(PersonParamBean param) {
- Pageable pageable = PageRequest.of(param.getPageNo() - 1, param.getPageSize());
- if (!StringUtil.isEmpty(param.getName())) {
- return new PageResult<>(pointsAccountDao.findAllByNameContaining(param.getName(), pageable));
- }
- return new PageResult<>(pointsAccountDao.findAll(pageable));
- }
-
- @Override
- public JsonResult saveUser(TPerson person) {
- if (!StringUtil.isEmpty(person.getUserid())) {
- Optional<TPerson> temp = personDao.findById(person.getUserid());
- if (!temp.isPresent()) {
- return JsonResult.error("参数错误");
- }
- TPerson it = temp.get();
- if (!person.getIdno().equals(it.getIdno())
- || !person.getIdtype().equals(it.getIdtype())) {
- TPerson has = personDao.findByIdentity(person.getIdtype(), person.getIdno());
- if (has != null && !has.getUserid().equals(person.getUserid())) {
- return JsonResult.error("证件类型、证件号已存在");
+ @Override
+ public PageResult<TPerson> getPersonsByKey(PersonParamBean param) {
+ Pageable pageable = PageRequest.of(param.getPageNo() - 1, param.getPageSize()
+ , Sort.by(Sort.Direction.DESC, "lastsaved"));
+ if (!StringUtil.isEmpty(param.getName())) {
+ return new PageResult<>(personDao.findAllByNameContaining(param.getName(), pageable));
}
- }
- if (!person.getName().equals(it.getName())) {
- TAccount account = accountDao.findByUserid(person.getUserid());
+ return new PageResult<>(personDao.findAll(pageable));
+ }
+
+ @Override
+ public PageResult<TAccount> getAccountsByKey(PersonParamBean param) {
+ Pageable pageable = PageRequest.of(param.getPageNo() - 1, param.getPageSize());
+ if (!StringUtil.isEmpty(param.getName())) {
+ return new PageResult<>(accountDao.findAllByAccnameContaining(param.getName(), pageable));
+ }
+ return new PageResult<>(accountDao.findAll(pageable));
+ }
+
+ @Override
+ public PageResult<TPointsAccount> getPointsByKey(PersonParamBean param) {
+ Pageable pageable = PageRequest.of(param.getPageNo() - 1, param.getPageSize());
+ if (!StringUtil.isEmpty(param.getName())) {
+ return new PageResult<>(pointsAccountDao.findAllByNameContaining(param.getName(), pageable));
+ }
+ return new PageResult<>(pointsAccountDao.findAll(pageable));
+ }
+
+ @Override
+ public JsonResult saveUser(TPerson person) {
+ if (!StringUtil.isEmpty(person.getUserid())) {
+ Optional<TPerson> temp = personDao.findById(person.getUserid());
+ if (!temp.isPresent()) {
+ return JsonResult.error("参数错误");
+ }
+ TPerson it = temp.get();
+ if (!person.getIdno().equals(it.getIdno())
+ || !person.getIdtype().equals(it.getIdtype())) {
+ TPerson has = personDao.findByIdentity(person.getIdtype(), person.getIdno());
+ if (has != null && !has.getUserid().equals(person.getUserid())) {
+ return JsonResult.error("证件类型、证件号已存在");
+ }
+ }
+ if (!person.getName().equals(it.getName())) {
+ TAccount account = accountDao.findByUserid(person.getUserid());
+ if (account != null) {
+ account.setAccname(person.getName());
+ accountDao.save(account);
+ }
+ }
+ if (StringUtil.isEmpty(person.getStatus())) {
+ person.setStatus(TradeDict.STATUS_NORMAL);
+ }
+ personDao.save(person);
+ } else {
+ TPerson has = personDao.findByIdentity(person.getIdtype(), person.getIdno());
+ if (has != null) {
+ return JsonResult.error("证件类型、证件号已存在");
+ }
+ SystemDateTime systemDateTime = systemUtilService.getSysdatetime();
+ person.setStatus(TradeDict.STATUS_NORMAL);
+ person.setLastsaved(systemDateTime.getHostdatetime());
+ person = personDao.save(person);
+
+ TAccount account = new TAccount();
+ account.setAccname(person.getName());
+ account.setSubjno(Subject.SUBJNO_PERSONAL_DEPOSIT);
+ account.setUserid(person.getUserid());
+ account.setStatus(person.getStatus());
+ account.setBalance(0.0);
+ account.setAvailbal(0.0);
+ account.setFrozebal(0.0);
+ account.setLowfreeFlag(false);
+ account.setMaxbal(systemUtilService.getSysparaValueAsDouble(SysparaUtil.SYSPARAID_NO1, SysparaUtil.SYSPARA_NO1_DEFAULT));
+ account.setLasttransdate(systemDateTime.getHostdate());
+ account.setLastdayDpsamt(0.0);
+ account.setLastdayTransamt(0.0);
+ account.setOpendate(systemDateTime.getHostdate());
+ account.setTac(account.generateTac());
+ accountDao.save(account);
+ }
+ return JsonResult.ok("添加成功");
+ }
+
+ @Override
+ public JsonResult deleteUser(String userid) {
+ TAccount account = accountDao.findByUserid(userid);
if (account != null) {
- account.setAccname(person.getName());
- accountDao.save(account);
+ if (!TradeDict.STATUS_CLOSED.equals(account.getStatus()) && account.getBalance() != 0) {
+ return JsonResult.error("该用户账户未注销且余额不为0,无法删除");
+ } else {
+ accountDao.delete(account);
+ }
}
- }
- if (StringUtil.isEmpty(person.getStatus())) {
- person.setStatus(TradeDict.STATUS_NORMAL);
- }
- personDao.save(person);
- } else {
- TPerson has = personDao.findByIdentity(person.getIdtype(), person.getIdno());
- if (has != null) {
- return JsonResult.error("证件类型、证件号已存在");
- }
- SystemDateTime systemDateTime = systemUtilService.getSysdatetime();
- person.setStatus(TradeDict.STATUS_NORMAL);
- person.setLastsaved(systemDateTime.getHostdatetime());
- person = personDao.save(person);
-
- TAccount account = new TAccount();
- account.setAccname(person.getName());
- account.setSubjno(Subject.SUBJNO_PERSONAL_DEPOSIT);
- account.setUserid(person.getUserid());
- account.setStatus(person.getStatus());
- account.setBalance(0.0);
- account.setAvailbal(0.0);
- account.setFrozebal(0.0);
- account.setLowfreeFlag(false);
- account.setMaxbal(systemUtilService.getSysparaValueAsDouble(SysparaUtil.SYSPARAID_NO1, SysparaUtil.SYSPARA_NO1_DEFAULT));
- account.setLasttransdate(systemDateTime.getHostdate());
- account.setLastdayDpsamt(0.0);
- account.setLastdayTransamt(0.0);
- account.setOpendate(systemDateTime.getHostdate());
- account.setTac(account.generateTac());
- accountDao.save(account);
+ TPointsAccount pointsAccount = pointsAccountDao.findByUserid(userid);
+ if (pointsAccount != null) {
+ if (pointsAccount.getPoints() != 0) {
+ return JsonResult.error("该用户账户积分不为0,无法删除,若要删除请先删除积分账户");
+ } else {
+ pointsAccountDao.delete(pointsAccount);
+ }
+ }
+ personDao.deleteById(userid);
+ return JsonResult.ok("操作成功");
}
- return JsonResult.ok("添加成功");
- }
- @Override
- public JsonResult deleteUser(String userid) {
- TAccount account = accountDao.findByUserid(userid);
- if (account != null) {
- if (!TradeDict.STATUS_CLOSED.equals(account.getStatus()) && account.getBalance() != 0) {
- return JsonResult.error("该用户账户未注销且余额不为0,无法删除");
- } else {
- accountDao.delete(account);
- }
+ @Override
+ public JsonResult closeAccount(String accno) {
+ Optional<TAccount> opt = accountDao.findById(accno);
+ if (opt.isPresent()) {
+ TAccount acc = opt.get();
+ acc.setStatus(TradeDict.STATUS_CLOSED);
+ accountDao.save(acc);
+ return JsonResult.ok("操作成功");
+ } else {
+ return JsonResult.error("参数错误");
+ }
}
- TPointsAccount pointsAccount = pointsAccountDao.findByUserid(userid);
- if (pointsAccount != null) {
- if (pointsAccount.getPoints() != 0) {
- return JsonResult.error("该用户账户积分不为0,无法删除,若要删除请先删除积分账户");
- } else {
- pointsAccountDao.delete(pointsAccount);
- }
+
+ @Override
+ public JsonResult deletePoint(String userid) {
+ Optional<TPointsAccount> pointsAccount = pointsAccountDao.findById(userid);
+ if (pointsAccount.isPresent()) {
+ pointsAccountDao.delete(pointsAccount.get());
+ return JsonResult.ok("操作成功");
+ } else {
+ return JsonResult.error("参数错误");
+ }
}
- personDao.deleteById(userid);
- return JsonResult.ok("操作成功");
- }
- @Override
- public JsonResult closeAccount(String accno) {
- Optional<TAccount> opt = accountDao.findById(accno);
- if (opt.isPresent()) {
- TAccount acc = opt.get();
- acc.setStatus(TradeDict.STATUS_CLOSED);
- accountDao.save(acc);
- return JsonResult.ok("操作成功");
- } else {
- return JsonResult.error("参数错误");
+ @Override
+ public List<TPersonIdentity> getPersonIdentity(String userid) {
+ return null;
}
- }
- @Override
- public JsonResult deletePoint(String userid) {
- Optional<TPointsAccount> pointsAccount = pointsAccountDao.findById(userid);
- if (pointsAccount.isPresent()) {
- pointsAccountDao.delete(pointsAccount.get());
- return JsonResult.ok("操作成功");
- }else {
- return JsonResult.error("参数错误");
+ @Override
+ public PageResult<TPointsAccount> getUserPointDTL(PersonParamBean param) {
+ return null;
}
- }
- @Override
- public List<TPersonIdentity> getPersonIdentity(String userid) {
- return null;
- }
-
- @Override
- public PageResult<TPointsAccount> getUserPointDTL(PersonParamBean param) {
- return null;
- }
-
- @Override
- public TPersonIdentity getPersonIdentityByThirdUid(String thirdUid) {
- TPersonIdentity personIdentity = personIdentityDao.getByThirdUid(thirdUid);
- if (personIdentity != null) {
- return personIdentity;
+ @Override
+ public TPersonIdentity getPersonIdentityByThirdUid(String thirdUid) {
+ TPersonIdentity personIdentity = personIdentityDao.getByThirdUid(thirdUid);
+ if (personIdentity != null) {
+ return personIdentity;
+ }
+ return null;
}
- return null;
- }
+
+ @Override
+ public TPersonIdentity updateCoamount(String thirdUid, Double amount) {
+ TPersonIdentity personIdentity = personIdentityDao.getByThirdUid(thirdUid);
+ if (null == personIdentity) {
+ throw new RuntimeException("未找到用户id为" + thirdUid + "的用户");
+ }
+ personIdentity.setCoamount(personIdentity.getCoamount() == null ? amount : personIdentity.getCoamount() + amount);
+ personIdentityDao.save(personIdentity);
+ return personIdentity;
+ }
+
+ @Override
+ public TPersonIdentity updateAccamount(String thirdUid, Double amount) {
+ TPersonIdentity personIdentity = personIdentityDao.getByThirdUid(thirdUid);
+ if (null == personIdentity) {
+ throw new RuntimeException("未找到用户id为" + thirdUid + "的用户");
+ }
+ personIdentity.setAccamount(personIdentity.getAccamount() == null ? amount : personIdentity.getAccamount() + amount);
+ personIdentityDao.save(personIdentity);
+ return personIdentity;
+ }
}
diff --git a/src/main/java/com/supwisdom/dlpay/water/dao/AccdtlDao.java b/src/main/java/com/supwisdom/dlpay/water/dao/AccdtlDao.java
new file mode 100644
index 0000000..0a1d624
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/water/dao/AccdtlDao.java
@@ -0,0 +1,21 @@
+package com.supwisdom.dlpay.water.dao;
+
+import com.supwisdom.dlpay.water.domain.TAccdtl;
+import org.springframework.data.jpa.repository.Lock;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.jpa.repository.QueryHints;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.LockModeType;
+import javax.persistence.QueryHint;
+
+@Repository
+public interface AccdtlDao extends CrudRepository<TAccdtl, String> {
+ @Lock(LockModeType.PESSIMISTIC_WRITE)
+ @Query("select t from TAccdtl t where t.billno=?1")
+ @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "0")})
+ TAccdtl findByBillnoForUpdate(String billno);
+
+ TAccdtl findByBillno(String billno);
+}
\ No newline at end of file
diff --git a/src/main/java/com/supwisdom/dlpay/water/dao/CollectdtlDao.java b/src/main/java/com/supwisdom/dlpay/water/dao/CollectdtlDao.java
new file mode 100644
index 0000000..f30cad3
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/water/dao/CollectdtlDao.java
@@ -0,0 +1,33 @@
+package com.supwisdom.dlpay.water.dao;
+
+import com.supwisdom.dlpay.water.domain.TCollectdtl;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.Lock;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.jpa.repository.QueryHints;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.LockModeType;
+import javax.persistence.QueryHint;
+import java.util.List;
+
+@Repository
+public interface CollectdtlDao extends CrudRepository<TCollectdtl, Integer> {
+ @Lock(LockModeType.PESSIMISTIC_WRITE)
+ @Query("select t from TCollectdtl t where t.cobillno=?1")
+ @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "0")})
+ TCollectdtl findByCobillnoForUpdate(Integer cobillno);
+
+ @Lock(LockModeType.PESSIMISTIC_WRITE)
+ @Query("select t from TCollectdtl t where t.entryno=?1")
+ @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "0")})
+ TCollectdtl findByEntrynoForUpdate(String entryno);
+
+ @Lock(LockModeType.PESSIMISTIC_WRITE)
+ @Query("select t from TCollectdtl t where t.status='wip'")
+ @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "0")})
+ List<TCollectdtl> findWipCollectdtl(Pageable pageable);
+
+ TCollectdtl findByCobillnoAndDeviceno(Integer cobillno, String deviceno);
+}
diff --git a/src/main/java/com/supwisdom/dlpay/water/dao/TransdtlDao.java b/src/main/java/com/supwisdom/dlpay/water/dao/TransdtlDao.java
deleted file mode 100644
index 3945100..0000000
--- a/src/main/java/com/supwisdom/dlpay/water/dao/TransdtlDao.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.supwisdom.dlpay.water.dao;
-
-import com.supwisdom.dlpay.water.domain.TTransdtl;
-import org.springframework.data.jpa.repository.Lock;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.jpa.repository.QueryHints;
-import org.springframework.data.repository.CrudRepository;
-import org.springframework.stereotype.Repository;
-
-import javax.persistence.LockModeType;
-import javax.persistence.QueryHint;
-
-@Repository
-public interface TransdtlDao extends CrudRepository<TTransdtl, String> {
- @Lock(LockModeType.PESSIMISTIC_WRITE)
- @Query("select t from TTransdtl t where t.billno=?1")
- @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "0")})
- TTransdtl findByBillnoForUpdate(String billno);
-
- TTransdtl findByBillnoAndDeviceno(String billno, String deviceno);
-}
diff --git a/src/main/java/com/supwisdom/dlpay/water/domain/TAccdtl.java b/src/main/java/com/supwisdom/dlpay/water/domain/TAccdtl.java
new file mode 100644
index 0000000..88265bb
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/water/domain/TAccdtl.java
@@ -0,0 +1,160 @@
+package com.supwisdom.dlpay.water.domain;
+
+import javax.persistence.*;
+import javax.validation.constraints.NotNull;
+
+@Entity
+@Table(name = "tb_accentrydtl",
+ indexes = {@Index(name = "accdtl_userid", columnList = "userid"),
+ @Index(name = "accdtl_status", columnList = "status"),
+ @Index(name = "accdtl_acc", columnList = "accdate")})
+public class TAccdtl {
+ @Id
+ @Column(name = "billno", length = 32)
+ private String billno;
+
+ @Column(length = 16)
+ private String status;
+
+ @Column(name = "transdate", length = 14)
+ @NotNull
+ private String transDate;
+
+ @Column(name = "transtime", length = 6)
+ @NotNull
+ private String transTime;
+
+ @Column(length = 8)
+ @NotNull
+ private String deviceno;
+
+ @Column(length = 32)
+ private String userid;
+
+ @Column(name = "bankcardno", length = 32)
+ private String citizenCardno;
+
+ @Column(length = 20)
+ @NotNull
+ private String mode;
+
+ @Column(precision = 10, scale = 2)
+ private Double amount;
+
+ @Column(name = "water_in_100ml", precision = 10)
+ private Integer waterSumHundredLitre;
+
+ @Column(name = "accdate", length = 8)
+ private String accdate;
+
+ @Column(name = "cardphyid",length = 60)
+ private String cardPhyId;
+
+ @Column(name = "refno", length = 32)
+ private String refno;
+
+
+ public String getRefno() {
+ return refno;
+ }
+
+ public void setRefno(String refno) {
+ this.refno = refno;
+ }
+
+ public String getBillno() {
+ return billno;
+ }
+
+ public void setBillno(String billno) {
+ this.billno = billno;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getTransDate() {
+ return transDate;
+ }
+
+ public void setTransDate(String transDate) {
+ this.transDate = transDate;
+ }
+
+ public String getTransTime() {
+ return transTime;
+ }
+
+ public void setTransTime(String transTime) {
+ this.transTime = transTime;
+ }
+
+ public String getDeviceno() {
+ return deviceno;
+ }
+
+ public void setDeviceno(String deviceno) {
+ this.deviceno = deviceno;
+ }
+
+ public String getUserid() {
+ return userid;
+ }
+
+ public void setUserid(String userid) {
+ this.userid = userid;
+ }
+
+ public String getCitizenCardno() {
+ return citizenCardno;
+ }
+
+ public void setCitizenCardno(String citizenCardno) {
+ this.citizenCardno = citizenCardno;
+ }
+
+ public String getMode() {
+ return mode;
+ }
+
+ public void setMode(String mode) {
+ this.mode = mode;
+ }
+
+ public Double getAmount() {
+ return amount;
+ }
+
+ public void setAmount(Double amount) {
+ this.amount = amount;
+ }
+
+ public Integer getWaterSumHundredLitre() {
+ return waterSumHundredLitre;
+ }
+
+ public void setWaterSumHundredLitre(Integer waterSumHundredLitre) {
+ this.waterSumHundredLitre = waterSumHundredLitre;
+ }
+
+ public String getAccdate() {
+ return accdate;
+ }
+
+ public void setAccdate(String accdate) {
+ this.accdate = accdate;
+ }
+
+ public String getCardPhyId() {
+ return cardPhyId;
+ }
+
+ public void setCardPhyId(String cardPhyId) {
+ this.cardPhyId = cardPhyId;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/supwisdom/dlpay/water/domain/TTransdtl.java b/src/main/java/com/supwisdom/dlpay/water/domain/TCollectdtl.java
similarity index 71%
rename from src/main/java/com/supwisdom/dlpay/water/domain/TTransdtl.java
rename to src/main/java/com/supwisdom/dlpay/water/domain/TCollectdtl.java
index f8e4b79..09c43f2 100644
--- a/src/main/java/com/supwisdom/dlpay/water/domain/TTransdtl.java
+++ b/src/main/java/com/supwisdom/dlpay/water/domain/TCollectdtl.java
@@ -4,16 +4,18 @@
import javax.validation.constraints.NotNull;
@Entity
-@Table(name = "tb_transdtl",
- indexes = {@Index(name = "trasndtl_userid", columnList = "userid"),
- @Index(name = "transdtl_status", columnList = "transdate, status"),
- @Index(name = "transdtl_acc", columnList = "accdate")})
-public class TTransdtl {
+@Table(name = "tb_collectdtl",
+ indexes = {@Index(name = "collectdtl_userid", columnList = "userid"),
+ @Index(name = "collectdtl_status", columnList = "transdate, status"),
+ @Index(name = "collectdtl_acc", columnList = "accdate")})
+@SequenceGenerator(name = "SEQ_COLLECT_BILLNO", sequenceName = "SEQ_COLLECT_BILLNO", allocationSize = 1)
+public class TCollectdtl {
@Id
- @Column(name = "billno", length = 32)
- private String billno;
+ @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_COLLECT_BILLNO")
+ @Column(name = "cobillno", nullable = false)
+ private Integer cobillno;
- @Column(name = "transdate", length = 8)
+ @Column(name = "transdate", length = 14)
@NotNull
private String transDate;
@@ -28,8 +30,8 @@
@Column(length = 32)
private String userid;
- @Column(name = "bankcardno", length = 32)
- private String bankCardNo;
+ @Column(name = "citizencardno", length = 32)
+ private String citizenCardno;
@Column(length = 20)
@NotNull
@@ -51,11 +53,8 @@
@Column(name = "accdate", length = 8)
private String accdate;
- @Column(name = "refno", length = 32)
- private String refno;
-
- @Column(name = "accstatus", length = 10)
- private String accStatus;
+ @Column(name = "entryno", length = 32)
+ private String entryno;
@Column(name = "authstatus")
private Boolean authStatus;
@@ -90,12 +89,12 @@
this.authStatus = authStatus;
}
- public String getBillno() {
- return billno;
+ public Integer getCobillno() {
+ return cobillno;
}
- public void setBillno(String billno) {
- this.billno = billno;
+ public void setCobillno(Integer cobillno) {
+ this.cobillno = cobillno;
}
public String getDeviceno() {
@@ -130,12 +129,12 @@
this.userid = userid;
}
- public String getBankCardNo() {
- return bankCardNo;
+ public String getCitizenCardno() {
+ return citizenCardno;
}
- public void setBankCardNo(String bankCardNo) {
- this.bankCardNo = bankCardNo;
+ public void setCitizenCardno(String citizenCardno) {
+ this.citizenCardno = citizenCardno;
}
public String getMode() {
@@ -186,19 +185,12 @@
this.accdate = accdate;
}
- public String getRefno() {
- return refno;
+ public String getEntryno() {
+ return entryno;
}
- public void setRefno(String refno) {
- this.refno = refno;
+ public void setEntryno(String entryno) {
+ this.entryno = entryno;
}
- public String getAccStatus() {
- return accStatus;
- }
-
- public void setAccStatus(String accStatus) {
- this.accStatus = accStatus;
- }
}
diff --git a/src/main/java/com/supwisdom/dlpay/water/domain/TTransdtlCount.java b/src/main/java/com/supwisdom/dlpay/water/domain/TTransdtlCount.java
index 21204c5..598b0ad 100644
--- a/src/main/java/com/supwisdom/dlpay/water/domain/TTransdtlCount.java
+++ b/src/main/java/com/supwisdom/dlpay/water/domain/TTransdtlCount.java
@@ -7,7 +7,8 @@
@Table(name = "tb_transdtl_count",
indexes = {@Index(name = "trasndtl_count_accdate", columnList = "accdate"),
@Index(name = "transdtl_count_areano", columnList = "areano"),
- @Index(name = "transdtl_count_devicename", columnList = "devicename")})
+ @Index(name = "transdtl_count_devicename", columnList = "devicename"),
+ @Index(name = "transdtl_count_idx", columnList = "accdate, areano, deviceno", unique = true)})
@SequenceGenerator(name = "SEQ_TRANSDTL_COUNT", sequenceName = "SEQ_TRANSDTL_COUNT", allocationSize = 1, initialValue = 1000)
public class TTransdtlCount {
@Id
diff --git a/src/main/java/com/supwisdom/dlpay/water/init/PayInit.java b/src/main/java/com/supwisdom/dlpay/water/init/PayInit.java
deleted file mode 100644
index 1389880..0000000
--- a/src/main/java/com/supwisdom/dlpay/water/init/PayInit.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.supwisdom.dlpay.water.init;
-
-import com.supwisdom.dlpay.paysdk.ApiLoginHelper;
-import com.supwisdom.dlpay.paysdk.proxy.ApiLoginProxy;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cloud.openfeign.EnableFeignClients;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.PostConstruct;
-
-@Component
-@EnableFeignClients(basePackages = "com.supwisdom.dlpay.paysdk")
-@ComponentScan(basePackages = {"com.supwisdom.dlpay.paysdk"})
-public class PayInit {
-
- private final static String appid = "700001";
- private final static String secret = "5f788ce433ec44f299351cdf7f137e81";
-
- @Autowired
- private ApiLoginProxy apiLoginProxy;
-
-// @PostConstruct
-// public void login() {
-// ApiLoginHelper helper = new ApiLoginHelper(apiLoginProxy);
-// helper.login(appid,secret);
-// }
-}
diff --git a/src/main/java/com/supwisdom/dlpay/water/pay/PayInit.java b/src/main/java/com/supwisdom/dlpay/water/pay/PayInit.java
new file mode 100644
index 0000000..c99b406
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/water/pay/PayInit.java
@@ -0,0 +1,44 @@
+package com.supwisdom.dlpay.water.pay;
+
+import com.supwisdom.dlpay.api.bean.ApiVersionResponse;
+import com.supwisdom.dlpay.paysdk.ApiLoginHelper;
+import com.supwisdom.dlpay.paysdk.proxy.ApiCommonProxy;
+import com.supwisdom.dlpay.paysdk.proxy.ApiLoginProxy;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.notNullValue;
+
+@Component
+@EnableFeignClients(basePackages = "com.supwisdom.dlpay.paysdk")
+@ComponentScan(basePackages = {"com.supwisdom.dlpay.paysdk"})
+public class PayInit {
+ @Value("${water.appid}")
+ private String appid;
+
+ @Value("${water.secret}")
+ private String secret;
+
+ @Autowired
+ private ApiLoginProxy apiLoginProxy;
+
+ @Autowired
+ private ApiCommonProxy apiCommonProxy;
+
+ @PostConstruct
+ public void login() {
+ ApiLoginHelper helper = new ApiLoginHelper(apiLoginProxy);
+ helper.login(appid,secret);
+ ApiVersionResponse version = apiCommonProxy.apiVersion();
+ assertThat("get version error " + version.getException(),
+ version.getVersion(), notNullValue());
+ }
+
+ //TODO:刷新TOKEN
+}
diff --git a/src/main/java/com/supwisdom/dlpay/water/pay/WaterPayAsyncTask.java b/src/main/java/com/supwisdom/dlpay/water/pay/WaterPayAsyncTask.java
new file mode 100644
index 0000000..1eeb82f
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/water/pay/WaterPayAsyncTask.java
@@ -0,0 +1,202 @@
+package com.supwisdom.dlpay.water.pay;
+
+import com.supwisdom.dlpay.api.bean.*;
+import com.supwisdom.dlpay.framework.service.BusinessparaService;
+import com.supwisdom.dlpay.framework.service.SystemUtilService;
+import com.supwisdom.dlpay.framework.util.Constants;
+import com.supwisdom.dlpay.framework.util.TradeDict;
+import com.supwisdom.dlpay.framework.util.TradeErrorCode;
+import com.supwisdom.dlpay.framework.util.WaterBudinessConstants;
+import com.supwisdom.dlpay.paysdk.proxy.CitizenCardPayProxy;
+import com.supwisdom.dlpay.paysdk.proxy.TransactionProxy;
+import com.supwisdom.dlpay.system.service.UserDataService;
+import com.supwisdom.dlpay.water.domain.TAccdtl;
+import com.supwisdom.dlpay.water.domain.TCollectdtl;
+import com.supwisdom.dlpay.water.service.AccdtlService;
+import com.supwisdom.dlpay.water.service.CollectdtlService;
+import org.hamcrest.MatcherAssert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import static org.hamcrest.Matchers.equalTo;
+
+
+@Component
+public class WaterPayAsyncTask {
+
+ private static final Logger logger = LoggerFactory.getLogger(WaterPayAsyncTask.class);
+
+ @Autowired
+ private CitizenCardPayProxy citizenCardPayProxy;
+
+ @Autowired
+ private TransactionProxy transactionProxy;
+
+ @Autowired
+ private SystemUtilService systemUtilService;
+
+ @Autowired
+ private AccdtlService accdtlService;
+
+ @Autowired
+ private UserDataService userDataService;
+
+ @Autowired
+ private CollectdtlService collectdtlService;
+
+ @Autowired
+ private BusinessparaService businessparaService;
+
+ @Async("waterPay")
+ public void waterPay(Integer cobillno) {
+ TCollectdtl collectdtl = collectdtlService.findByCobillnoForUpdate(cobillno);
+ // 是否已生成入账流水
+ if (collectdtl.getEntryno() != null) {
+ TAccdtl accdtl = accdtlService.findByBillno(collectdtl.getEntryno());
+ String accStatus = accdtl.getStatus();
+ if (null == accStatus) {
+ // 入账流水状态为空,需查询是否已初始化
+ QueryDtlResultParam queryParam = new QueryDtlResultParam();
+ queryParam.setBillno(accdtl.getBillno());
+ queryParam.setShopaccno(businessparaService.findByParakey(WaterBudinessConstants.WATER_SHOP_ACCNO).getParaval());
+ QueryTransDtlResponse queryResult = transactionProxy.queryDtlResult(queryParam);
+ if (0 == queryResult.getRetcode()) {
+ // 流水已初始化,进行确认
+ TAccdtl initAccdtl = initAcc(queryResult.getOutTradeNo(), queryResult.getRefno());
+ payConfirm(initAccdtl);
+ } else if (TradeErrorCode.TRANSACTION_NOT_EXISTS == queryResult.getRetcode()) {
+ // 流水尚未初始化,可直接扣费
+ waterPay(accdtl);
+ }
+ } else if (TradeDict.DTL_STATUS_FAIL.equals(accStatus)) {
+ // 入账流水扣费失败,重新生成入账流水扣费
+ TAccdtl newAccdtl = buildAccdtl(collectdtl);
+ newAccdtl = accdtlService.creatNewAccdtl(newAccdtl,collectdtl.getCobillno());
+ waterPay(newAccdtl);
+ } else if (TradeDict.DTL_STATUS_INIT.equals(accStatus) ||
+ TradeDict.DTL_STATUS_WIP.equals(accStatus)) {
+ // 入账流水状态为init,需查询是否已确认
+ QueryDtlResultParam queryParam = new QueryDtlResultParam();
+ queryParam.setRefno(accdtl.getRefno());
+ QueryTransDtlResponse queryResult = transactionProxy.queryDtlResult(queryParam);
+ if (0 == queryResult.getRetcode()) {
+ // 查询得到状态为init
+ if (TradeDict.DTL_STATUS_INIT.equals(queryResult.getStatus())) {
+ // 进行消费确认
+ payConfirm(accdtl);
+ } else if (TradeDict.DTL_STATUS_SUCCESS.equals(queryResult.getStatus())) {
+ // 查询得到状态为success或fail,记录下状态
+ userDataService.updateAccamount(accdtl.getCitizenCardno(), accdtl.getAmount());
+ cofirmAcc(queryResult.getStatus(), accdtl.getBillno(), accdtl.getRefno());
+ } else if (TradeDict.DTL_STATUS_FAIL.equals(queryResult.getStatus())) {
+ cofirmAcc(queryResult.getStatus(), accdtl.getBillno(), accdtl.getRefno());
+ }
+ } else if (TradeErrorCode.TRANSACTION_NOT_EXISTS == queryResult.getRetcode()) {
+ logger.error("入账流水:" + accdtl.getBillno() + "的refno:" + accdtl.getRefno() + "未找到");
+ }
+ }
+ } else {
+ // 未生成入账流水
+ // 生成一条入账流水,并将其billno存入对应的采集流水
+ TAccdtl accdtl = buildAccdtl(collectdtl);
+ accdtl = accdtlService.creatNewAccdtl(accdtl, collectdtl.getCobillno());
+ if (null == accdtl) {
+ return;
+ }
+ // 支付中心初始化并确认入账流水
+ waterPay(accdtl);
+ }
+ }
+
+ private void waterPay(TAccdtl accdtl) {
+ // 支付中心初始化入账流水
+ CitizenCardPayinitParam initParam = buildPayInitParam(accdtl);
+ CitizenPayResponse payInit = citizenCardPayProxy.citizencardPayinit(initParam);
+ MatcherAssert.assertThat("pay initialized " + payInit.getRetmsg() + payInit.getException(),
+ payInit.getRetcode(), equalTo(0));
+ // 初始化成功记录下refno,并修改入账流水状态为init
+ TAccdtl initAccdtl = initAcc(payInit.getBillno(), payInit.getRefno());
+ // 支付中心确认入账流水
+ payConfirm(initAccdtl);
+ }
+
+ private TAccdtl initAcc(String billno, String refno) {
+ InitAccParam initAccParam = new InitAccParam();
+ initAccParam.setBillno(billno);
+ initAccParam.setRefno(refno);
+ return accdtlService.initAcc(initAccParam);
+ }
+
+ private TAccdtl buildAccdtl(TCollectdtl collectdtl) {
+ TAccdtl accdtl = new TAccdtl();
+ accdtl.setDeviceno(collectdtl.getDeviceno());
+ accdtl.setUserid(collectdtl.getUserid());
+ accdtl.setCitizenCardno(collectdtl.getCitizenCardno());
+ accdtl.setMode(TradeDict.PAY_MODE_CARD);//TODO: 二维码消费
+ accdtl.setAmount(collectdtl.getAmount());
+ accdtl.setWaterSumHundredLitre(collectdtl.getWaterSumHundredLitre());
+ accdtl.setCardPhyId(collectdtl.getCardPhyId());
+ accdtl.setTransTime(collectdtl.getTransTime());
+ accdtl.setTransDate(collectdtl.getTransDate());
+ return accdtl;
+ }
+
+ private CitizenCardPayinitParam buildPayInitParam(TAccdtl accdtl) {
+ CitizenCardPayinitParam initParam = new CitizenCardPayinitParam();
+ initParam.setBillno(accdtl.getBillno());
+ initParam.setCardNo(accdtl.getCitizenCardno());
+ Double amount = (accdtl.getAmount() * 100);
+ initParam.setAmount(amount.intValue());
+ initParam.setDtltype(Constants.DTLTYPE_WATER);
+ initParam.setTransdate(accdtl.getTransDate());
+ initParam.setTranstime(accdtl.getTransTime());
+ initParam.setShopaccno(businessparaService.findByParakey(WaterBudinessConstants.WATER_SHOP_ACCNO).getParaval());
+ return initParam;
+ }
+
+ private void payConfirm(TAccdtl initAccdtl) {
+ CitizenCardPayfinishParam finishParam = new CitizenCardPayfinishParam();
+ finishParam.setRefno(initAccdtl.getRefno());
+ CitizenPayResponse payFinish = citizenCardPayProxy.citizencardPayFinish(finishParam);
+ //2.1 处理消费确认响应结果
+ int finishRetcode = payFinish.getRetcode();
+ String accStatus;
+ if (finishRetcode == 0) {
+ accStatus = TradeDict.DTL_STATUS_SUCCESS;
+ // 更新用户已入账金额
+ userDataService.updateAccamount(initAccdtl.getCitizenCardno(), initAccdtl.getAmount());
+ } else if (finishRetcode == TradeErrorCode.WAIT_QUERY_RESULT) {
+ QueryDtlResultParam queryParam = new QueryDtlResultParam();
+ queryParam.setRefno(payFinish.getRefno());
+ QueryTransDtlResponse queryResult = transactionProxy.queryDtlResult(queryParam);
+ if (0 == queryResult.getRetcode()) {
+ accStatus = queryResult.getStatus();
+ if (TradeDict.DTL_STATUS_SUCCESS.equals(accStatus)) {
+ userDataService.updateAccamount(initAccdtl.getCitizenCardno(), initAccdtl.getAmount());
+ }
+ } else {
+ accStatus = TradeDict.DTL_STATUS_WIP;
+ logger.error("查询确认结果失败:" + queryResult.getRetcode() + "," + queryResult.getRetmsg());
+ }
+ } else if (finishRetcode == TradeErrorCode.BUSINESS_DEAL_ERROR) {
+ accStatus = TradeDict.DTL_STATUS_FAIL;
+ } else {
+ accStatus = TradeDict.DTL_STATUS_WIP;
+ logger.error("未知的确认状态码:" + finishRetcode + "," + payFinish.getRetmsg());
+ }
+ //2.2 记录消费确认
+ cofirmAcc(accStatus, payFinish.getBillno(), payFinish.getRefno());
+ }
+
+ private void cofirmAcc(String accStatus, String billno, String refno) {
+ ConfirmAccParam accParam = new ConfirmAccParam();
+ accParam.setAccdate(systemUtilService.getSysdatetime().getHostdate());
+ accParam.setAccstatus(accStatus);
+ accParam.setBillno(billno);
+ accParam.setRefno(refno);
+ accdtlService.confirmAcc(accParam);
+ }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/water/service/AccdtlService.java b/src/main/java/com/supwisdom/dlpay/water/service/AccdtlService.java
new file mode 100644
index 0000000..8580f45
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/water/service/AccdtlService.java
@@ -0,0 +1,21 @@
+package com.supwisdom.dlpay.water.service;
+
+
+import com.supwisdom.dlpay.api.bean.ConfirmAccParam;
+import com.supwisdom.dlpay.api.bean.InitAccParam;
+import com.supwisdom.dlpay.water.domain.TAccdtl;
+import org.springframework.transaction.annotation.Transactional;
+
+public interface AccdtlService {
+ @Transactional(rollbackFor = Exception.class)
+ TAccdtl initAcc(InitAccParam param);
+
+ @Transactional(rollbackFor = Exception.class)
+ TAccdtl confirmAcc(ConfirmAccParam param);
+
+ @Transactional(rollbackFor = Exception.class)
+ TAccdtl creatNewAccdtl(TAccdtl accdtl, Integer cobillno);
+
+ @Transactional(rollbackFor = Exception.class)
+ TAccdtl findByBillno(String billno);
+}
diff --git a/src/main/java/com/supwisdom/dlpay/water/service/TransdtlService.java b/src/main/java/com/supwisdom/dlpay/water/service/CollectdtlService.java
similarity index 65%
rename from src/main/java/com/supwisdom/dlpay/water/service/TransdtlService.java
rename to src/main/java/com/supwisdom/dlpay/water/service/CollectdtlService.java
index acb1a9b..9a38e4c 100644
--- a/src/main/java/com/supwisdom/dlpay/water/service/TransdtlService.java
+++ b/src/main/java/com/supwisdom/dlpay/water/service/CollectdtlService.java
@@ -5,31 +5,37 @@
import com.supwisdom.dlpay.water.UploadRecordRequest;
import com.supwisdom.dlpay.water.UserAuthRequest;
import com.supwisdom.dlpay.water.bean.TransdtlCountSearchBean;
-import com.supwisdom.dlpay.water.domain.TTransdtl;
+import com.supwisdom.dlpay.water.domain.TCollectdtl;
import com.supwisdom.dlpay.water.domain.TTransdtlCount;
import com.supwisdom.dlpay.water.pojo.TTransdtlDTO;
import com.supwisdom.dlpay.water.bean.TransdtlSearchBean;
import org.springframework.transaction.annotation.Transactional;
+import java.util.List;
-public interface TransdtlService {
+
+public interface CollectdtlService {
@Transactional(rollbackFor = Exception.class)
- TTransdtl createNewTransdtl(TTransdtl dtl);
+ TCollectdtl createNewTransdtl(TCollectdtl dtl);
@Transactional(rollbackFor = Exception.class)
- TTransdtl saveDeviceDtlData(UploadRecordRequest record);
+ TCollectdtl saveDeviceDtlData(UploadRecordRequest record);
@Transactional(rollbackFor = Exception.class)
- TTransdtl queryTrans(QrcodeQueryRequest param);
+ TCollectdtl queryTrans(Integer cobillno);
@Transactional(rollbackFor = Exception.class)
- TTransdtl userAuth(UserAuthRequest param);
+ TCollectdtl userAuth(UserAuthRequest param);
@Transactional(rollbackFor = Exception.class)
PageResult<TTransdtlDTO> queryTransdtlDTOByParam(TransdtlSearchBean param);
- @Transactional(rollbackFor = Exception.class)
+ @Transactional(rollbackFor = Exception.class,readOnly = true)
PageResult<TTransdtlCount> queryTransdtlCountByParam(TransdtlCountSearchBean param);
+ @Transactional(rollbackFor = Exception.class)
+ List<TCollectdtl> queryTransdtlNotEntry();
+ @Transactional(rollbackFor = Exception.class)
+ TCollectdtl findByCobillnoForUpdate(Integer cobillno);
}
diff --git a/src/main/java/com/supwisdom/dlpay/water/service/impl/AccdtlServiceImpl.java b/src/main/java/com/supwisdom/dlpay/water/service/impl/AccdtlServiceImpl.java
new file mode 100644
index 0000000..54033bc
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/water/service/impl/AccdtlServiceImpl.java
@@ -0,0 +1,106 @@
+package com.supwisdom.dlpay.water.service.impl;
+
+import com.supwisdom.dlpay.api.bean.ConfirmAccParam;
+import com.supwisdom.dlpay.api.bean.InitAccParam;
+import com.supwisdom.dlpay.framework.service.SystemUtilService;
+import com.supwisdom.dlpay.framework.util.TradeDict;
+import com.supwisdom.dlpay.water.dao.AccdtlDao;
+import com.supwisdom.dlpay.water.dao.CollectdtlDao;
+import com.supwisdom.dlpay.water.domain.TAccdtl;
+import com.supwisdom.dlpay.water.domain.TCollectdtl;
+import com.supwisdom.dlpay.water.service.AccdtlService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+
+@Service
+public class AccdtlServiceImpl implements AccdtlService {
+
+ private static final Logger logger = LoggerFactory.getLogger(AccdtlServiceImpl.class);
+
+ @Autowired
+ private CollectdtlDao collectdtlDao;
+
+ @Autowired
+ private AccdtlDao accdtlDao;
+
+ @Autowired
+ private SystemUtilService systemUtilService;
+
+ @Override
+ public TAccdtl initAcc(InitAccParam param) {
+ TAccdtl accdtl = accdtlDao.findByBillnoForUpdate(param.getBillno());
+ if (null == accdtl) {
+ logger.error("入账流水:" + param.getBillno() + "未找到");
+ return null;
+ }
+ accdtl.setRefno(param.getRefno());
+ accdtl.setStatus(TradeDict.DTL_STATUS_INIT);
+ accdtlDao.save(accdtl);
+ return accdtl;
+ }
+
+ @Override
+ public TAccdtl confirmAcc(ConfirmAccParam param) {
+ String billno = param.getBillno();
+ TAccdtl accdtl = accdtlDao.findByBillnoForUpdate(billno);
+ if (null == accdtl) {
+ logger.error("确认入账后,未找到流水号为:" + billno + "的入账流水");
+ return null;
+ }
+ if (!param.getRefno().equals(accdtl.getRefno())) {
+ logger.error("确认入账时,支付中心确认流水号:"+param.getRefno()+"与初始化流水号:"+accdtl.getRefno()+"不相等");
+ return null;
+ }
+ if (TradeDict.DTL_STATUS_SUCCESS.equals(param.getAccstatus())) {
+ TCollectdtl collectdtl = collectdtlDao.findByEntrynoForUpdate(billno);
+ if (null == collectdtl) {
+ logger.error("确认入账后,未找到入账流水为:" + billno + "对应的采集流水");
+ return null;
+ }
+ collectdtl.setAccdate(param.getAccdate());
+ collectdtl.setStatus(TradeDict.DTL_STATUS_SUCCESS);
+ accdtl.setAccdate(param.getAccdate());
+ collectdtlDao.save(collectdtl);
+ }
+ accdtl.setStatus(param.getAccstatus());
+ accdtlDao.save(accdtl);
+ return accdtl;
+ }
+
+ @Override
+ public TAccdtl creatNewAccdtl(TAccdtl accdtl,Integer cobillno) {
+ TCollectdtl collectdtl = collectdtlDao.findByCobillnoForUpdate(cobillno);
+ if (null == collectdtl) {
+ throw new RuntimeException("采集流水号:" + cobillno + "未找到");
+ }
+ if (null == collectdtl.getEntryno()) {
+ accdtl.setBillno(systemUtilService.getRefno());
+ accdtlDao.save(accdtl);
+ collectdtl.setEntryno(accdtl.getBillno());
+ collectdtlDao.save(collectdtl);
+ return accdtl;
+ } else {
+ TAccdtl oldAccdtl = accdtlDao.findByBillno(collectdtl.getEntryno());
+ if (TradeDict.DTL_STATUS_FAIL.equals(oldAccdtl.getStatus())) {
+ accdtl.setBillno(systemUtilService.getRefno());
+ collectdtl.setEntryno(accdtl.getBillno());
+ accdtlDao.save(accdtl);
+ collectdtlDao.save(collectdtl);
+ return accdtl;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public TAccdtl findByBillno(String billno) {
+ TAccdtl accdtl = accdtlDao.findByBillno(billno);
+ if (null == accdtl) {
+ throw new RuntimeException("入账流水号:" + billno + "未找到");
+ }
+ return accdtl;
+ }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/water/service/impl/DeviceServiceImpl.java b/src/main/java/com/supwisdom/dlpay/water/service/impl/DeviceServiceImpl.java
index 5df271b..043e561 100644
--- a/src/main/java/com/supwisdom/dlpay/water/service/impl/DeviceServiceImpl.java
+++ b/src/main/java/com/supwisdom/dlpay/water/service/impl/DeviceServiceImpl.java
@@ -2,9 +2,9 @@
import com.supwisdom.dlpay.framework.dao.DictionaryDao;
import com.supwisdom.dlpay.framework.domain.TDictionary;
+import com.supwisdom.dlpay.framework.util.Dictionary;
import com.supwisdom.dlpay.framework.util.PageResult;
import com.supwisdom.dlpay.framework.util.StringUtil;
-import com.supwisdom.dlpay.framework.util.WaterBudinessConstants;
import com.supwisdom.dlpay.framework.util.WaterDeviceParam;
import com.supwisdom.dlpay.water.DeviceLineCheckParam;
import com.supwisdom.dlpay.water.DeviceLoginParam;
@@ -53,7 +53,7 @@
@PersistenceContext
private EntityManager entityManager;
- private static String paraSql = "select p.* from tb_device d left join " +
+ private final static String paraSql = "select p.* from tb_device d left join " +
"tb_areapara_bind b on d.areano = b.areano left join " +
"tb_areapara p on b.groupid = p.groupid where d.deviceno = ?";
@@ -164,7 +164,7 @@
@Override
public List<TDictionary> groupStatus() {
- return dictionaryDao.findAllByDicttype(WaterBudinessConstants.waterDeviceStatus);
+ return dictionaryDao.findAllByDicttype(Dictionary.WATER_DEVICE_STATUS);
}
@Override
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt b/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
index 6e06756..af9581b 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
@@ -160,11 +160,11 @@
class QueryDtlResultParam : APIRequestParam() {
@Sign
- var refno:String?=null //二选一
+ var refno: String? = null //二选一
@Sign
- var billno:String?=null //二选一 (billno+shopaccno) 传billno时,shopaccno必传
+ var billno: String? = null //二选一 (cobillno+shopaccno) 传billno时,shopaccno必传
@Sign
- var shopaccno: String?=null
+ var shopaccno: String? = null
override fun checkParam(): Boolean {
if (StringUtil.isEmpty(refno) && (StringUtil.isEmpty(billno) || StringUtil.isEmpty(shopaccno))) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "流水唯一号不能为空")
@@ -188,6 +188,8 @@
var transdate: String = "" //必传
@Sign
var transtime: String = "" //必传
+ @Sign
+ var dtltype: String = ""
override fun checkParam(): Boolean {
if (StringUtil.isEmpty(cardNo)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "卡唯一号不能为空")
@@ -203,7 +205,7 @@
class CitizenCardPayfinishParam : APIRequestParam() {
@Sign
- var refno:String=""
+ var refno: String = ""
override fun checkParam(): Boolean {
if (StringUtil.isEmpty(refno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "交易参考号不能为空")
@@ -242,12 +244,44 @@
if (!DateUtil.checkDatetimeValid(transdate, DateUtil.DATE_FMT)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "交易日期错误[yyyyMMdd]")
if (!DateUtil.checkDatetimeValid(transtime, DateUtil.TIME_FMT)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "交易时间错误[HHmmss]")
if (StringUtil.isEmpty(stuempno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "一卡通唯一号不能为空")
- if(!StringUtil.isEmpty(yktshopid) && !NumberUtil.isDigits(yktshopid)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "一卡通商户号非整数")
+ if (!StringUtil.isEmpty(yktshopid) && !NumberUtil.isDigits(yktshopid)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "一卡通商户号非整数")
return true
}
}
+class ConfirmAccParam : APIRequestParam() {
+ @Sign
+ var accdate: String = ""
+ @Sign
+ var accstatus: String = ""
+ @Sign
+ var refno: String = ""
+ @Sign
+ var billno: String = ""
+
+ override fun checkParam(): Boolean {
+ if (StringUtil.isEmpty(accdate)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "入账日期不能为空")
+ if (StringUtil.isEmpty(accstatus)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "入账确认状态不能为空")
+ if (StringUtil.isEmpty(refno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "入账确认流水号不能为空")
+ if (StringUtil.isEmpty(billno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "本地流水号不能为空")
+ return true
+ }
+}
+
+class InitAccParam : APIRequestParam() {
+ @Sign
+ var refno: String = ""
+ @Sign
+ var billno: String = ""
+
+ override fun checkParam(): Boolean {
+ if (StringUtil.isEmpty(refno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "入账确认流水号不能为空")
+ if (StringUtil.isEmpty(billno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "本地流水号不能为空")
+ return true
+ }
+}
+
diff --git a/src/main/kotlin/com/supwisdom/dlpay/water/api_request_param.kt b/src/main/kotlin/com/supwisdom/dlpay/water/api_request_param.kt
index e408e60..ef6476c 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/water/api_request_param.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/water/api_request_param.kt
@@ -79,19 +79,19 @@
if (deviceno.length != 8 || deviceno.any { it !in '0'..'9' }) {
throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "设备ID号长度不符")
}
-
+ if (citizenCardno.length != 8 || citizenCardno.any { it !in '0'..'9' }) {
+ throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "市民卡号长度不符")
+ }
if (!DateUtil.checkDatetimeValid(termdate, DateUtil.DATE_FMT)
|| !DateUtil.checkDatetimeValid(termtime, DateUtil.TIME_FMT)) {
throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "设备日期时间错误")
}
if (citizenCardno.isEmpty()) {
- throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR,
- "市民卡号长度错误")
+ throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "市民卡号长度错误")
}
if (cardphyid.isEmpty()) {
- throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR,
- "物理卡号长度错误")
+ throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "物理卡号长度错误")
}
return true
}
@@ -126,7 +126,7 @@
var deviceno: String = ""
@Sign
- var billno: String = ""
+ var cobillno: Int = 0
override fun checkParam(): Boolean {
@@ -148,7 +148,7 @@
var transtime: String = ""
@Sign
- var billno: String = ""
+ var cobillno: Int = 0
@Sign
var amount: Int = 0
@@ -175,14 +175,64 @@
class UserAuthRequest : APIRequestParam() {
@Sign
- var billno: String = ""
+ var cobillno: Int = 0
@Sign
var userid: String = ""
override fun checkParam(): Boolean {
- if (billno.length != 20 || billno.any { it !in '0'..'9' }) {
- throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "流水号长度不符")
+ return true
+ }
+}
+
+class AccdtlParam : APIRequestParam() {
+
+ @Sign
+ var deviceno: String = ""
+
+ @Sign
+ var cobillno: Int = 0
+
+ @Sign
+ var transdate: String = ""
+
+ @Sign
+ var transtime: String = ""
+
+ @Sign
+ var amount: Double = 0.0
+
+ @Sign
+ var flowsensors: Int = 0
+
+ @Sign
+ var userid: String = ""
+
+ @Sign
+ var citizenCardno: String = ""
+
+ @Sign
+ var mode: String = ""
+
+ @Sign
+ var cardPhyId: String = ""
+
+ override fun checkParam(): Boolean {
+ if (deviceno.length != 8 || deviceno.any { it !in '0'..'9' }) {
+ throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "设备ID号长度不符")
+ }
+ if (!DateUtil.checkDatetimeValid(transdate, DateUtil.DATE_FMT)
+ || !DateUtil.checkDatetimeValid(transtime, DateUtil.TIME_FMT)) {
+ throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "交易日期时间错误")
+ }
+ if (citizenCardno.isEmpty()) {
+ throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "市民卡号长度错误")
+ }
+ if (cardPhyId.isEmpty()) {
+ throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "物理卡号长度错误")
+ }
+ if (cobillno==0) {
+ throw RequestParamCheckException(TradeErrorCode.INPUT_DATA_ERROR, "采集流水号不能为空")
}
return true
}
diff --git a/src/main/kotlin/com/supwisdom/dlpay/water/async_tasks.kt b/src/main/kotlin/com/supwisdom/dlpay/water/async_tasks.kt
new file mode 100644
index 0000000..2f27350
--- /dev/null
+++ b/src/main/kotlin/com/supwisdom/dlpay/water/async_tasks.kt
@@ -0,0 +1,35 @@
+package com.supwisdom.dlpay.water
+
+import mu.KotlinLogging
+import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.scheduling.annotation.AsyncConfigurer
+import org.springframework.scheduling.annotation.EnableAsync
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
+import java.lang.reflect.Method
+import java.util.concurrent.Executor
+
+@Configuration
+@EnableAsync
+class SpringAsyncConfig : AsyncConfigurer {
+ @Bean(value = ["waterPay"])
+ fun threadPoolExecutor(): Executor {
+ return ThreadPoolTaskExecutor().apply {
+ corePoolSize = 5
+ maxPoolSize = 10
+ setWaitForTasksToCompleteOnShutdown(true)
+ }
+ }
+
+ override fun getAsyncUncaughtExceptionHandler(): AsyncUncaughtExceptionHandler? {
+ return MyAsyncUncaughtExceptionHandler()
+ }
+}
+
+class MyAsyncUncaughtExceptionHandler : AsyncUncaughtExceptionHandler {
+ private val logger = KotlinLogging.logger { }
+ override fun handleUncaughtException(ex: Throwable, method: Method, vararg params: Any?) {
+ logger.error { "Async Task execute error: <${method.name}>, exception <${ex.message}>" }
+ }
+}
diff --git a/src/main/kotlin/com/supwisdom/dlpay/water/controller/api_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/water/controller/api_controller.kt
index 55772db..67345a9 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/water/controller/api_controller.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/water/controller/api_controller.kt
@@ -1,15 +1,18 @@
package com.supwisdom.dlpay.water.controller
+import com.supwisdom.dlpay.api.bean.CitizenCardPayinitParam
import com.supwisdom.dlpay.framework.ResponseBodyBuilder
-import com.supwisdom.dlpay.framework.dao.BusinessparaDao
import com.supwisdom.dlpay.framework.service.BusinessparaService
import com.supwisdom.dlpay.framework.service.SystemUtilService
import com.supwisdom.dlpay.framework.util.*
import com.supwisdom.dlpay.system.service.UserDataService
import com.supwisdom.dlpay.water.*
-import com.supwisdom.dlpay.water.domain.TTransdtl
+import com.supwisdom.dlpay.water.domain.TAccdtl
+import com.supwisdom.dlpay.water.domain.TCollectdtl
+import com.supwisdom.dlpay.water.pay.WaterPayAsyncTask
+import com.supwisdom.dlpay.water.service.AccdtlService
import com.supwisdom.dlpay.water.service.DeviceService
-import com.supwisdom.dlpay.water.service.TransdtlService
+import com.supwisdom.dlpay.water.service.CollectdtlService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
@@ -30,7 +33,7 @@
private lateinit var userDataService: UserDataService
@Autowired
- private lateinit var transdtlService: TransdtlService
+ private lateinit var collectdtlService: CollectdtlService
@Autowired
private lateinit var shortURLUtil: ShortURLUtil
@@ -38,6 +41,12 @@
@Autowired
private lateinit var businessparaService: BusinessparaService
+ @Autowired
+ private lateinit var waterPayAsyncTask: WaterPayAsyncTask
+
+ @Autowired
+ private lateinit var accdtlService: AccdtlService
+
@PostMapping("/devicelogin")
fun deviceLogin(param: DeviceLoginParam): ResponseEntity<Any> {
try {
@@ -89,14 +98,13 @@
//2. 通过 deviceno 查询设备费率参数
val deviceParam = deviceService.getParaMapByDeviceno(param.deviceno)
//3. 创建 transdtl 记录初始流水
- val trans = TTransdtl().apply {
- billno = systemUtilService.refno
+ val trans = TCollectdtl().apply {
mode = TradeDict.PAY_MODE_CARD
transDate = param.termdate
transTime = param.termtime
deviceno = param.deviceno
userid = personIdentity.person.userid
- bankCardNo = param.citizenCardno
+ citizenCardno = param.citizenCardno
cardPhyId = param.cardphyid
amount = 0.0
waterSumHundredLitre = 0
@@ -104,10 +112,10 @@
authStatus = true
uploadStatus = false
}
- val savedTrans = transdtlService.createNewTransdtl(trans)
- //4. 将流水 billno 和费率信息返回给终端
+ val savedTrans = collectdtlService.createNewTransdtl(trans)
+ //4. 将流水 cobillno 和费率信息返回给终端
return ResponseEntity.ok(ResponseBodyBuilder.create()
- .data(WaterDeviceParam.billNo, savedTrans.billno)
+ .data(WaterDeviceParam.cobillNo, savedTrans.cobillno)
.data(WaterDeviceParam.feeAmount, deviceParam[WaterDeviceParam.feeAmount]!!)
.data(WaterDeviceParam.waterLimit, deviceParam[WaterDeviceParam.waterLimit]!!)
.data(WaterDeviceParam.feestart, deviceParam[WaterDeviceParam.feestart]!!)
@@ -124,8 +132,7 @@
try {
val deviceParam = deviceService.getParaMapByDeviceno(param.deviceno)
//1. 创建并记录初始流水
- val trans = TTransdtl().apply {
- billno = systemUtilService.refno
+ val trans = TCollectdtl().apply {
mode = TradeDict.PAY_MODE_QRCODE
transDate = param.termdate
transTime = param.termtime
@@ -136,13 +143,13 @@
authStatus = false
uploadStatus = false
}
- val savedTrans = transdtlService.createNewTransdtl(trans)
+ val savedTrans = collectdtlService.createNewTransdtl(trans)
//2.将流水号及认证地址返回给终端
//将认证url转为短码
val url = shortURLUtil.doGetSinaShortUrl(
- businessparaService.findByParakey(WaterBudinessConstants.waterAuthUrl).paraval + savedTrans.billno)
+ businessparaService.findByParakey(WaterBudinessConstants.waterAuthUrl).paraval + savedTrans.cobillno)
return ResponseEntity.ok(ResponseBodyBuilder.create()
- .data(WaterDeviceParam.billNo, savedTrans.billno)
+ .data(WaterDeviceParam.cobillNo, savedTrans.cobillno)
.data(WaterDeviceParam.url, url)
.data(WaterDeviceParam.validTime, deviceParam[WaterDeviceParam.validTime]!!)
.success())
@@ -156,13 +163,13 @@
fun qrcodeQuery(param: QrcodeQueryRequest): ResponseEntity<Any> {
try {
val deviceParam = deviceService.getParaMapByDeviceno(param.deviceno)
- val trans = transdtlService.queryTrans(param)
+ val trans = collectdtlService.queryTrans(param.cobillno)
var authStatus = 0
if (trans.authStatus) {
authStatus = 1
}
return ResponseEntity.ok(ResponseBodyBuilder.create()
- .data(WaterDeviceParam.billNo, trans.billno)
+ .data(WaterDeviceParam.cobillNo, trans.cobillno)
.data(WaterDeviceParam.authStatus, authStatus)
//2为代扣模式
.data(WaterDeviceParam.payStatus, 2)
@@ -187,7 +194,7 @@
@ResponseBody
fun auth(@RequestBody param: UserAuthRequest): ResponseEntity<Any> {
return try {
- transdtlService.userAuth(param)
+ collectdtlService.userAuth(param)
ResponseEntity.ok(ResponseBodyBuilder.create().success())
} catch (ex: Exception) {
ResponseEntity.ok(ResponseBodyBuilder.create()
@@ -197,9 +204,26 @@
@PostMapping("/uploadrecord")
fun transdtlUpload(param: UploadRecordRequest): ResponseEntity<Any> {
- // 1. 根据 billno 查询 transdtl , 并加锁
- val dtl = transdtlService.saveDeviceDtlData(param)
- return ResponseEntity.ok(ResponseBodyBuilder.create().data(WaterDeviceParam.billNo, dtl.billno)
- .success())
+ // 1. 根据 cobillno 查询 transdtl , 并加锁
+ val querycodtl = collectdtlService.queryTrans(param.cobillno)
+ ?: return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(WaterErrorCode.DATA_NOTFOUND_ERROR, "采集流水号未找到"))
+ // 流水是否重复上传
+ if (!querycodtl.uploadStatus) {
+ val dtl = collectdtlService.saveDeviceDtlData(param)
+ userDataService.updateCoamount(dtl.citizenCardno, param.amount/100.0)
+ // 是否立即扣费
+ if (param.amount >= deviceService.getParaMapByDeviceno(param.deviceno)[WaterDeviceParam.imdDecThreshold]!!.toInt()) {
+ // 刷卡消费
+ if (TradeDict.PAY_MODE_CARD == dtl.mode) {
+ // 立即异步扣费
+ waterPayAsyncTask.waterPay(querycodtl.cobillno)
+ }
+ }
+ return ResponseEntity.ok(ResponseBodyBuilder.create().data(WaterDeviceParam.cobillNo, dtl.cobillno)
+ .success())
+ }
+ return ResponseEntity.ok(ResponseBodyBuilder.create().data(WaterDeviceParam.cobillNo, querycodtl.cobillno)
+ .success())
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/water/controller/water_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/water/controller/water_controller.kt
index c7abfc8..4cf3e21 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/water/controller/water_controller.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/water/controller/water_controller.kt
@@ -10,7 +10,7 @@
import com.supwisdom.dlpay.water.pojo.TTransdtlDTO
import com.supwisdom.dlpay.water.service.DeviceService
import com.supwisdom.dlpay.water.service.AreaService
-import com.supwisdom.dlpay.water.service.TransdtlService
+import com.supwisdom.dlpay.water.service.CollectdtlService
import com.supwisdom.dlpay.water.domain.TAreaparaGroup
import com.supwisdom.dlpay.water.domain.TTransdtlCount
import com.supwisdom.dlpay.water.pojo.TAreaparaBindDTO
@@ -362,7 +362,7 @@
@Controller
class TransdtlController {
@Autowired
- private lateinit var transdtlService: TransdtlService
+ private lateinit var collectdtlService: CollectdtlService
@GetMapping("/transdtl/index")
fun dtlIndexView() = "system/transdtl/index"
@@ -395,7 +395,7 @@
this.username = username
this.transtime = transtime
}
- transdtlService.queryTransdtlDTOByParam(searchBean)?.let {
+ collectdtlService.queryTransdtlDTOByParam(searchBean)?.let {
return it
}
return PageResult(WaterErrorCode.DATA_NOTFOUND_ERROR, "设备未找到")
@@ -431,7 +431,7 @@
this.areano = areano
this.transtime = transtime
}
- transdtlService.queryTransdtlCountByParam(searchBean)?.let {
+ collectdtlService.queryTransdtlCountByParam(searchBean)?.let {
return it
}
return PageResult(WaterErrorCode.DATA_NOTFOUND_ERROR, "流水统计未找到")
diff --git a/src/main/kotlin/com/supwisdom/dlpay/water/scheduler_task.kt b/src/main/kotlin/com/supwisdom/dlpay/water/scheduler_task.kt
new file mode 100644
index 0000000..60c2dd8
--- /dev/null
+++ b/src/main/kotlin/com/supwisdom/dlpay/water/scheduler_task.kt
@@ -0,0 +1,35 @@
+package com.supwisdom.dlpay.water
+
+import com.supwisdom.dlpay.water.pay.WaterPayAsyncTask
+import com.supwisdom.dlpay.water.service.CollectdtlService
+import mu.KotlinLogging
+import net.javacrumbs.shedlock.core.SchedulerLock
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.scheduling.annotation.EnableScheduling
+import org.springframework.scheduling.annotation.Scheduled
+import org.springframework.stereotype.Component
+
+@Component
+@EnableScheduling
+class CollectdtlQueryResultSchedulerTask {
+
+ private val logger = KotlinLogging.logger { }
+
+ @Autowired
+ private lateinit var collectdtlService: CollectdtlService
+
+ @Autowired
+ private lateinit var waterPayAsyncTask: WaterPayAsyncTask
+
+ @Scheduled(cron = "*/30 * * * * ?")
+ @SchedulerLock(name = "dealCollectdtlAccountEntry", lockAtMostForString = "PT10M")
+ fun queryCollectdtlResult() {
+ val collectdtlList = collectdtlService.queryTransdtlNotEntry()
+ if (null == collectdtlList || 0 == collectdtlList.size) {
+ return
+ }
+ for (collectdtl in collectdtlList) {
+ waterPayAsyncTask.waterPay(collectdtl.cobillno)
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/water/service/transdtl_service.kt b/src/main/kotlin/com/supwisdom/dlpay/water/service/collectdtl_service.kt
similarity index 80%
rename from src/main/kotlin/com/supwisdom/dlpay/water/service/transdtl_service.kt
rename to src/main/kotlin/com/supwisdom/dlpay/water/service/collectdtl_service.kt
index 482aaf0..7799cc5 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/water/service/transdtl_service.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/water/service/collectdtl_service.kt
@@ -5,34 +5,33 @@
import com.supwisdom.dlpay.framework.util.StringUtil
import com.supwisdom.dlpay.framework.util.TradeDict
import com.supwisdom.dlpay.framework.util.WaterErrorCode
-import com.supwisdom.dlpay.water.QrcodeQueryRequest
import com.supwisdom.dlpay.water.UploadRecordRequest
import com.supwisdom.dlpay.water.UserAuthRequest
import com.supwisdom.dlpay.water.bean.TransdtlCountSearchBean
-import com.supwisdom.dlpay.water.dao.TransdtlDao
-import com.supwisdom.dlpay.water.domain.TTransdtl
+import com.supwisdom.dlpay.water.dao.CollectdtlDao
+import com.supwisdom.dlpay.water.domain.TCollectdtl
import com.supwisdom.dlpay.water.pojo.TTransdtlDTO
import com.supwisdom.dlpay.water.bean.TransdtlSearchBean
+import com.supwisdom.dlpay.water.dao.AccdtlDao
import com.supwisdom.dlpay.water.dao.TransdtlCountDao
import com.supwisdom.dlpay.water.domain.TTransdtlCount
+import mu.KotlinLogging
import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.data.domain.Example
-import org.springframework.data.domain.ExampleMatcher
import org.springframework.data.domain.PageRequest
import org.springframework.data.jpa.domain.Specification
import org.springframework.stereotype.Service
+import java.lang.RuntimeException
import java.util.ArrayList
import javax.persistence.EntityManager
-import javax.persistence.Query
-import javax.persistence.criteria.CriteriaBuilder
-import javax.persistence.criteria.CriteriaQuery
import javax.persistence.criteria.Predicate
-import javax.persistence.criteria.Root
@Service
-class TransdtlServiceImpl : TransdtlService {
+class CollectdtlServiceImpl : CollectdtlService {
+
+ private val logger = KotlinLogging.logger { }
+
@Autowired
- private lateinit var transdtlDao: TransdtlDao
+ private lateinit var collectdtlDao: CollectdtlDao
@Autowired
private lateinit var em: EntityManager
@@ -40,13 +39,14 @@
@Autowired
private lateinit var transdtlCountDao: TransdtlCountDao
- override fun createNewTransdtl(dtl: TTransdtl): TTransdtl {
- transdtlDao.save(dtl)
+
+ override fun createNewTransdtl(dtl: TCollectdtl): TCollectdtl {
+ collectdtlDao.save(dtl)
return dtl
}
- override fun saveDeviceDtlData(record: UploadRecordRequest): TTransdtl {
- val dtl = transdtlDao.findByBillnoForUpdate(record.billno)
+ override fun saveDeviceDtlData(record: UploadRecordRequest): TCollectdtl {
+ val dtl = collectdtlDao.findByCobillnoForUpdate(record.cobillno)
?: throw TransactionProcessException(WaterErrorCode.DATA_NOTFOUND_ERROR,
"交易订单号不存在")
if (record.transtatus == "2") {
@@ -58,32 +58,30 @@
dtl.waterSumHundredLitre = record.flowsensors
dtl.uploadTime = record.transdate + record.transtime
dtl.uploadStatus = true
- transdtlDao.save(dtl)
+ collectdtlDao.save(dtl)
return dtl
}
- override fun queryTrans(param: QrcodeQueryRequest): TTransdtl {
- return transdtlDao.findByBillnoAndDeviceno(param.billno, param.deviceno)
- ?: throw TransactionProcessException(WaterErrorCode.DATA_NOTFOUND_ERROR,
- "交易订单号不存在")
+ override fun queryTrans(cobillno: Int?): TCollectdtl {
+ return collectdtlDao.findByCobillnoForUpdate(cobillno)
}
- override fun userAuth(param: UserAuthRequest): TTransdtl {
- val dtl = transdtlDao.findById(param.billno).orElse(null)
+ override fun userAuth(param: UserAuthRequest): TCollectdtl {
+ val dtl = collectdtlDao.findByCobillnoForUpdate(param.cobillno)
?: throw TransactionProcessException(WaterErrorCode.DATA_NOTFOUND_ERROR,
"交易订单号不存在")
dtl.userid = param.userid
dtl.authStatus = true
- transdtlDao.save(dtl)
+ collectdtlDao.save(dtl)
return dtl
}
override fun queryTransdtlDTOByParam(param: TransdtlSearchBean): PageResult<TTransdtlDTO>? {
- val sql = StringBuffer("select t1.billno,t1.amount,t1.bankcardno,t1.cardphyid,t1.deviceno,t1.mode,t1.status,t1.transdate,t1.transtime,t1.water_in_100ml water_sum_hundred_litre,t1.name username,t2.devicename,t2.areaname,t2.areano " +
+ val sql = StringBuffer("select t1.cobillno,t1.amount,t1.bankcardno,t1.cardphyid,t1.deviceno,t1.mode,t1.status,t1.transdate,t1.transtime,t1.water_in_100ml water_sum_hundred_litre,t1.name username,t2.devicename,t2.areaname,t2.areano " +
"from (select dtl.*,person.name from tb_transdtl dtl left join tb_person person on dtl.userid = person.userid) t1," +
"(select device.deviceno,device.devicename,area.areaname,area.areano from tb_device device,tb_area area where device.areano = area.areano) t2 " +
"where t1.deviceno = t2.deviceno")
- val countSql = StringBuffer("select count(billno) " +
+ val countSql = StringBuffer("select count(cobillno) " +
"from (select dtl.*,person.name from tb_transdtl dtl left join tb_person person on dtl.userid = person.userid) t1," +
"(select device.deviceno,device.devicename,area.areaname,area.areano from tb_device device,tb_area area where device.areano = area.areano) t2 " +
"where t1.deviceno = t2.deviceno")
@@ -118,7 +116,7 @@
countSql.append(" and areano =?")
map.put("areano", position++)
}
- sql.append(" order by billno desc limit " + param.pageSize + " offset " + (param.pageNo - 1) * param.pageSize)
+ sql.append(" order by cobillno desc limit " + param.pageSize + " offset " + (param.pageNo - 1) * param.pageSize)
val query = em.createNativeQuery(sql.toString(), TTransdtlDTO::class.java)
val countQuery = em.createNativeQuery(countSql.toString())
map["devicename"]?.let {
@@ -177,4 +175,12 @@
val dtlCountPage = transdtlCountDao.findAll(specification, pageable)
return PageResult<TTransdtlCount>(dtlCountPage)
}
+
+ override fun queryTransdtlNotEntry(): List<TCollectdtl>? {
+ return collectdtlDao.findWipCollectdtl(PageRequest.of(0,10))
+ }
+
+ override fun findByCobillnoForUpdate(cobillno: Int?): TCollectdtl {
+ return collectdtlDao.findByCobillnoForUpdate(cobillno) ?: throw RuntimeException("采集流水号:" + cobillno + "未找到")
+ }
}
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 992c6c6..28dbe72 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -25,4 +25,7 @@
################################################
# user password
auth.password.bcrypt.length=10
-payapi.url=http://localhost:9000/payapi
+payapi.url=https://yy.dlsmk.cn/payapi
+#appid secret
+water.appid=700001
+water.secret=5f788ce433ec44f299351cdf7f137e81
\ No newline at end of file
diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql
index 79bc39c..ea6e5d8 100644
--- a/src/main/resources/data.sql
+++ b/src/main/resources/data.sql
@@ -1,5 +1,5 @@
-insert into tb_apiclient(appid, secret, status, roles)
-values ('100001', 'oUw2NmA09ficiVWD4TUQLDOkPyzQa3VzbjjsW0B2qTk=', 'normal', 'ROLE_THIRD_ADMIN');
+insert into tb_apiclient(appid, secret,bcrypt_secret, status, roles,thirdurl)
+values ('100001', 'oUw2NmA09ficiVWD4TUQLDOkPyzQa3VzbjjsW0B2qTk=',1, 'normal', 'ROLE_THIRD_ADMIN',1);
INSERT INTO tb_operator(
operid, closedate, opendate, opercode, opername, operpwd, opertype, status,thirdadmin)
VALUES ('LOR2IwRkbOjp+sVG9KR2BpHZbwGKepS4', '20500101', '20190101', 'system', '系统管理员', '$2a$10$Ex9xp11.vCaD8D0a7ahiUOKqDij1TcCUBwRAmrqXeDvAkmzLibn4.', 'oper', 'normal','1');
@@ -109,12 +109,20 @@
INSERT INTO "tb_devicefeeconfig"("areano", "feecfgversion", "feeconfig") VALUES (1, NULL, 1);
INSERT INTO "tb_feeconfig"("id", "amount", "max_water_litre", "cfg_version") VALUES (1, 1, 50, NULL);
-INSERT INTO "tb_person_identity"("third_uid", "createtime", "lockflag", "lossflag", "status", "userid", "cardphyid") VALUES ('000000000000000000000000', NULL, 0, 0, '1', 'd1yctWs5+ks0iQN3m9bUvRHus6HbKbrs', '6655ec27');
+INSERT INTO "tb_person_identity"("third_uid", "createtime", "lockflag", "lossflag", "status", "userid", "cardphyid","coamount","accamount") VALUES ('25002882', NULL, 0, 0, '1', 'd1yctWs5+ks0iQN3m9bUvRHus6HbKbrs', '6655ec27',0,0);
+INSERT INTO "tb_person_identity"("third_uid", "accamount", "cardphyid", "coamount", "createtime", "lockflag", "lossflag", "status", "userid") VALUES ('25002885', 0, '6655ec27', 0, NULL, 0, 0, '1', 'f3yctKs5+bs1iMU4m8JUvPOus7SbDbrd');
INSERT INTO "tb_person"("userid", "addr", "country", "email", "idno", "idtype", "lastsaved", "mobile", "name", "nation", "sex", "status", "tel", "zipcode") VALUES ('d1yctWs5+ks0iQN3m9bUvRHus6HbKbrs', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '王富贵', NULL, NULL, '1', NULL, NULL);
-INSERT INTO "tb_businesspara"("parakey", "paraval") VALUES ('water_auth_url', 'http://172.28.43.20:8080/water/api/device/confirm?billno=');
-INSERT INTO "tb_businesspara"("parakey", "paraval") VALUES ('water_sina_shorturl', 'http://api.t.sina.com.cn/short_url/shorten.json?source=2223392143');
+INSERT INTO "tb_person"("userid", "addr", "country", "email", "idno", "idtype", "lastsaved", "mobile", "name", "nation", "sex", "status", "tel", "zipcode") VALUES ('f3yctKs5+bs1iMU4m8JUvPOus7SbDbrd', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '蔡程应', NULL, NULL, '1', NULL, NULL);
+INSERT INTO "tb_businesspara"("parakey", "paraval") VALUES ('water_auth_url', 'http://172.28.43.20:8080/water/api/device/confirm?cobillno=');
+INSERT INTO "tb_businesspara"("parakey", "paraval") VALUES ('water_sina_shorturl', 'http://api.t.sina.com.cn/short_url/shorten.json?source=2223392143');
+INSERT INTO "tb_businesspara"("parakey", "paraval") VALUES ('water_shopaccno', '2000000010');
+
+INSERT INTO "tb_area"("areano", "address", "areaname", "available", "arealevel", "parentid", "remarks") VALUES (1, '测试路1号', '测试区域', 1, 1, 0, '测试');
+INSERT INTO "tb_device"("deviceid", "areano", "linecheck", "devistatus", "devicename", "deviceno", "soft_verno") VALUES (1, 1, '20190813143440', 'normal', '测试POS01', '10000001', NULL);
+INSERT INTO "tb_areapara_bind"("areano", "groupid", "lastsaved") VALUES (1, 1, '20190813143615');
+
INSERT INTO "tb_dictionary"("dictval", "dicttype", "dictcaption", "dicttypename") VALUES ('正常', 'device_status', 'normal', '设备状态');
INSERT INTO "tb_dictionary"("dictval", "dicttype", "dictcaption", "dicttypename") VALUES ('注销', 'device_status', 'closed', '设备状态');
INSERT INTO "tb_dictionary"("dictval", "dicttype", "dictcaption", "dicttypename") VALUES ('签出', 'device_status', 'logout', '设备状态');
@@ -132,6 +140,8 @@
INSERT INTO "tb_areapara"("paraname", "groupid", "maxval", "minval", "paradesc", "paraval", "valtype") VALUES ('pulseInHML', 1, '100', '1', '每百毫升流量计的脉冲数(单位:个)', '40', 'N');
INSERT INTO "tb_areapara"("paraname", "groupid", "maxval", "minval", "paradesc", "paraval", "valtype") VALUES ('waterlimit', 1, '500', '1', '单次用水上限(单位:百毫升)', '300', 'N');
INSERT INTO "tb_areapara"("paraname", "groupid", "maxval", "minval", "paradesc", "paraval", "valtype") VALUES ('validtime', 1, '240', '60', '二维码有效时间(单位:秒)', '180', 'N');
+INSERT INTO "tb_areapara"("paraname", "groupid", "maxval", "minval", "paradesc", "paraval", "valtype") VALUES ('imdDecThreshold', 1, '500', '1', '流水上传立即扣费阈值(单位:分)', '50', 'N');
+
commit;
\ No newline at end of file
diff --git a/src/main/resources/templates/system/confirm/confirm.html b/src/main/resources/templates/system/confirm/confirm.html
index 6562948..5e66269 100644
--- a/src/main/resources/templates/system/confirm/confirm.html
+++ b/src/main/resources/templates/system/confirm/confirm.html
@@ -26,7 +26,7 @@
return "d1yctWs5+ks0iQN3m9bUvRHus6HbKbrs"
}
var allData = {
- billno:GetUrlRefnoPara(),
+ cobillno:GetUrlRefnoPara(),
userid:GetUserid()
}
$("#button-auth").click(function () {
diff --git a/src/main/resources/templates/system/transdtl/index.html b/src/main/resources/templates/system/transdtl/index.html
index fefeb56..475a84d 100644
--- a/src/main/resources/templates/system/transdtl/index.html
+++ b/src/main/resources/templates/system/transdtl/index.html
@@ -111,7 +111,7 @@
page: true,
cols: [
[
- {field: 'billno', align: 'center', title: '流水号'},
+ {field: 'cobillno', align: 'center', title: '流水号'},
{field: 'deviceno', align: 'center', title: '设备号'},
{field: 'devicename', align: 'center', title: '设备名称'},
{field: 'areaname', align: 'center', title: '区域'},