提交 d3b8a353 authored 作者: jacksmith1988's avatar jacksmith1988

//init

上级 ed53a40a
...@@ -160,4 +160,8 @@ public class Constant { ...@@ -160,4 +160,8 @@ public class Constant {
public static final String 下级账号查询范围_指定账号及直接下级 = "20"; public static final String 下级账号查询范围_指定账号及直接下级 = "20";
public static final String 支付渠道_银行卡 = "bankcard";
public static final String 支付渠道_微信码 = "wechat";
public static final String 支付渠道_支付宝码 = "alipay";
} }
...@@ -29,52 +29,64 @@ import me.zohar.runscore.useraccount.domain.UserAccount; ...@@ -29,52 +29,64 @@ import me.zohar.runscore.useraccount.domain.UserAccount;
@DynamicUpdate(true) @DynamicUpdate(true)
public class GatheringCode { public class GatheringCode {
/** /**
* 主键id * 主键id
*/ */
@Id @Id
@Column(name = "id", length = 32) @Column(name = "id", length = 32)
private String id; private String id;
/** /**
* 收款渠道 * 收款渠道
*/ */
private String gatheringChannelCode; private String gatheringChannelCode;
/** /**
* 状态,启用:1;禁用:0 * 状态,启用:1;禁用:0
*/ */
private String state; private String state;
private Boolean fixedGatheringAmount; private Boolean fixedGatheringAmount;
/** /**
* 收款金额 * 收款金额
*/ */
private Double gatheringAmount; private Double gatheringAmount;
/** /**
* 收款人 * 收款人
*/ */
private String payee; private String payee;
/** /**
* 创建时间 * 开户行
*/ */
private Date createTime; private String bankAddress;
/**
@Column(name = "storage_id", length = 32) * 卡号
private String storageId; */
private String bankCode;
/** /**
* 用户账号id * 卡户主
*/ */
@Column(name = "user_account_id", length = 32) private String bankUsername;
private String userAccountId; /**
* 创建时间
@NotFound(action = NotFoundAction.IGNORE) */
@ManyToOne(fetch = FetchType.LAZY) private Date createTime;
@JoinColumn(name = "user_account_id", updatable = false, insertable = false, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
private UserAccount userAccount; @Column(name = "storage_id", length = 32)
private String storageId;
/**
* 用户账号id
*/
@Column(name = "user_account_id", length = 32)
private String userAccountId;
@NotFound(action = NotFoundAction.IGNORE)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_account_id", updatable = false, insertable = false, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
private UserAccount userAccount;
} }
...@@ -54,6 +54,19 @@ public class GatheringCodeParam { ...@@ -54,6 +54,19 @@ public class GatheringCodeParam {
private String storageId; private String storageId;
/**
* 开户行
*/
private String bankAddress;
/**
* 卡号
*/
private String bankCode;
/**
* 卡户主
*/
private String bankUsername;
public GatheringCode convertToPo(String userAccountId) { public GatheringCode convertToPo(String userAccountId) {
GatheringCode po = new GatheringCode(); GatheringCode po = new GatheringCode();
BeanUtils.copyProperties(this, po); BeanUtils.copyProperties(this, po);
......
...@@ -38,150 +38,156 @@ import me.zohar.runscore.useraccount.repo.UserAccountRepo; ...@@ -38,150 +38,156 @@ import me.zohar.runscore.useraccount.repo.UserAccountRepo;
@Service @Service
public class GatheringCodeService { public class GatheringCodeService {
@Autowired @Autowired
private GatheringCodeRepo gatheringCodeRepo; private GatheringCodeRepo gatheringCodeRepo;
@Autowired @Autowired
private StorageRepo storageRepo; private StorageRepo storageRepo;
@Autowired @Autowired
private UserAccountRepo userAccountRepo; private UserAccountRepo userAccountRepo;
@Transactional @Transactional
public void delMyGatheringCodeById(String id, String userAccountId) { public void delMyGatheringCodeById(String id, String userAccountId) {
GatheringCode gatheringCode = gatheringCodeRepo.getOne(id); GatheringCode gatheringCode = gatheringCodeRepo.getOne(id);
if (!userAccountId.equals(gatheringCode.getUserAccountId())) { if (!userAccountId.equals(gatheringCode.getUserAccountId())) {
throw new BizException(BizError.无权删除数据); throw new BizException(BizError.无权删除数据);
} }
delGatheringCodeById(id); delGatheringCodeById(id);
} }
@Transactional @Transactional
public void delGatheringCodeById(String id) { public void delGatheringCodeById(String id) {
GatheringCode gatheringCode = gatheringCodeRepo.getOne(id); GatheringCode gatheringCode = gatheringCodeRepo.getOne(id);
disassociationGatheringCodeStorage(gatheringCode.getStorageId()); disassociationGatheringCodeStorage(gatheringCode.getStorageId());
gatheringCodeRepo.delete(gatheringCode); gatheringCodeRepo.delete(gatheringCode);
} }
@Transactional(readOnly = true) @Transactional(readOnly = true)
public GatheringCodeVO findMyGatheringCodeById(String id, String userAccountId) { public GatheringCodeVO findMyGatheringCodeById(String id, String userAccountId) {
GatheringCodeVO vo = findGatheringCodeById(id); GatheringCodeVO vo = findGatheringCodeById(id);
if (!userAccountId.equals(vo.getUserAccountId())) { if (!userAccountId.equals(vo.getUserAccountId())) {
throw new BizException(BizError.无权查看数据); throw new BizException(BizError.无权查看数据);
} }
return vo; return vo;
} }
@Transactional(readOnly = true) @Transactional(readOnly = true)
public GatheringCodeVO findGatheringCodeById(String id) { public GatheringCodeVO findGatheringCodeById(String id) {
GatheringCode gatheringCode = gatheringCodeRepo.getOne(id); GatheringCode gatheringCode = gatheringCodeRepo.getOne(id);
return GatheringCodeVO.convertFor(gatheringCode); return GatheringCodeVO.convertFor(gatheringCode);
} }
@Transactional(readOnly = true) @Transactional(readOnly = true)
public PageResult<GatheringCodeVO> findMyGatheringCodeByPage(GatheringCodeQueryCondParam param) { public PageResult<GatheringCodeVO> findMyGatheringCodeByPage(GatheringCodeQueryCondParam param) {
if (StrUtil.isBlank(param.getUserAccountId())) { if (StrUtil.isBlank(param.getUserAccountId())) {
throw new BizException(BizError.无权查看数据); throw new BizException(BizError.无权查看数据);
} }
return findGatheringCodeByPage(param); return findGatheringCodeByPage(param);
} }
@Transactional(readOnly = true) @Transactional(readOnly = true)
public PageResult<GatheringCodeVO> findGatheringCodeByPage(GatheringCodeQueryCondParam param) { public PageResult<GatheringCodeVO> findGatheringCodeByPage(GatheringCodeQueryCondParam param) {
Specification<GatheringCode> spec = new Specification<GatheringCode>() { Specification<GatheringCode> spec = new Specification<GatheringCode>() {
/** /**
* *
*/ */
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public Predicate toPredicate(Root<GatheringCode> root, CriteriaQuery<?> query, CriteriaBuilder builder) { public Predicate toPredicate(Root<GatheringCode> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
List<Predicate> predicates = new ArrayList<Predicate>(); List<Predicate> predicates = new ArrayList<Predicate>();
if (StrUtil.isNotEmpty(param.getState())) { if (StrUtil.isNotEmpty(param.getState())) {
predicates.add(builder.equal(root.get("state"), param.getState())); predicates.add(builder.equal(root.get("state"), param.getState()));
} }
if (StrUtil.isNotEmpty(param.getGatheringChannelCode())) { if (StrUtil.isNotEmpty(param.getGatheringChannelCode())) {
predicates.add(builder.equal(root.get("gatheringChannelCode"), param.getGatheringChannelCode())); predicates.add(builder.equal(root.get("gatheringChannelCode"), param.getGatheringChannelCode()));
} }
if (StrUtil.isNotEmpty(param.getPayee())) { if (StrUtil.isNotEmpty(param.getPayee())) {
predicates.add(builder.equal(root.get("payee"), param.getPayee())); predicates.add(builder.equal(root.get("payee"), param.getPayee()));
} }
if (StrUtil.isNotEmpty(param.getUserName())) { if (StrUtil.isNotEmpty(param.getUserName())) {
predicates.add(builder.equal(root.join("userAccount", JoinType.INNER).get("userName"), predicates.add(builder.equal(root.join("userAccount", JoinType.INNER).get("userName"),
param.getUserName())); param.getUserName()));
} }
if (StrUtil.isNotEmpty(param.getUserAccountId())) { if (StrUtil.isNotEmpty(param.getUserAccountId())) {
predicates.add(builder.equal(root.get("userAccountId"), param.getUserAccountId())); predicates.add(builder.equal(root.get("userAccountId"), param.getUserAccountId()));
} }
return predicates.size() > 0 ? builder.and(predicates.toArray(new Predicate[predicates.size()])) : null; return predicates.size() > 0 ? builder.and(predicates.toArray(new Predicate[predicates.size()])) : null;
} }
}; };
Page<GatheringCode> result = gatheringCodeRepo.findAll(spec, Page<GatheringCode> result = gatheringCodeRepo.findAll(spec,
PageRequest.of(param.getPageNum() - 1, param.getPageSize(), Sort.by(Sort.Order.desc("createTime")))); PageRequest.of(param.getPageNum() - 1, param.getPageSize(), Sort.by(Sort.Order.desc("createTime"))));
PageResult<GatheringCodeVO> pageResult = new PageResult<>(GatheringCodeVO.convertFor(result.getContent()), PageResult<GatheringCodeVO> pageResult = new PageResult<>(GatheringCodeVO.convertFor(result.getContent()),
param.getPageNum(), param.getPageSize(), result.getTotalElements()); param.getPageNum(), param.getPageSize(), result.getTotalElements());
return pageResult; return pageResult;
} }
@Transactional @Transactional
public void associateGatheringCodeStorage(String storageId, String gatheringCodeId) { public void associateGatheringCodeStorage(String storageId, String gatheringCodeId) {
Storage storage = storageRepo.getOne(storageId); Storage storage = storageRepo.getOne(storageId);
storage.setAssociateId(gatheringCodeId); storage.setAssociateId(gatheringCodeId);
storage.setAssociateBiz("gatheringCode"); storage.setAssociateBiz("gatheringCode");
storageRepo.save(storage); storageRepo.save(storage);
} }
@Transactional @Transactional
public void disassociationGatheringCodeStorage(String storageId) { public void disassociationGatheringCodeStorage(String storageId) {
Storage oldStorage = storageRepo.getOne(storageId); Storage oldStorage = storageRepo.getOne(storageId);
oldStorage.setAssociateId(null); oldStorage.setAssociateId(null);
oldStorage.setAssociateBiz(null); oldStorage.setAssociateBiz(null);
storageRepo.save(oldStorage); storageRepo.save(oldStorage);
} }
@Transactional @Transactional
public void addOrUpdateGatheringCode(GatheringCodeParam param) { public void addOrUpdateGatheringCode(GatheringCodeParam param) {
String userAccountId = null; String userAccountId = null;
if (StrUtil.isBlank(param.getId())) { if (StrUtil.isBlank(param.getId())) {
if (StrUtil.isBlank(param.getUserName())) { if (StrUtil.isBlank(param.getUserName())) {
throw new BizException(BizError.参数异常); throw new BizException(BizError.参数异常);
} }
UserAccount userAccount = userAccountRepo.findByUserName(param.getUserName()); UserAccount userAccount = userAccountRepo.findByUserName(param.getUserName());
if (userAccount == null) { if (userAccount == null) {
throw new BizException(BizError.找不到所属账号无法新增收款码); throw new BizException(BizError.找不到所属账号无法新增收款码);
} }
userAccountId = userAccount.getId(); userAccountId = userAccount.getId();
} }
addOrUpdateGatheringCode(param, userAccountId); addOrUpdateGatheringCode(param, userAccountId);
} }
@ParamValid @ParamValid
@Transactional @Transactional
public void addOrUpdateGatheringCode(GatheringCodeParam param, String userAccountId) { public void addOrUpdateGatheringCode(GatheringCodeParam param, String userAccountId) {
if (param.getFixedGatheringAmount()) { /*if (param.getFixedGatheringAmount()) {
if (param.getGatheringAmount() == null) { if (param.getGatheringAmount() == null) {
throw new BizException(BizError.参数异常); throw new BizException(BizError.参数异常);
} }
if (param.getGatheringAmount() <= 0) { if (param.getGatheringAmount() <= 0) {
throw new BizException(BizError.参数异常); throw new BizException(BizError.参数异常);
} }
} }*/
// 新增 // 新增
if (StrUtil.isBlank(param.getId())) { if (StrUtil.isBlank(param.getId())) {
GatheringCode gatheringCode = param.convertToPo(userAccountId); GatheringCode gatheringCode = param.convertToPo(userAccountId);
gatheringCodeRepo.save(gatheringCode); gatheringCodeRepo.save(gatheringCode);
associateGatheringCodeStorage(param.getStorageId(), gatheringCode.getId()); if (param.getGatheringChannelCode().equals("bankcard")) {
} return;
// 修改 }
else { associateGatheringCodeStorage(param.getStorageId(), gatheringCode.getId());
GatheringCode gatheringCode = gatheringCodeRepo.getOne(param.getId()); }
// 取消关联旧的收款码图片 // 修改
if (!param.getStorageId().equals(gatheringCode.getStorageId())) { else {
disassociationGatheringCodeStorage(gatheringCode.getStorageId()); GatheringCode gatheringCode = gatheringCodeRepo.getOne(param.getId());
} // 取消关联旧的收款码图片
BeanUtils.copyProperties(param, gatheringCode); if (!param.getStorageId().equals(gatheringCode.getStorageId())) {
gatheringCodeRepo.save(gatheringCode); disassociationGatheringCodeStorage(gatheringCode.getStorageId());
associateGatheringCodeStorage(param.getStorageId(), gatheringCode.getId()); }
} BeanUtils.copyProperties(param, gatheringCode);
} gatheringCodeRepo.save(gatheringCode);
if (param.getGatheringChannelCode().equals("bankcard")) {
return;
}
associateGatheringCodeStorage(param.getStorageId(), gatheringCode.getId());
}
}
} }
...@@ -37,6 +37,7 @@ import cn.hutool.core.date.DateField; ...@@ -37,6 +37,7 @@ import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestAlgorithm; import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester; import cn.hutool.crypto.digest.Digester;
...@@ -84,658 +85,681 @@ import me.zohar.runscore.useraccount.repo.UserAccountRepo; ...@@ -84,658 +85,681 @@ import me.zohar.runscore.useraccount.repo.UserAccountRepo;
@Service @Service
public class MerchantOrderService { public class MerchantOrderService {
@Autowired @Autowired
private StringRedisTemplate redisTemplate; private StringRedisTemplate redisTemplate;
@Autowired @Autowired
private MerchantOrderRepo merchantOrderRepo; private MerchantOrderRepo merchantOrderRepo;
@Autowired @Autowired
private MerchantOrderPayInfoRepo merchantOrderPayInfoRepo; private MerchantOrderPayInfoRepo merchantOrderPayInfoRepo;
@Autowired @Autowired
private MerchantRepo merchantRepo; private MerchantRepo merchantRepo;
@Autowired @Autowired
private UserAccountRepo userAccountRepo; private UserAccountRepo userAccountRepo;
@Autowired @Autowired
private GatheringCodeRepo gatheringCodeRepo; private GatheringCodeRepo gatheringCodeRepo;
@Autowired @Autowired
private AccountChangeLogRepo accountChangeLogRepo; private AccountChangeLogRepo accountChangeLogRepo;
@Autowired @Autowired
private ReceiveOrderSettingRepo platformOrderSettingRepo; private ReceiveOrderSettingRepo platformOrderSettingRepo;
@Autowired @Autowired
private OrderRebateRepo orderRebateRepo; private OrderRebateRepo orderRebateRepo;
@Transactional(readOnly = true)
public MerchantOrderDetailsVO findMerchantOrderDetailsById(@NotBlank String orderId) {
MerchantOrderDetailsVO vo = MerchantOrderDetailsVO.convertFor(merchantOrderRepo.getOne(orderId)); @Transactional(readOnly = true)
return vo; public MerchantOrderDetailsVO findMerchantOrderDetailsById(@NotBlank String orderId) {
} MerchantOrderDetailsVO vo = MerchantOrderDetailsVO.convertFor(merchantOrderRepo.getOne(orderId));
return vo;
/** }
* 客服取消订单退款
* /**
* @param orderId * 客服取消订单退款
*/ */
@Transactional @Transactional
public void customerServiceCancelOrderRefund(@NotBlank String orderId) { public void customerServiceCancelOrderRefund(@NotBlank String orderId) {
MerchantOrder merchantOrder = merchantOrderRepo.getOne(orderId); MerchantOrder merchantOrder = merchantOrderRepo.getOne(orderId);
if (!(Constant.商户订单状态_申诉中.equals(merchantOrder.getOrderState()))) { if (!(Constant.商户订单状态_申诉中.equals(merchantOrder.getOrderState()))) {
throw new BizException(BizError.只有申诉中的商户订单才能取消订单退款); throw new BizException(BizError.只有申诉中的商户订单才能取消订单退款);
} }
UserAccount userAccount = merchantOrder.getReceivedAccount(); UserAccount userAccount = merchantOrder.getReceivedAccount();
Double cashDeposit = NumberUtil.round(userAccount.getCashDeposit() + merchantOrder.getGatheringAmount(), 4) Double cashDeposit = NumberUtil.round(userAccount.getCashDeposit() + merchantOrder.getGatheringAmount(), 4)
.doubleValue(); .doubleValue();
userAccount.setCashDeposit(cashDeposit); userAccount.setCashDeposit(cashDeposit);
userAccountRepo.save(userAccount); userAccountRepo.save(userAccount);
merchantOrder.customerCancelOrderRefund(); merchantOrder.customerCancelOrderRefund();
merchantOrderRepo.save(merchantOrder); merchantOrderRepo.save(merchantOrder);
accountChangeLogRepo.save(AccountChangeLog.buildWithCustomerCancelOrderRefund(userAccount, merchantOrder)); accountChangeLogRepo.save(AccountChangeLog.buildWithCustomerCancelOrderRefund(userAccount, merchantOrder));
} }
// @Transactional // @Transactional
// public void merchantConfirmToPaid(@NotBlank String secretKey, @NotBlank // public void merchantConfirmToPaid(@NotBlank String secretKey, @NotBlank
// String orderId) { // String orderId) {
// Merchant merchant = merchantRepo.findByMerchantNum(secretKey); // Merchant merchant = merchantRepo.findByMerchantNum(secretKey);
// if (merchant == null) { // if (merchant == null) {
// throw new BizException(BizError.商户未接入); // throw new BizException(BizError.商户未接入);
// } // }
// MerchantOrder order = merchantOrderRepo.findById(orderId).orElse(null); // MerchantOrder order = merchantOrderRepo.findById(orderId).orElse(null);
// if (order == null) { // if (order == null) {
// log.error("商家订单不存在;secretKey:{},orderId:{}", secretKey, orderId); // log.error("商家订单不存在;secretKey:{},orderId:{}", secretKey, orderId);
// throw new BizException(BizError.商户订单不存在); // throw new BizException(BizError.商户订单不存在);
// } // }
// if (!order.getMerchantId().equals(merchant.getId())) { // if (!order.getMerchantId().equals(merchant.getId())) {
// log.error("无权更新商家订单状态为商户已确认支付;secretKey:{},orderId:{}", secretKey, orderId); // log.error("无权更新商家订单状态为商户已确认支付;secretKey:{},orderId:{}", secretKey, orderId);
// throw new BizException(BizError.无权更新商户订单状态为商户已确认支付); // throw new BizException(BizError.无权更新商户订单状态为商户已确认支付);
// } // }
// if (!Constant.商户订单状态_已接单.equals(order.getOrderState())) { // if (!Constant.商户订单状态_已接单.equals(order.getOrderState())) {
// throw new BizException(BizError.订单状态为已接单才能转为平台已确认支付); // throw new BizException(BizError.订单状态为已接单才能转为平台已确认支付);
// } // }
// order.merchantConfirmToPaid(); // order.merchantConfirmToPaid();
// merchantOrderRepo.save(order); // merchantOrderRepo.save(order);
// } // }
@Transactional(readOnly = true) @Transactional(readOnly = true)
public OrderGatheringCodeVO getOrderGatheringCode(@NotBlank String orderNo) { public OrderGatheringCodeVO getOrderGatheringCode(@NotBlank String orderNo) {
MerchantOrder order = merchantOrderRepo.findByOrderNo(orderNo); MerchantOrder order = merchantOrderRepo.findByOrderNo(orderNo);
if (order == null) { if (order == null) {
log.error("商户订单不存在;orderNo:{}", orderNo); log.error("商户订单不存在;orderNo:{}", orderNo);
throw new BizException(BizError.商户订单不存在); throw new BizException(BizError.商户订单不存在);
} }
String gatheringCodeStorageId = getGatheringCodeStorageId(order.getReceivedAccountId(), GatheringCode gatheringCode = getGatheringCode(order.getReceivedAccountId(),
order.getGatheringChannelCode(), order.getGatheringAmount()); order.getGatheringChannelCode(), order.getGatheringAmount());
OrderGatheringCodeVO vo = OrderGatheringCodeVO.convertFor(order); OrderGatheringCodeVO vo = OrderGatheringCodeVO.convertFor(order);
vo.setGatheringCodeStorageId(gatheringCodeStorageId); vo.setGatheringCodeStorageId(gatheringCode.getStorageId());
return vo; vo.setGatheringCode(gatheringCode);
}
return vo;
@Transactional(readOnly = true) }
public String getGatheringCodeStorageId(String receivedAccountId, String gatheringChannelCode,
Double gatheringAmount) { @Transactional(readOnly = true)
ReceiveOrderSetting merchantOrderSetting = platformOrderSettingRepo.findTopByOrderByLatelyUpdateTime(); public String getGatheringCodeStorageId(String receivedAccountId, String gatheringChannelCode,
if (merchantOrderSetting.getUnfixedGatheringCodeReceiveOrder()) { Double gatheringAmount) {
GatheringCode gatheringCode = gatheringCodeRepo ReceiveOrderSetting merchantOrderSetting = platformOrderSettingRepo.findTopByOrderByLatelyUpdateTime();
.findTopByUserAccountIdAndGatheringChannelCodeAndFixedGatheringAmountIsFalse(receivedAccountId, if (merchantOrderSetting.getUnfixedGatheringCodeReceiveOrder()) {
gatheringChannelCode); GatheringCode gatheringCode = gatheringCodeRepo
if (gatheringCode != null) { .findTopByUserAccountIdAndGatheringChannelCodeAndFixedGatheringAmountIsFalse(receivedAccountId,
return gatheringCode.getStorageId(); gatheringChannelCode);
} if (gatheringCode != null) {
} else { return gatheringCode.getStorageId();
GatheringCode gatheringCode = gatheringCodeRepo }
.findTopByUserAccountIdAndGatheringChannelCodeAndGatheringAmount(receivedAccountId, } else {
gatheringChannelCode, gatheringAmount); GatheringCode gatheringCode = gatheringCodeRepo
if (gatheringCode != null) { .findTopByUserAccountIdAndGatheringChannelCodeAndGatheringAmount(receivedAccountId,
return gatheringCode.getStorageId(); gatheringChannelCode, gatheringAmount);
} if (gatheringCode != null) {
} return gatheringCode.getStorageId();
return null; }
} }
return null;
@Transactional }
public void userConfirmToPaid(@NotBlank String userAccountId, @NotBlank String orderId) {
MerchantOrder platformOrder = merchantOrderRepo.findByIdAndReceivedAccountId(orderId, userAccountId); @Transactional(readOnly = true)
if (platformOrder == null) { public GatheringCode getGatheringCode(String receivedAccountId, String gatheringChannelCode,
throw new BizException(BizError.商户订单不存在); Double gatheringAmount) {
} ReceiveOrderSetting merchantOrderSetting = platformOrderSettingRepo.findTopByOrderByLatelyUpdateTime();
if (!(Constant.商户订单状态_已接单.equals(platformOrder.getOrderState()) if (merchantOrderSetting.getUnfixedGatheringCodeReceiveOrder()) {
|| Constant.商户订单状态_商户已确认支付.equals(platformOrder.getOrderState()))) { GatheringCode gatheringCode = gatheringCodeRepo
throw new BizException(BizError.订单状态为已接单或平台已确认支付才能转为确认已支付); .findTopByUserAccountIdAndGatheringChannelCodeAndFixedGatheringAmountIsFalse(receivedAccountId,
} gatheringChannelCode);
platformOrder.confirmToPaid(null); if (gatheringCode != null) {
merchantOrderRepo.save(platformOrder); return gatheringCode;
receiveOrderBountySettlement(platformOrder); }
} } else {
GatheringCode gatheringCode = gatheringCodeRepo
/** .findTopByUserAccountIdAndGatheringChannelCodeAndGatheringAmount(receivedAccountId,
* 客服确认已支付 gatheringChannelCode, gatheringAmount);
* if (gatheringCode != null) {
* @param orderId return gatheringCode;
*/ }
@Transactional }
public void customerServiceConfirmToPaid(@NotBlank String orderId, String note) { return null;
MerchantOrder platformOrder = merchantOrderRepo.findById(orderId).orElse(null); }
if (platformOrder == null) {
throw new BizException(BizError.商户订单不存在); @Transactional
} public void userConfirmToPaid(@NotBlank String userAccountId, @NotBlank String orderId) {
if (!Constant.商户订单状态_申诉中.equals(platformOrder.getOrderState())) { MerchantOrder platformOrder = merchantOrderRepo.findByIdAndReceivedAccountId(orderId, userAccountId);
throw new BizException(BizError.订单状态为申述中才能转为确认已支付); if (platformOrder == null) {
} throw new BizException(BizError.商户订单不存在);
platformOrder.confirmToPaid(note); }
merchantOrderRepo.save(platformOrder); if (!(Constant.商户订单状态_已接单.equals(platformOrder.getOrderState())
receiveOrderBountySettlement(platformOrder); || Constant.商户订单状态_商户已确认支付.equals(platformOrder.getOrderState()))) {
} throw new BizException(BizError.订单状态为已接单或平台已确认支付才能转为确认已支付);
}
/** platformOrder.confirmToPaid(null);
* 接单奖励金结算 merchantOrderRepo.save(platformOrder);
*/ receiveOrderBountySettlement(platformOrder);
@Transactional }
public void receiveOrderBountySettlement(MerchantOrder merchantOrder) {
UserAccount userAccount = merchantOrder.getReceivedAccount(); /**
double bounty = NumberUtil.round(merchantOrder.getGatheringAmount() * userAccount.getRebate() * 0.01, 4) * 客服确认已支付
.doubleValue(); */
merchantOrder.updateBounty(bounty); @Transactional
merchantOrderRepo.save(merchantOrder); public void customerServiceConfirmToPaid(@NotBlank String orderId, String note) {
userAccount.setCashDeposit(NumberUtil.round(userAccount.getCashDeposit() + bounty, 4).doubleValue()); MerchantOrder platformOrder = merchantOrderRepo.findById(orderId).orElse(null);
userAccountRepo.save(userAccount); if (platformOrder == null) {
accountChangeLogRepo throw new BizException(BizError.商户订单不存在);
.save(AccountChangeLog.buildWithReceiveOrderBounty(userAccount, bounty, userAccount.getRebate())); }
generateOrderRebate(merchantOrder); if (!Constant.商户订单状态_申诉中.equals(platformOrder.getOrderState())) {
ThreadPoolUtils.getPaidMerchantOrderPool().schedule(() -> { throw new BizException(BizError.订单状态为申述中才能转为确认已支付);
redisTemplate.opsForList().leftPush(Constant.商户订单ID, merchantOrder.getId()); }
}, 1, TimeUnit.SECONDS); platformOrder.confirmToPaid(note);
} merchantOrderRepo.save(platformOrder);
receiveOrderBountySettlement(platformOrder);
/** }
* 生成订单返点
* /**
* @param bettingOrder * 接单奖励金结算
*/ */
public void generateOrderRebate(MerchantOrder merchantOrder) { @Transactional
UserAccount userAccount = merchantOrder.getReceivedAccount(); public void receiveOrderBountySettlement(MerchantOrder merchantOrder) {
UserAccount superior = merchantOrder.getReceivedAccount().getInviter(); UserAccount userAccount = merchantOrder.getReceivedAccount();
while (superior != null) { double bounty = NumberUtil.round(merchantOrder.getGatheringAmount() * userAccount.getRebate() * 0.01, 4)
double rebate = NumberUtil.round(superior.getRebate() - userAccount.getRebate(), 4).doubleValue(); .doubleValue();
if (rebate < 0) { merchantOrder.updateBounty(bounty);
log.error("订单返点异常,下级账号的返点不能大于上级账号;下级账号id:{},上级账号id:{}", userAccount.getId(), superior.getId()); merchantOrderRepo.save(merchantOrder);
break; userAccount.setCashDeposit(NumberUtil.round(userAccount.getCashDeposit() + bounty, 4).doubleValue());
} userAccountRepo.save(userAccount);
double rebateAmount = NumberUtil.round(merchantOrder.getGatheringAmount() * rebate * 0.01, 4).doubleValue(); accountChangeLogRepo
OrderRebate orderRebate = OrderRebate.build(rebate, rebateAmount, merchantOrder.getId(), superior.getId()); .save(AccountChangeLog.buildWithReceiveOrderBounty(userAccount, bounty, userAccount.getRebate()));
orderRebateRepo.save(orderRebate); generateOrderRebate(merchantOrder);
userAccount = superior; ThreadPoolUtils.getPaidMerchantOrderPool().schedule(() -> {
superior = superior.getInviter(); redisTemplate.opsForList().leftPush(Constant.商户订单ID, merchantOrder.getId());
} }, 1, TimeUnit.SECONDS);
} }
@Transactional(readOnly = true) /**
public void orderRebateAutoSettlement() { * 生成订单返点
List<OrderRebate> orderRebates = orderRebateRepo.findBySettlementTimeIsNull(); */
for (OrderRebate orderRebate : orderRebates) { public void generateOrderRebate(MerchantOrder merchantOrder) {
redisTemplate.opsForList().leftPush(Constant.订单返点ID, orderRebate.getId()); UserAccount userAccount = merchantOrder.getReceivedAccount();
} UserAccount superior = merchantOrder.getReceivedAccount().getInviter();
} while (superior != null) {
double rebate = NumberUtil.round(superior.getRebate() - userAccount.getRebate(), 4).doubleValue();
/** if (rebate < 0) {
* 通知指定的订单进行返点结算 log.error("订单返点异常,下级账号的返点不能大于上级账号;下级账号id:{},上级账号id:{}", userAccount.getId(), superior.getId());
* break;
* @param issueId }
*/ double rebateAmount = NumberUtil.round(merchantOrder.getGatheringAmount() * rebate * 0.01, 4).doubleValue();
@Transactional(readOnly = true) OrderRebate orderRebate = OrderRebate.build(rebate, rebateAmount, merchantOrder.getId(), superior.getId());
public void noticeOrderRebateSettlement(@NotBlank String orderId) { orderRebateRepo.save(orderRebate);
List<OrderRebate> orderRebates = orderRebateRepo.findByMerchantOrderId(orderId); userAccount = superior;
for (OrderRebate orderRebate : orderRebates) { superior = superior.getInviter();
redisTemplate.opsForList().leftPush(Constant.订单返点ID, orderRebate.getId()); }
} }
}
@Transactional(readOnly = true)
/** public void orderRebateAutoSettlement() {
* 订单返点结算 List<OrderRebate> orderRebates = orderRebateRepo.findBySettlementTimeIsNull();
*/ for (OrderRebate orderRebate : orderRebates) {
@Transactional redisTemplate.opsForList().leftPush(Constant.订单返点ID, orderRebate.getId());
public void orderRebateSettlement(@NotBlank String orderRebateId) { }
OrderRebate orderRebate = orderRebateRepo.getOne(orderRebateId); }
if (orderRebate.getSettlementTime() != null) {
log.warn("当前的订单返点记录已结算,无法重复结算;id:{}", orderRebateId); /**
return; * 通知指定的订单进行返点结算
} */
orderRebate.settlement(); @Transactional(readOnly = true)
orderRebateRepo.save(orderRebate); public void noticeOrderRebateSettlement(@NotBlank String orderId) {
UserAccount userAccount = orderRebate.getRebateAccount(); List<OrderRebate> orderRebates = orderRebateRepo.findByMerchantOrderId(orderId);
double cashDeposit = userAccount.getCashDeposit() + orderRebate.getRebateAmount(); for (OrderRebate orderRebate : orderRebates) {
userAccount.setCashDeposit(NumberUtil.round(cashDeposit, 4).doubleValue()); redisTemplate.opsForList().leftPush(Constant.订单返点ID, orderRebate.getId());
userAccountRepo.save(userAccount); }
accountChangeLogRepo.save(AccountChangeLog.buildWithOrderRebate(userAccount, orderRebate)); }
}
/**
@Transactional(readOnly = true) * 订单返点结算
public List<MyWaitConfirmOrderVO> findMyWaitConfirmOrder(@NotBlank String userAccountId) { */
return MyWaitConfirmOrderVO @Transactional
.convertFor(merchantOrderRepo.findByOrderStateInAndReceivedAccountIdOrderBySubmitTimeDesc( public void orderRebateSettlement(@NotBlank String orderRebateId) {
Arrays.asList(Constant.商户订单状态_已接单, Constant.商户订单状态_商户已确认支付), userAccountId)); OrderRebate orderRebate = orderRebateRepo.getOne(orderRebateId);
} if (orderRebate.getSettlementTime() != null) {
log.warn("当前的订单返点记录已结算,无法重复结算;id:{}", orderRebateId);
@Transactional(readOnly = true) return;
public List<MyWaitReceivingOrderVO> findMyWaitReceivingOrder(@NotBlank String userAccountId) { }
UserAccount userAccount = userAccountRepo.getOne(userAccountId); orderRebate.settlement();
List<GatheringCode> gatheringCodes = gatheringCodeRepo.findByUserAccountId(userAccountId); orderRebateRepo.save(orderRebate);
if (CollectionUtil.isEmpty(gatheringCodes)) { UserAccount userAccount = orderRebate.getRebateAccount();
throw new BizException(BizError.未设置收款码无法接单); double cashDeposit = userAccount.getCashDeposit() + orderRebate.getRebateAmount();
} userAccount.setCashDeposit(NumberUtil.round(cashDeposit, 4).doubleValue());
ReceiveOrderSetting merchantOrderSetting = platformOrderSettingRepo.findTopByOrderByLatelyUpdateTime(); userAccountRepo.save(userAccount);
if (merchantOrderSetting.getUnfixedGatheringCodeReceiveOrder()) { accountChangeLogRepo.save(AccountChangeLog.buildWithOrderRebate(userAccount, orderRebate));
Map<String, String> gatheringChannelCodeMap = new HashMap<>(); }
for (GatheringCode gatheringCode : gatheringCodes) {
gatheringChannelCodeMap.put(gatheringCode.getGatheringChannelCode(), @Transactional(readOnly = true)
gatheringCode.getGatheringChannelCode()); public List<MyWaitConfirmOrderVO> findMyWaitConfirmOrder(@NotBlank String userAccountId) {
} return MyWaitConfirmOrderVO
List<MerchantOrder> waitReceivingOrders = merchantOrderRepo .convertFor(merchantOrderRepo.findByOrderStateInAndReceivedAccountIdOrderBySubmitTimeDesc(
.findTop10ByOrderStateAndGatheringAmountIsLessThanEqualAndGatheringChannelCodeInOrderBySubmitTimeDesc( Arrays.asList(Constant.商户订单状态_已接单, Constant.商户订单状态_商户已确认支付), userAccountId));
Constant.商户订单状态_等待接单, userAccount.getCashDeposit(), }
new ArrayList<>(gatheringChannelCodeMap.keySet()));
return MyWaitReceivingOrderVO.convertFor(waitReceivingOrders); @Transactional(readOnly = true)
} public List<MyWaitReceivingOrderVO> findMyWaitReceivingOrder(@NotBlank String userAccountId) {
Map<String, List<Double>> gatheringChannelCodeMap = new HashMap<>(); UserAccount userAccount = userAccountRepo.getOne(userAccountId);
for (GatheringCode gatheringCode : gatheringCodes) { List<GatheringCode> gatheringCodes = gatheringCodeRepo.findByUserAccountId(userAccountId);
if (gatheringChannelCodeMap.get(gatheringCode.getGatheringChannelCode()) == null) { if (CollectionUtil.isEmpty(gatheringCodes)) {
gatheringChannelCodeMap.put(gatheringCode.getGatheringChannelCode(), new ArrayList<>()); throw new BizException(BizError.未设置收款码无法接单);
} }
if (userAccount.getCashDeposit() < gatheringCode.getGatheringAmount()) { ReceiveOrderSetting merchantOrderSetting = platformOrderSettingRepo.findTopByOrderByLatelyUpdateTime();
continue; if (merchantOrderSetting.getUnfixedGatheringCodeReceiveOrder()) {
} Map<String, String> gatheringChannelCodeMap = new HashMap<>();
gatheringChannelCodeMap.get(gatheringCode.getGatheringChannelCode()) for (GatheringCode gatheringCode : gatheringCodes) {
.add(gatheringCode.getGatheringAmount()); gatheringChannelCodeMap.put(gatheringCode.getGatheringChannelCode(),
} gatheringCode.getGatheringChannelCode());
List<MerchantOrder> waitReceivingOrders = new ArrayList<>(); }
for (Entry<String, List<Double>> entry : gatheringChannelCodeMap.entrySet()) { List<MerchantOrder> waitReceivingOrders = merchantOrderRepo
if (CollectionUtil.isEmpty(entry.getValue())) { .findTop10ByOrderStateAndGatheringAmountIsLessThanEqualAndGatheringChannelCodeInOrderBySubmitTimeDesc(
continue; Constant.商户订单状态_等待接单, userAccount.getCashDeposit(),
} new ArrayList<>(gatheringChannelCodeMap.keySet()));
List<MerchantOrder> tmpOrders = merchantOrderRepo return MyWaitReceivingOrderVO.convertFor(waitReceivingOrders);
.findTop10ByOrderStateAndGatheringAmountInAndGatheringChannelCodeOrderBySubmitTimeDesc( }
Constant.商户订单状态_等待接单, entry.getValue(), entry.getKey()); Map<String, List<Double>> gatheringChannelCodeMap = new HashMap<>();
waitReceivingOrders.addAll(tmpOrders); for (GatheringCode gatheringCode : gatheringCodes) {
} if (gatheringChannelCodeMap.get(gatheringCode.getGatheringChannelCode()) == null) {
Collections.sort(waitReceivingOrders, new Comparator<MerchantOrder>() { gatheringChannelCodeMap.put(gatheringCode.getGatheringChannelCode(), new ArrayList<>());
}
@Override if (userAccount.getCashDeposit() < gatheringCode.getGatheringAmount()) {
public int compare(MerchantOrder o1, MerchantOrder o2) { continue;
return o1.getSubmitTime().before(o2.getSubmitTime()) ? 1 : -1; }
} gatheringChannelCodeMap.get(gatheringCode.getGatheringChannelCode())
}); .add(gatheringCode.getGatheringAmount());
if (waitReceivingOrders.isEmpty()) { }
return MyWaitReceivingOrderVO.convertFor(waitReceivingOrders); List<MerchantOrder> waitReceivingOrders = new ArrayList<>();
} for (Entry<String, List<Double>> entry : gatheringChannelCodeMap.entrySet()) {
return MyWaitReceivingOrderVO.convertFor( if (CollectionUtil.isEmpty(entry.getValue())) {
waitReceivingOrders.subList(0, waitReceivingOrders.size() >= 10 ? 10 : waitReceivingOrders.size())); continue;
} }
List<MerchantOrder> tmpOrders = merchantOrderRepo
@ParamValid .findTop10ByOrderStateAndGatheringAmountInAndGatheringChannelCodeOrderBySubmitTimeDesc(
@Transactional Constant.商户订单状态_等待接单, entry.getValue(), entry.getKey());
public MerchantOrderVO manualStartOrder(ManualStartOrderParam param) { waitReceivingOrders.addAll(tmpOrders);
Merchant merchant = merchantRepo.findByMerchantNum(param.getMerchantNum()); }
if (merchant == null) { Collections.sort(waitReceivingOrders, new Comparator<MerchantOrder>() {
throw new BizException(BizError.商户未接入);
} @Override
String sign = param.getMerchantNum() + param.getOrderNo() public int compare(MerchantOrder o1, MerchantOrder o2) {
+ new DecimalFormat("###################.###########").format(param.getGatheringAmount()) return o1.getSubmitTime().before(o2.getSubmitTime()) ? 1 : -1;
+ param.getNotifyUrl() + merchant.getSecretKey(); }
sign = new Digester(DigestAlgorithm.MD5).digestHex(sign); });
param.setSign(sign); if (waitReceivingOrders.isEmpty()) {
return MyWaitReceivingOrderVO.convertFor(waitReceivingOrders);
Integer orderEffectiveDuration = Constant.商户订单接单有效时长; }
ReceiveOrderSetting setting = platformOrderSettingRepo.findTopByOrderByLatelyUpdateTime(); return MyWaitReceivingOrderVO.convertFor(
if (setting != null) { waitReceivingOrders.subList(0, waitReceivingOrders.size() >= 10 ? 10 : waitReceivingOrders.size()));
orderEffectiveDuration = setting.getReceiveOrderEffectiveDuration(); }
}
MerchantOrder merchantOrder = param.convertToPo(merchant.getId(), orderEffectiveDuration); @ParamValid
MerchantOrderPayInfo payInfo = param.convertToPayInfoPo(merchantOrder.getId()); @Transactional
merchantOrder.setPayInfoId(payInfo.getId()); public MerchantOrderVO manualStartOrder(ManualStartOrderParam param) {
merchantOrderRepo.save(merchantOrder); Merchant merchant = merchantRepo.findByMerchantNum(param.getMerchantNum());
merchantOrderPayInfoRepo.save(payInfo); if (merchant == null) {
return MerchantOrderVO.convertFor(merchantOrder); throw new BizException(BizError.商户未接入);
} }
String sign = param.getMerchantNum() + param.getOrderNo()
/** + new DecimalFormat("###################.###########").format(param.getGatheringAmount())
* 接单 + param.getNotifyUrl() + merchant.getSecretKey();
* sign = new Digester(DigestAlgorithm.MD5).digestHex(sign);
* @param param param.setSign(sign);
* @return
*/ Integer orderEffectiveDuration = Constant.商户订单接单有效时长;
@Lock(keys = "'receiveOrder_' + #orderId") ReceiveOrderSetting setting = platformOrderSettingRepo.findTopByOrderByLatelyUpdateTime();
@Transactional if (setting != null) {
public void receiveOrder(@NotBlank String userAccountId, @NotBlank String orderId) { orderEffectiveDuration = setting.getReceiveOrderEffectiveDuration();
List<GatheringCode> gatheringCodes = gatheringCodeRepo.findByUserAccountId(userAccountId); }
if (CollectionUtil.isEmpty(gatheringCodes)) { MerchantOrder merchantOrder = param.convertToPo(merchant.getId(), orderEffectiveDuration);
throw new BizException(BizError.未设置收款码无法接单); MerchantOrderPayInfo payInfo = param.convertToPayInfoPo(merchantOrder.getId());
} merchantOrder.setPayInfoId(payInfo.getId());
MerchantOrder platformOrder = merchantOrderRepo.getOne(orderId); merchantOrderRepo.save(merchantOrder);
if (platformOrder == null) { merchantOrderPayInfoRepo.save(payInfo);
throw new BizException(BizError.商户订单不存在);
} //todo this is temporary code 这里要匹配有资源的用户接单
if (!Constant.商户订单状态_等待接单.equals(platformOrder.getOrderState())) { List<UserAccount> userAccounts = userAccountRepo.findAllByAccountType(Constant.账号类型_会员);
throw new BizException(BizError.订单已被接或已取消); ;
} this.receiveOrder(userAccounts.get(RandomUtil.randomInt(0, userAccounts.size())).getId(), merchantOrder.getId());
String gatheringCodeStorageId = getGatheringCodeStorageId(userAccountId,
platformOrder.getGatheringChannelCode(), platformOrder.getGatheringAmount()); return MerchantOrderVO.convertFor(merchantOrder);
if (StrUtil.isBlank(gatheringCodeStorageId)) { }
throw new BizException(BizError.无法接单找不到对应金额的收款码);
} /**
// 校验用户是否达到接单上限,若达到上限,则不能接单 * 接单
ReceiveOrderSetting setting = platformOrderSettingRepo.findTopByOrderByLatelyUpdateTime(); */
if (setting != null && setting.getReceiveOrderUpperLimit() != null) { @Lock(keys = "'receiveOrder_' + #orderId")
List<MyWaitConfirmOrderVO> waitConfirmOrders = findMyWaitConfirmOrder(userAccountId); @Transactional
if (waitConfirmOrders.size() >= setting.getReceiveOrderUpperLimit()) { public void receiveOrder(@NotBlank String userAccountId, @NotBlank String orderId) {
throw new BizException(BizError.已达到接单数量上限); List<GatheringCode> gatheringCodes = gatheringCodeRepo.findByUserAccountId(userAccountId);
} if (CollectionUtil.isEmpty(gatheringCodes)) {
} throw new BizException(BizError.未设置收款码无法接单);
UserAccount userAccount = userAccountRepo.getOne(userAccountId); }
if (setting != null && setting.getCashDepositMinimumRequire() != null) { MerchantOrder platformOrder = merchantOrderRepo.getOne(orderId);
if (userAccount.getCashDeposit() < setting.getCashDepositMinimumRequire()) { if (platformOrder == null) {
throw new BizException(BizError.未达到接单保证金最低要求); throw new BizException(BizError.商户订单不存在);
} }
} if (!Constant.商户订单状态_等待接单.equals(platformOrder.getOrderState())) {
Double cashDeposit = NumberUtil.round(userAccount.getCashDeposit() - platformOrder.getGatheringAmount(), 4) throw new BizException(BizError.订单已被接或已取消);
.doubleValue(); }
if (cashDeposit < 0) { String gatheringCodeStorageId = getGatheringCodeStorageId(userAccountId,
throw new BizException(BizError.保证金不足无法接单); platformOrder.getGatheringChannelCode(), platformOrder.getGatheringAmount());
} //支付宝和微信才有收款码
if (StrUtil.isBlank(gatheringCodeStorageId) && !platformOrder.getGatheringChannelCode().equals(Constant.支付渠道_银行卡) ) {
userAccount.setCashDeposit(cashDeposit); throw new BizException(BizError.无法接单找不到对应金额的收款码);
userAccountRepo.save(userAccount); }
// 校验用户是否达到接单上限,若达到上限,则不能接单
Integer orderEffectiveDuration = Constant.商户订单支付有效时长; ReceiveOrderSetting setting = platformOrderSettingRepo.findTopByOrderByLatelyUpdateTime();
if (setting != null && setting.getOrderPayEffectiveDuration() != null) { if (setting != null && setting.getReceiveOrderUpperLimit() != null) {
orderEffectiveDuration = setting.getOrderPayEffectiveDuration(); List<MyWaitConfirmOrderVO> waitConfirmOrders = findMyWaitConfirmOrder(userAccountId);
} if (waitConfirmOrders.size() >= setting.getReceiveOrderUpperLimit()) {
platformOrder.updateReceived(userAccount.getId(), gatheringCodeStorageId); throw new BizException(BizError.已达到接单数量上限);
platformOrder.updateUsefulTime( }
DateUtil.offset(platformOrder.getReceivedTime(), DateField.MINUTE, orderEffectiveDuration)); }
merchantOrderRepo.save(platformOrder); UserAccount userAccount = userAccountRepo.getOne(userAccountId);
accountChangeLogRepo.save(AccountChangeLog.buildWithReceiveOrderDeduction(userAccount, platformOrder)); if (setting != null && setting.getCashDepositMinimumRequire() != null) {
} if (userAccount.getCashDeposit() < setting.getCashDepositMinimumRequire()) {
throw new BizException(BizError.未达到接单保证金最低要求);
@Transactional(readOnly = true) }
public PageResult<MerchantOrderVO> findMerchantOrderByPage(MerchantOrderQueryCondParam param) { }
Specification<MerchantOrder> spec = new Specification<MerchantOrder>() { Double cashDeposit = NumberUtil.round(userAccount.getCashDeposit() - platformOrder.getGatheringAmount(), 4)
/** .doubleValue();
* if (cashDeposit < 0) {
*/ throw new BizException(BizError.保证金不足无法接单);
private static final long serialVersionUID = 1L; }
public Predicate toPredicate(Root<MerchantOrder> root, CriteriaQuery<?> query, CriteriaBuilder builder) { userAccount.setCashDeposit(cashDeposit);
List<Predicate> predicates = new ArrayList<Predicate>(); userAccountRepo.save(userAccount);
if (StrUtil.isNotBlank(param.getOrderNo())) {
predicates.add(builder.equal(root.get("orderNo"), param.getOrderNo())); Integer orderEffectiveDuration = Constant.商户订单支付有效时长;
} if (setting != null && setting.getOrderPayEffectiveDuration() != null) {
orderEffectiveDuration = setting.getOrderPayEffectiveDuration();
if (StrUtil.isNotBlank(param.getPlatformName())) { }
predicates.add( platformOrder.updateReceived(userAccount.getId(), gatheringCodeStorageId);
builder.equal(root.join("merchant", JoinType.INNER).get("name"), param.getPlatformName())); platformOrder.updateUsefulTime(
} DateUtil.offset(platformOrder.getReceivedTime(), DateField.MINUTE, orderEffectiveDuration));
if (StrUtil.isNotBlank(param.getGatheringChannelCode())) { merchantOrderRepo.save(platformOrder);
predicates.add(builder.equal(root.get("gatheringChannelCode"), param.getGatheringChannelCode())); accountChangeLogRepo.save(AccountChangeLog.buildWithReceiveOrderDeduction(userAccount, platformOrder));
} }
if (StrUtil.isNotBlank(param.getOrderState())) {
predicates.add(builder.equal(root.get("orderState"), param.getOrderState())); @Transactional(readOnly = true)
} public PageResult<MerchantOrderVO> findMerchantOrderByPage(MerchantOrderQueryCondParam param) {
if (StrUtil.isNotBlank(param.getReceiverUserName())) { Specification<MerchantOrder> spec = new Specification<MerchantOrder>() {
predicates.add(builder.equal(root.join("userAccount", JoinType.INNER).get("userName"), /**
param.getReceiverUserName())); *
} */
if (param.getSubmitStartTime() != null) { private static final long serialVersionUID = 1L;
predicates.add(builder.greaterThanOrEqualTo(root.get("submitTime").as(Date.class),
DateUtil.beginOfDay(param.getSubmitStartTime()))); public Predicate toPredicate(Root<MerchantOrder> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
} List<Predicate> predicates = new ArrayList<Predicate>();
if (param.getSubmitEndTime() != null) { if (StrUtil.isNotBlank(param.getOrderNo())) {
predicates.add(builder.lessThanOrEqualTo(root.get("submitTime").as(Date.class), predicates.add(builder.equal(root.get("orderNo"), param.getOrderNo()));
DateUtil.endOfDay(param.getSubmitEndTime()))); }
}
if (param.getReceiveOrderStartTime() != null) { if (StrUtil.isNotBlank(param.getPlatformName())) {
predicates.add(builder.greaterThanOrEqualTo(root.get("receivedTime").as(Date.class), predicates.add(
DateUtil.beginOfDay(param.getReceiveOrderStartTime()))); builder.equal(root.join("merchant", JoinType.INNER).get("name"), param.getPlatformName()));
} }
if (param.getReceiveOrderEndTime() != null) { if (StrUtil.isNotBlank(param.getGatheringChannelCode())) {
predicates.add(builder.lessThanOrEqualTo(root.get("receivedTime").as(Date.class), predicates.add(builder.equal(root.get("gatheringChannelCode"), param.getGatheringChannelCode()));
DateUtil.endOfDay(param.getReceiveOrderEndTime()))); }
} if (StrUtil.isNotBlank(param.getOrderState())) {
return predicates.size() > 0 ? builder.and(predicates.toArray(new Predicate[predicates.size()])) : null; predicates.add(builder.equal(root.get("orderState"), param.getOrderState()));
} }
}; if (StrUtil.isNotBlank(param.getReceiverUserName())) {
Page<MerchantOrder> result = merchantOrderRepo.findAll(spec, predicates.add(builder.equal(root.join("userAccount", JoinType.INNER).get("userName"),
PageRequest.of(param.getPageNum() - 1, param.getPageSize(), Sort.by(Sort.Order.desc("submitTime")))); param.getReceiverUserName()));
PageResult<MerchantOrderVO> pageResult = new PageResult<>(MerchantOrderVO.convertFor(result.getContent()), }
param.getPageNum(), param.getPageSize(), result.getTotalElements()); if (param.getSubmitStartTime() != null) {
return pageResult; predicates.add(builder.greaterThanOrEqualTo(root.get("submitTime").as(Date.class),
} DateUtil.beginOfDay(param.getSubmitStartTime())));
}
@Transactional(readOnly = true) if (param.getSubmitEndTime() != null) {
public PageResult<ReceiveOrderRecordVO> findMyReceiveOrderRecordByPage(MyReceiveOrderRecordQueryCondParam param) { predicates.add(builder.lessThanOrEqualTo(root.get("submitTime").as(Date.class),
Specification<MerchantOrder> spec = new Specification<MerchantOrder>() { DateUtil.endOfDay(param.getSubmitEndTime())));
/** }
* if (param.getReceiveOrderStartTime() != null) {
*/ predicates.add(builder.greaterThanOrEqualTo(root.get("receivedTime").as(Date.class),
private static final long serialVersionUID = 1L; DateUtil.beginOfDay(param.getReceiveOrderStartTime())));
}
public Predicate toPredicate(Root<MerchantOrder> root, CriteriaQuery<?> query, CriteriaBuilder builder) { if (param.getReceiveOrderEndTime() != null) {
List<Predicate> predicates = new ArrayList<Predicate>(); predicates.add(builder.lessThanOrEqualTo(root.get("receivedTime").as(Date.class),
if (StrUtil.isNotBlank(param.getGatheringChannelCode())) { DateUtil.endOfDay(param.getReceiveOrderEndTime())));
predicates.add(builder.equal(root.get("gatheringChannelCode"), param.getGatheringChannelCode())); }
} return predicates.size() > 0 ? builder.and(predicates.toArray(new Predicate[predicates.size()])) : null;
if (StrUtil.isNotBlank(param.getReceiverUserName())) { }
predicates.add(builder.equal(root.join("receivedAccount", JoinType.INNER).get("userName"), };
param.getReceiverUserName())); Page<MerchantOrder> result = merchantOrderRepo.findAll(spec,
} PageRequest.of(param.getPageNum() - 1, param.getPageSize(), Sort.by(Sort.Order.desc("submitTime"))));
if (param.getReceiveOrderTime() != null) { PageResult<MerchantOrderVO> pageResult = new PageResult<>(MerchantOrderVO.convertFor(result.getContent()),
predicates.add(builder.greaterThanOrEqualTo(root.get("receivedTime").as(Date.class), param.getPageNum(), param.getPageSize(), result.getTotalElements());
DateUtil.beginOfDay(param.getReceiveOrderTime()))); return pageResult;
predicates.add(builder.lessThanOrEqualTo(root.get("receivedTime").as(Date.class), }
DateUtil.endOfDay(param.getReceiveOrderTime())));
} @Transactional(readOnly = true)
return predicates.size() > 0 ? builder.and(predicates.toArray(new Predicate[predicates.size()])) : null; public PageResult<ReceiveOrderRecordVO> findMyReceiveOrderRecordByPage(MyReceiveOrderRecordQueryCondParam param) {
} Specification<MerchantOrder> spec = new Specification<MerchantOrder>() {
}; /**
Page<MerchantOrder> result = merchantOrderRepo.findAll(spec, *
PageRequest.of(param.getPageNum() - 1, param.getPageSize(), Sort.by(Sort.Order.desc("submitTime")))); */
PageResult<ReceiveOrderRecordVO> pageResult = new PageResult<>( private static final long serialVersionUID = 1L;
ReceiveOrderRecordVO.convertFor(result.getContent()), param.getPageNum(), param.getPageSize(),
result.getTotalElements()); public Predicate toPredicate(Root<MerchantOrder> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return pageResult; List<Predicate> predicates = new ArrayList<Predicate>();
} if (StrUtil.isNotBlank(param.getGatheringChannelCode())) {
predicates.add(builder.equal(root.get("gatheringChannelCode"), param.getGatheringChannelCode()));
/** }
* 取消订单 if (StrUtil.isNotBlank(param.getReceiverUserName())) {
* predicates.add(builder.equal(root.join("receivedAccount", JoinType.INNER).get("userName"),
* @param id param.getReceiverUserName()));
*/ }
@Transactional if (param.getReceiveOrderTime() != null) {
public void cancelOrder(@NotBlank String id) { predicates.add(builder.greaterThanOrEqualTo(root.get("receivedTime").as(Date.class),
MerchantOrder platformOrder = merchantOrderRepo.getOne(id); DateUtil.beginOfDay(param.getReceiveOrderTime())));
if (!Constant.商户订单状态_等待接单.equals(platformOrder.getOrderState())) { predicates.add(builder.lessThanOrEqualTo(root.get("receivedTime").as(Date.class),
throw new BizException(BizError.只有等待接单状态的商户订单才能取消); DateUtil.endOfDay(param.getReceiveOrderTime())));
} }
platformOrder.setOrderState(Constant.商户订单状态_人工取消); return predicates.size() > 0 ? builder.and(predicates.toArray(new Predicate[predicates.size()])) : null;
platformOrder.setDealTime(new Date()); }
merchantOrderRepo.save(platformOrder); };
} Page<MerchantOrder> result = merchantOrderRepo.findAll(spec,
PageRequest.of(param.getPageNum() - 1, param.getPageSize(), Sort.by(Sort.Order.desc("submitTime"))));
/** PageResult<ReceiveOrderRecordVO> pageResult = new PageResult<>(
* 商户取消订单 ReceiveOrderRecordVO.convertFor(result.getContent()), param.getPageNum(), param.getPageSize(),
* result.getTotalElements());
* @param id return pageResult;
*/ }
@Transactional
public void merchatCancelOrder(@NotBlank String merchantId, @NotBlank String id) { /**
MerchantOrder platformOrder = merchantOrderRepo.getOne(id); * 取消订单
if (!merchantId.equals(platformOrder.getMerchantId())) { */
throw new BizException(BizError.无权取消订单); @Transactional
} public void cancelOrder(@NotBlank String id) {
if (!Constant.商户订单状态_等待接单.equals(platformOrder.getOrderState())) { MerchantOrder platformOrder = merchantOrderRepo.getOne(id);
throw new BizException(BizError.只有等待接单状态的商户订单才能取消); if (!Constant.商户订单状态_等待接单.equals(platformOrder.getOrderState())) {
} throw new BizException(BizError.只有等待接单状态的商户订单才能取消);
platformOrder.setOrderState(Constant.商户订单状态_商户取消订单); }
platformOrder.setDealTime(new Date()); platformOrder.setOrderState(Constant.商户订单状态_人工取消);
merchantOrderRepo.save(platformOrder); platformOrder.setDealTime(new Date());
} merchantOrderRepo.save(platformOrder);
}
@Transactional
public void orderTimeoutDeal() { /**
Date now = new Date(); * 商户取消订单
List<MerchantOrder> orders = merchantOrderRepo.findByOrderStateAndUsefulTimeLessThan(Constant.商户订单状态_等待接单, now); */
for (MerchantOrder order : orders) { @Transactional
order.setDealTime(now); public void merchatCancelOrder(@NotBlank String merchantId, @NotBlank String id) {
order.setOrderState(Constant.商户订单状态_超时取消); MerchantOrder platformOrder = merchantOrderRepo.getOne(id);
merchantOrderRepo.save(order); if (!merchantId.equals(platformOrder.getMerchantId())) {
} throw new BizException(BizError.无权取消订单);
} }
if (!Constant.商户订单状态_等待接单.equals(platformOrder.getOrderState())) {
@ParamValid throw new BizException(BizError.只有等待接单状态的商户订单才能取消);
@Transactional }
public StartOrderSuccessVO startOrder(StartOrderParam param) { platformOrder.setOrderState(Constant.商户订单状态_商户取消订单);
Merchant merchant = merchantRepo.findByMerchantNum(param.getMerchantNum()); platformOrder.setDealTime(new Date());
if (merchant == null) { merchantOrderRepo.save(platformOrder);
throw new BizException(BizError.商户未接入); }
}
boolean unknownPayTypeFlag = true; @Transactional
List<DictItemVO> payTypes = DictHolder.findDictItem("gatheringChannel"); public void orderTimeoutDeal() {
for (DictItemVO payType : payTypes) { Date now = new Date();
if (payType.getDictItemCode().equals(param.getPayType())) { List<MerchantOrder> orders = merchantOrderRepo.findByOrderStateAndUsefulTimeLessThan(Constant.商户订单状态_等待接单, now);
unknownPayTypeFlag = false; for (MerchantOrder order : orders) {
} order.setDealTime(now);
} order.setOrderState(Constant.商户订单状态_超时取消);
if (unknownPayTypeFlag) { merchantOrderRepo.save(order);
throw new BizException(BizError.不支持该支付类型); }
} }
String sign = param.getMerchantNum() + param.getOrderNo()
+ new DecimalFormat("###################.###########").format(param.getAmount()) + param.getNotifyUrl() @ParamValid
+ merchant.getSecretKey(); @Transactional
sign = new Digester(DigestAlgorithm.MD5).digestHex(sign); public StartOrderSuccessVO startOrder(StartOrderParam param) {
if (!sign.equals(param.getSign())) { Merchant merchant = merchantRepo.findByMerchantNum(param.getMerchantNum());
throw new BizException(BizError.签名不正确); if (merchant == null) {
} throw new BizException(BizError.商户未接入);
Integer orderEffectiveDuration = Constant.商户订单接单有效时长; }
ReceiveOrderSetting setting = platformOrderSettingRepo.findTopByOrderByLatelyUpdateTime(); boolean unknownPayTypeFlag = true;
if (setting != null) { List<DictItemVO> payTypes = DictHolder.findDictItem("gatheringChannel");
orderEffectiveDuration = setting.getReceiveOrderEffectiveDuration(); for (DictItemVO payType : payTypes) {
} if (payType.getDictItemCode().equals(param.getPayType())) {
MerchantOrder merchantOrder = param.convertToPo(merchant.getId(), orderEffectiveDuration); unknownPayTypeFlag = false;
MerchantOrderPayInfo payInfo = param.convertToPayInfoPo(merchantOrder.getId()); }
merchantOrder.setPayInfoId(payInfo.getId()); }
merchantOrderRepo.save(merchantOrder); if (unknownPayTypeFlag) {
merchantOrderPayInfoRepo.save(payInfo); throw new BizException(BizError.不支持该支付类型);
return StartOrderSuccessVO.convertFor(merchantOrder.getOrderNo()); }
} String sign = param.getMerchantNum() + param.getOrderNo()
+ new DecimalFormat("###################.###########").format(param.getAmount()) + param.getNotifyUrl()
/** + merchant.getSecretKey();
* 支付成功异步通知 sign = new Digester(DigestAlgorithm.MD5).digestHex(sign);
* if (!sign.equals(param.getSign())) {
* @param merchantOrderId throw new BizException(BizError.签名不正确);
*/ }
@Transactional Integer orderEffectiveDuration = Constant.商户订单接单有效时长;
public String paySuccessAsynNotice(@NotBlank String merchantOrderId) { ReceiveOrderSetting setting = platformOrderSettingRepo.findTopByOrderByLatelyUpdateTime();
MerchantOrderPayInfo payInfo = merchantOrderPayInfoRepo.findByMerchantOrderId(merchantOrderId); if (setting != null) {
if (Constant.商户订单支付通知状态_通知成功.equals(payInfo.getNoticeState())) { orderEffectiveDuration = setting.getReceiveOrderEffectiveDuration();
log.warn("商户订单支付已通知成功,无需重复通知;商户订单id为{}", merchantOrderId); }
return Constant.商户订单通知成功返回值; MerchantOrder merchantOrder = param.convertToPo(merchant.getId(), orderEffectiveDuration);
} MerchantOrderPayInfo payInfo = param.convertToPayInfoPo(merchantOrder.getId());
Merchant merchant = merchantRepo.findByMerchantNum(payInfo.getMerchantNum()); merchantOrder.setPayInfoId(payInfo.getId());
if (merchant == null) { merchantOrderRepo.save(merchantOrder);
throw new BizException(BizError.商户未接入); merchantOrderPayInfoRepo.save(payInfo);
}
//todo this is temporary code 这里要匹配有资源的用户接单
String sign = Constant.商户订单支付成功 + payInfo.getMerchantNum() + payInfo.getOrderNo() List<UserAccount> userAccounts = userAccountRepo.findAllByAccountType(Constant.账号类型_会员);
+ new DecimalFormat("###################.###########").format(payInfo.getAmount()) ;
+ merchant.getSecretKey(); this.receiveOrder(userAccounts.get(RandomUtil.randomInt(0, userAccounts.size())).getId(), merchantOrder.getId());
sign = new Digester(DigestAlgorithm.MD5).digestHex(sign);
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("merchantNum", payInfo.getMerchantNum()); return StartOrderSuccessVO.convertFor(merchantOrder.getOrderNo());
paramMap.put("orderNo", payInfo.getOrderNo()); }
paramMap.put("platformOrderNo", payInfo.getMerchantOrder().getOrderNo());
paramMap.put("amount", payInfo.getAmount()); /**
paramMap.put("attch", payInfo.getAttch()); * 支付成功异步通知
paramMap.put("state", Constant.商户订单支付成功); */
paramMap.put("payTime", @Transactional
DateUtil.format(payInfo.getMerchantOrder().getConfirmTime(), DatePattern.NORM_DATETIME_PATTERN)); public String paySuccessAsynNotice(@NotBlank String merchantOrderId) {
paramMap.put("sign", sign); MerchantOrderPayInfo payInfo = merchantOrderPayInfoRepo.findByMerchantOrderId(merchantOrderId);
String result = "fail"; if (Constant.商户订单支付通知状态_通知成功.equals(payInfo.getNoticeState())) {
// 通知3次 log.warn("商户订单支付已通知成功,无需重复通知;商户订单id为{}", merchantOrderId);
for (int i = 0; i < 3; i++) { return Constant.商户订单通知成功返回值;
try { }
result = HttpUtil.get(payInfo.getNotifyUrl(), paramMap, 2500); Merchant merchant = merchantRepo.findByMerchantNum(payInfo.getMerchantNum());
if (Constant.商户订单通知成功返回值.equals(result)) { if (merchant == null) {
break; throw new BizException(BizError.商户未接入);
} }
} catch (Exception e) {
result = e.getMessage(); String sign = Constant.商户订单支付成功 + payInfo.getMerchantNum() + payInfo.getOrderNo()
log.error(MessageFormat.format("商户订单支付成功异步通知地址请求异常,id为{0}", merchantOrderId), e); + new DecimalFormat("###################.###########").format(payInfo.getAmount())
} + merchant.getSecretKey();
} sign = new Digester(DigestAlgorithm.MD5).digestHex(sign);
payInfo.setNoticeState( Map<String, Object> paramMap = new HashMap<>();
Constant.商户订单通知成功返回值.equals(result) ? Constant.商户订单支付通知状态_通知成功 : Constant.商户订单支付通知状态_通知失败); paramMap.put("merchantNum", payInfo.getMerchantNum());
merchantOrderPayInfoRepo.save(payInfo); paramMap.put("orderNo", payInfo.getOrderNo());
return result; paramMap.put("platformOrderNo", payInfo.getMerchantOrder().getOrderNo());
} paramMap.put("amount", payInfo.getAmount());
paramMap.put("attch", payInfo.getAttch());
@Transactional(readOnly = true) paramMap.put("state", Constant.商户订单支付成功);
public PageResult<ReceiveOrderRecordVO> findLowerLevelAccountReceiveOrderRecordByPage( paramMap.put("payTime",
LowerLevelAccountReceiveOrderQueryCondParam param) { DateUtil.format(payInfo.getMerchantOrder().getConfirmTime(), DatePattern.NORM_DATETIME_PATTERN));
UserAccount currentAccount = userAccountRepo.getOne(param.getCurrentAccountId()); paramMap.put("sign", sign);
UserAccount lowerLevelAccount = currentAccount; String result = "fail";
if (StrUtil.isNotBlank(param.getUserName())) { // 通知3次
lowerLevelAccount = userAccountRepo.findByUserName(param.getUserName()); for (int i = 0; i < 3; i++) {
if (lowerLevelAccount == null) { try {
throw new BizException(BizError.用户名不存在); result = HttpUtil.get(payInfo.getNotifyUrl(), paramMap, 2500);
} if (Constant.商户订单通知成功返回值.equals(result)) {
// 说明该用户名对应的账号不是当前账号的下级账号 break;
if (!lowerLevelAccount.getAccountLevelPath().startsWith(currentAccount.getAccountLevelPath())) { }
throw new BizException(BizError.不是上级账号无权查看该账号及下级的接单记录); } catch (Exception e) {
} result = e.getMessage();
} log.error(MessageFormat.format("商户订单支付成功异步通知地址请求异常,id为{0}", merchantOrderId), e);
String lowerLevelAccountId = lowerLevelAccount.getId(); }
String lowerLevelAccountLevelPath = lowerLevelAccount.getAccountLevelPath(); }
payInfo.setNoticeState(
Specification<MerchantOrder> spec = new Specification<MerchantOrder>() { Constant.商户订单通知成功返回值.equals(result) ? Constant.商户订单支付通知状态_通知成功 : Constant.商户订单支付通知状态_通知失败);
/** merchantOrderPayInfoRepo.save(payInfo);
* return result;
*/ }
private static final long serialVersionUID = 1L;
@Transactional(readOnly = true)
public Predicate toPredicate(Root<MerchantOrder> root, CriteriaQuery<?> query, CriteriaBuilder builder) { public PageResult<ReceiveOrderRecordVO> findLowerLevelAccountReceiveOrderRecordByPage(
List<Predicate> predicates = new ArrayList<Predicate>(); LowerLevelAccountReceiveOrderQueryCondParam param) {
if (StrUtil.isNotBlank(param.getUserName())) { UserAccount currentAccount = userAccountRepo.getOne(param.getCurrentAccountId());
predicates.add(builder.equal(root.get("receivedAccountId"), lowerLevelAccountId)); UserAccount lowerLevelAccount = currentAccount;
} else { if (StrUtil.isNotBlank(param.getUserName())) {
predicates.add(builder.like(root.join("receivedAccount", JoinType.INNER).get("accountLevelPath"), lowerLevelAccount = userAccountRepo.findByUserName(param.getUserName());
lowerLevelAccountLevelPath + "%")); if (lowerLevelAccount == null) {
} throw new BizException(BizError.用户名不存在);
if (StrUtil.isNotBlank(param.getOrderState())) { }
predicates.add(builder.equal(root.get("orderState"), param.getOrderState())); // 说明该用户名对应的账号不是当前账号的下级账号
} if (!lowerLevelAccount.getAccountLevelPath().startsWith(currentAccount.getAccountLevelPath())) {
if (StrUtil.isNotBlank(param.getGatheringChannelCode())) { throw new BizException(BizError.不是上级账号无权查看该账号及下级的接单记录);
predicates.add(builder.equal(root.get("gatheringChannelCode"), param.getGatheringChannelCode())); }
} }
if (param.getStartTime() != null) { String lowerLevelAccountId = lowerLevelAccount.getId();
predicates.add(builder.greaterThanOrEqualTo(root.get("receivedTime").as(Date.class), String lowerLevelAccountLevelPath = lowerLevelAccount.getAccountLevelPath();
DateUtil.beginOfDay(param.getStartTime())));
} Specification<MerchantOrder> spec = new Specification<MerchantOrder>() {
if (param.getEndTime() != null) { /**
predicates.add(builder.lessThanOrEqualTo(root.get("receivedTime").as(Date.class), *
DateUtil.endOfDay(param.getEndTime()))); */
} private static final long serialVersionUID = 1L;
return predicates.size() > 0 ? builder.and(predicates.toArray(new Predicate[predicates.size()])) : null;
} public Predicate toPredicate(Root<MerchantOrder> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
}; List<Predicate> predicates = new ArrayList<Predicate>();
Page<MerchantOrder> result = merchantOrderRepo.findAll(spec, if (StrUtil.isNotBlank(param.getUserName())) {
PageRequest.of(param.getPageNum() - 1, param.getPageSize(), Sort.by(Sort.Order.desc("submitTime")))); predicates.add(builder.equal(root.get("receivedAccountId"), lowerLevelAccountId));
PageResult<ReceiveOrderRecordVO> pageResult = new PageResult<>( } else {
ReceiveOrderRecordVO.convertFor(result.getContent()), param.getPageNum(), param.getPageSize(), predicates.add(builder.like(root.join("receivedAccount", JoinType.INNER).get("accountLevelPath"),
result.getTotalElements()); lowerLevelAccountLevelPath + "%"));
return pageResult; }
} if (StrUtil.isNotBlank(param.getOrderState())) {
predicates.add(builder.equal(root.get("orderState"), param.getOrderState()));
}
if (StrUtil.isNotBlank(param.getGatheringChannelCode())) {
predicates.add(builder.equal(root.get("gatheringChannelCode"), param.getGatheringChannelCode()));
}
if (param.getStartTime() != null) {
predicates.add(builder.greaterThanOrEqualTo(root.get("receivedTime").as(Date.class),
DateUtil.beginOfDay(param.getStartTime())));
}
if (param.getEndTime() != null) {
predicates.add(builder.lessThanOrEqualTo(root.get("receivedTime").as(Date.class),
DateUtil.endOfDay(param.getEndTime())));
}
return predicates.size() > 0 ? builder.and(predicates.toArray(new Predicate[predicates.size()])) : null;
}
};
Page<MerchantOrder> result = merchantOrderRepo.findAll(spec,
PageRequest.of(param.getPageNum() - 1, param.getPageSize(), Sort.by(Sort.Order.desc("submitTime"))));
PageResult<ReceiveOrderRecordVO> pageResult = new PageResult<>(
ReceiveOrderRecordVO.convertFor(result.getContent()), param.getPageNum(), param.getPageSize(),
result.getTotalElements());
return pageResult;
}
} }
...@@ -8,6 +8,7 @@ import com.fasterxml.jackson.annotation.JsonFormat; ...@@ -8,6 +8,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import me.zohar.runscore.dictconfig.DictHolder; import me.zohar.runscore.dictconfig.DictHolder;
import me.zohar.runscore.gatheringcode.domain.GatheringCode;
import me.zohar.runscore.merchant.domain.MerchantOrder; import me.zohar.runscore.merchant.domain.MerchantOrder;
@Data @Data
...@@ -58,6 +59,8 @@ public class OrderGatheringCodeVO { ...@@ -58,6 +59,8 @@ public class OrderGatheringCodeVO {
private String gatheringCodeUrl; private String gatheringCodeUrl;
private GatheringCode gatheringCode;
/** /**
* 同步通知地址 * 同步通知地址
*/ */
...@@ -75,4 +78,5 @@ public class OrderGatheringCodeVO { ...@@ -75,4 +78,5 @@ public class OrderGatheringCodeVO {
return vo; return vo;
} }
} }
...@@ -32,6 +32,7 @@ public class LoginLog { ...@@ -32,6 +32,7 @@ public class LoginLog {
/** /**
* 登录系统 * 登录系统
*/ */
@Column(name="`system`")
private String system; private String system;
/** /**
......
...@@ -3,6 +3,8 @@ package me.zohar.runscore.useraccount.repo; ...@@ -3,6 +3,8 @@ package me.zohar.runscore.useraccount.repo;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.List;
import me.zohar.runscore.useraccount.domain.UserAccount; import me.zohar.runscore.useraccount.domain.UserAccount;
...@@ -12,4 +14,5 @@ public interface UserAccountRepo extends JpaRepository<UserAccount, String>, Jpa ...@@ -12,4 +14,5 @@ public interface UserAccountRepo extends JpaRepository<UserAccount, String>, Jpa
Long countByInviterId(String inviterId); Long countByInviterId(String inviterId);
List<UserAccount> findAllByAccountType(String accountType);
} }
...@@ -19,6 +19,11 @@ public class ApiController { ...@@ -19,6 +19,11 @@ public class ApiController {
@Autowired @Autowired
private MerchantOrderService platformOrderService; private MerchantOrderService platformOrderService;
/**
* 商户开单,获取支付方式,返回银行卡信息或者支付码信息
* @param param
* @return
*/
@PostMapping("/startOrder") @PostMapping("/startOrder")
@ResponseBody @ResponseBody
public Result startOrder(StartOrderParam param) { public Result startOrder(StartOrderParam param) {
......
...@@ -15,11 +15,12 @@ public class StartOrderTest { ...@@ -15,11 +15,12 @@ public class StartOrderTest {
*/ */
public static void main(String[] args) { public static void main(String[] args) {
String merchantNum = "201906001"; String merchantNum = "1001";
String merchantOrderNo = "20190629023134U936283877"; String merchantOrderNo = "20190629023134U936283878";
Double amount = 100d; Double amount = 100d;
String notifyUrl = "http://xhbc10.com/index.php/Pay/Paynotify"; String notifyUrl = "http://xhbc10.com/index.php/Pay/Paynotify";
String secretKey = "l54x9426o68962464"; //String returnUrl = "http://xhbc10.com/index.php/Pay/Paynotify";
String secretKey = "456";
String sign = merchantNum + merchantOrderNo String sign = merchantNum + merchantOrderNo
+ new DecimalFormat("###################.###########").format(amount) + notifyUrl + secretKey; + new DecimalFormat("###################.###########").format(amount) + notifyUrl + secretKey;
System.out.println(sign); System.out.println(sign);
......
...@@ -135,9 +135,12 @@ var gatheringCodeVM = new Vue({ ...@@ -135,9 +135,12 @@ var gatheringCodeVM = new Vue({
that.editGatheringCode = { that.editGatheringCode = {
gatheringChannelCode : '', gatheringChannelCode : '',
state : '', state : '',
fixedGatheringAmount : true, fixedGatheringAmount : false,
gatheringAmount : '', gatheringAmount : '',
payee : '' payee : '',
bankAddress:'',
bankCode:'',
bankUsername:''
}; };
that.showEditGatheringCodePageInner(); that.showEditGatheringCodePageInner();
that.initFileUploadWidget(); that.initFileUploadWidget();
...@@ -187,24 +190,24 @@ var gatheringCodeVM = new Vue({ ...@@ -187,24 +190,24 @@ var gatheringCodeVM = new Vue({
}); });
return; return;
} }
if (editGatheringCode.fixedGatheringAmount == null) { // if (editGatheringCode.fixedGatheringAmount == null) {
layer.alert('请选择是否固定收款金额', { // layer.alert('请选择是否固定收款金额', {
title : '提示', // title : '提示',
icon : 7, // icon : 7,
time : 3000 // time : 3000
}); // });
return; // return;
} // }
if (editGatheringCode.fixedGatheringAmount) { // if (editGatheringCode.fixedGatheringAmount) {
if (editGatheringCode.gatheringAmount == null || editGatheringCode.gatheringAmount == '') { // if (editGatheringCode.gatheringAmount == null || editGatheringCode.gatheringAmount == '') {
layer.alert('请输入收款金额', { // layer.alert('请输入收款金额', {
title : '提示', // title : '提示',
icon : 7, // icon : 7,
time : 3000 // time : 3000
}); // });
return; // return;
} // }
} // }
if (editGatheringCode.payee == null || editGatheringCode.payee == '') { if (editGatheringCode.payee == null || editGatheringCode.payee == '') {
layer.alert('请选择收款人', { layer.alert('请选择收款人', {
title : '提示', title : '提示',
...@@ -214,11 +217,12 @@ var gatheringCodeVM = new Vue({ ...@@ -214,11 +217,12 @@ var gatheringCodeVM = new Vue({
return; return;
} }
if ($('.gathering-code-pic').fileinput('getPreview').content.length != 0) { if ($('.gathering-code-pic').fileinput('getPreview').content.length != 0 || editGatheringCode.gatheringChannelCode =='bankcard') {
that.addOrUpdateGatheringCodeInner(); that.addOrUpdateGatheringCodeInner();
} else { } else {
var filesCount = $('.gathering-code-pic').fileinput('getFilesCount'); var filesCount = $('.gathering-code-pic').fileinput('getFilesCount');
if (filesCount == 0) { console.log(editGatheringCode.gatheringChannelCode);
if (filesCount == 0 ) {
layer.alert('请选择要上传的图片', { layer.alert('请选择要上传的图片', {
title : '提示', title : '提示',
icon : 7, icon : 7,
......
<!DOCTYPE html> <!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"> <html xmlns:th="http://www.thymeleaf.org">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>收款码</title> <title>收款码</title>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/css/bootstrap.min.css"> <link rel="stylesheet"
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script> href="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/popper.js/1.12.5/umd/popper.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/js/bootstrap.min.js"></script> <script src="https://cdn.staticfile.org/popper.js/1.12.5/umd/popper.min.js"></script>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script> <script src="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/js/bootstrap.min.js"></script>
<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script> <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<script src="https://cdn.bootcss.com/dayjs/1.7.8/dayjs.min.js"></script> <script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
<script src="https://cdn.bootcss.com/layer/2.3/layer.js"></script> <script src="https://cdn.bootcss.com/dayjs/1.7.8/dayjs.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/5.0.1/css/fileinput.min.css" media="all" rel="stylesheet" type="text/css" /> <script src="https://cdn.bootcss.com/layer/2.3/layer.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/5.0.1/js/fileinput.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/5.0.1/css/fileinput.min.css"
<script src="/js/common/common.js"></script> media="all" rel="stylesheet" type="text/css"/>
<link href="/css/common/common.css" rel="stylesheet" type="text/css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/5.0.1/js/fileinput.min.js"></script>
<style type="text/css"> <script src="/js/common/common.js"></script>
.account-change { <link href="/css/common/common.css" rel="stylesheet" type="text/css">
background-color: #fff;; <style type="text/css">
margin-bottom: 1rem; .account-change {
display: flex; background-color: #fff;;
padding-left: 1.2rem; margin-bottom: 1rem;
padding-right: 0.2rem; display: flex;
padding-top: 0.5rem; padding-left: 1.2rem;
padding-bottom: 0.5rem; padding-right: 0.2rem;
} padding-top: 0.5rem;
padding-bottom: 0.5rem;
}
.account-change-body { .account-change-body {
flex: 4; flex: 4;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.account-change-body-item label { .account-change-body-item label {
text-align: end; text-align: end;
width: 5rem; width: 5rem;
margin-right: 0.5rem; margin-right: 0.5rem;
} }
.account-change-body-item span { .account-change-body-item span {
min-width: 5rem; min-width: 5rem;
display: inline-block; display: inline-block;
} }
.account-change-body-item button { .account-change-body-item button {
width: 48%; width: 48%;
} }
.account-change-body-item-highlight { .account-change-body-item-highlight {
color: #c3606a; color: #c3606a;
} }
.page-link { .page-link {
color: #007bff !important color: #007bff !important
} }
</style> </style>
</head> </head>
<body> <body>
<div th:replace="common/header::html"></div> <div th:replace="common/header::html"></div>
<div id="gatheringCode" v-cloak> <div id="gatheringCode" v-cloak>
<div class="page-body" style="background: #f2f2f2;" v-show="showGatheringCodeFlag"> <div class="page-body" style="background: #f2f2f2;" v-show="showGatheringCodeFlag">
<button type="button" style="margin-top: 0.3rem;" class="btn btn-outline-info btn-lg btn-block" v-on:click="showEditGatheringCodePage()">添加收款码</button> <button type="button" style="margin-top: 0.3rem;"
<div class="input-group" style="padding-bottom: 0.3rem; padding-top: 0.3rem;"> class="btn btn-outline-info btn-lg btn-block"
<select class="form-control" style="width: 2.2rem; height: 3rem;" v-model="state"> v-on:click="showEditGatheringCodePage()">添加收款码
<option value="">状态</option> </button>
<option v-for="dictItem in gatheringCodeStateDictItems" :value="dictItem.dictItemCode">{{dictItem.dictItemName}}</option> <div class="input-group" style="padding-bottom: 0.3rem; padding-top: 0.3rem;">
</select> <select class="form-control" style="width: 6.2rem; height: 3rem;" v-model="gatheringChannelCode"> <select class="form-control" style="width: 2.2rem; height: 3rem;" v-model="state">
<option value="">收款渠道</option> <option value="">状态</option>
<option v-for="dictItem in gatheringChannelDictItems" :value="dictItem.dictItemCode">{{dictItem.dictItemName}}</option> <option v-for="dictItem in gatheringCodeStateDictItems"
</select> :value="dictItem.dictItemCode">{{dictItem.dictItemName}}
<div class="input-group-append"> </option>
<button class="btn btn-outline-secondary" type="button" v-on:click="query">查询</button> </select> <select class="form-control" style="width: 6.2rem; height: 3rem;"
</div> v-model="gatheringChannelCode">
</div> <option value="">收款渠道</option>
<div class="account-change" v-for="gatheringCode in gatheringCodes"> <option v-for="dictItem in gatheringChannelDictItems" :value="dictItem.dictItemCode">
<div class="account-change-body"> {{dictItem.dictItemName}}
<div class="account-change-body-item"> </option>
<label>创建时间:</label> <span>{{gatheringCode.createTime}}</span> </select>
</div> <div class="input-group-append">
<div class="account-change-body-item"> <button class="btn btn-outline-secondary" type="button" v-on:click="query">查询
<label>收款渠道:</label> <span>{{gatheringCode.gatheringChannelName}}</span><label>状态:</label> <span>{{gatheringCode.stateName}}</span> </button>
</div> </div>
<div class="account-change-body-item"> </div>
<label> 收款金额: </label> <span class="account-change-body-item-highlight">{{gatheringCode.fixedGatheringAmount ? gatheringCode.gatheringAmount + '元' : '不固定'}}</span><label>收款人:</label> <span class="account-change-body-item-highlight">{{gatheringCode.payee}}</span> <div class="account-change" v-for="gatheringCode in gatheringCodes">
</div> <div class="account-change-body">
<div class="account-change-body-item"> <div class="account-change-body-item">
<button class="btn btn-outline-info btn-lg" type="button" v-on:click="showEditGatheringCodePage(gatheringCode.id)">编辑</button> <label>创建时间:</label> <span>{{gatheringCode.createTime}}</span>
<button class="btn btn-outline-danger btn-lg" type="button" v-on:click="delGatheringCode(gatheringCode.id)">删除</button> </div>
</div> <div class="account-change-body-item">
</div> <label>收款渠道:</label> <span>{{gatheringCode.gatheringChannelName}}</span><label>状态:</label>
</div> <span>{{gatheringCode.stateName}}</span>
<div style="padding-left: 13rem;"> </div>
<ul class="pagination"> <div class="account-change-body-item">
<li class="page-item"><a class="page-link" v-show="totalPage > 0 && pageNum > 1" v-on:click="prePage">上一页</a></li> <label> 收款金额: </label> <span class="account-change-body-item-highlight">{{gatheringCode.fixedGatheringAmount ? gatheringCode.gatheringAmount + '元' : '不固定'}}</span><label>收款人:</label>
<li class="page-item"><a class="page-link" v-show="pageNum >= 1 && pageNum < totalPage" v-on:click="nextPage">下一页</a></li> <span class="account-change-body-item-highlight">{{gatheringCode.payee}}</span>
</ul> </div>
</div> <div class="account-change-body-item">
</div> <button class="btn btn-outline-info btn-lg" type="button"
<div class="page-body" style="background: #f2f2f2;" v-show="showEditGatheringCodeFlag"> v-on:click="showEditGatheringCodePage(gatheringCode.id)">编辑
<div class="container" style="margin-top: 1.3rem;"> </button>
<form> <button class="btn btn-outline-danger btn-lg" type="button"
<div class="form-group"> v-on:click="delGatheringCode(gatheringCode.id)">删除
<label>收款渠道:</label> <select class="form-control" v-model="editGatheringCode.gatheringChannelCode" @change="alert(editGatheringCode.gatheringChannelCode);"> </button>
<option value="">请选择</option> </div>
<option v-for="dictItem in gatheringChannelDictItems" :value="dictItem.dictItemCode">{{dictItem.dictItemName}}</option> </div>
</select> </div>
</div> <div style="padding-left: 13rem;">
<div class="form-group"> <ul class="pagination">
<label>状态:</label> <select class="form-control" v-model="editGatheringCode.state"> <li class="page-item"><a class="page-link" v-show="totalPage > 0 && pageNum > 1"
<option value="">请选择</option> v-on:click="prePage">上一页</a></li>
<option v-for="dictItem in gatheringCodeStateDictItems" :value="dictItem.dictItemCode">{{dictItem.dictItemName}}</option> <li class="page-item"><a class="page-link"
</select> v-show="pageNum >= 1 && pageNum < totalPage"
</div> v-on:click="nextPage">下一页</a></li>
<!--<div class="form-group"> </ul>
<label> <span> 收款金额:</span> </div>
<div class="custom-control custom-checkbox custom-control-inline" v-on:click="switchGatheringAmountMode"> </div>
<input type="checkbox" id="fixedGatheringAmount" class="custom-control-input" v-model="editGatheringCode.fixedGatheringAmount"> <div class="page-body" style="background: #f2f2f2;" v-show="showEditGatheringCodeFlag">
<label for="fixedGatheringAmount" class="custom-control-label">固定收款金额</label> <div class="container" style="margin-top: 1.3rem;">
</div> <form>
</label> <input type="number" class="form-control" v-model="editGatheringCode.gatheringAmount" :disabled="!editGatheringCode.fixedGatheringAmount"> <div class="form-group">
</div>--> <label>收款渠道:</label> <select class="form-control"
<div class="form-group"> v-model="editGatheringCode.gatheringChannelCode">
<label>收款人:</label> <input type="text" class="form-control" v-model="editGatheringCode.payee"> <option value="">请选择</option>
</div> <option v-for="dictItem in gatheringChannelDictItems"
<div class="form-group" v-show="editGatheringCode.gatheringChannelCode == 'bankcard'" style=""><label>银行卡号:</label> <input type="text" class="form-control"> <label>开户行:</label> <input type="text" class="form-control"> <label>卡姓名:</label> <input type="text" class="form-control"></div> :value="dictItem.dictItemCode">{{dictItem.dictItemName}}
<div class="form-group" v-show="editGatheringCode.gatheringChannelCode != 'bankcard'"> </option>
<label>收款码:</label> <input type="file" class="form-control gathering-code-pic"> </select>
</div> </div>
<button type="button" class="btn btn-danger btn-lg btn-block" v-on:click="addOrUpdateGatheringCode">保存</button> <div class="form-group">
<button type="button" class="btn btn-light btn-lg btn-block" v-on:click="hideEditGatheringCodePage">返回</button> <label>状态:</label> <select class="form-control"
</form> v-model="editGatheringCode.state">
<option value="">请选择</option>
<option v-for="dictItem in gatheringCodeStateDictItems"
:value="dictItem.dictItemCode">{{dictItem.dictItemName}}
</option>
</select>
</div>
<!--<div class="form-group">
<label> <span> 收款金额:</span>
<div class="custom-control custom-checkbox custom-control-inline" v-on:click="switchGatheringAmountMode">
<input type="checkbox" id="fixedGatheringAmount" class="custom-control-input" v-model="editGatheringCode.fixedGatheringAmount">
<label for="fixedGatheringAmount" class="custom-control-label">固定收款金额</label>
</div>
</label> <input type="number" class="form-control" v-model="editGatheringCode.gatheringAmount" :disabled="!editGatheringCode.fixedGatheringAmount">
</div>-->
<div class="form-group">
<label>收款人:</label> <input type="text" class="form-control"
v-model="editGatheringCode.payee">
</div>
<div class="form-group"
v-show="editGatheringCode.gatheringChannelCode == 'bankcard'" style="">
<label>银行卡号:</label>
<input type="text" class="form-control" v-model="editGatheringCode.bankCode">
<label>开户行:</label>
<input type="text" class="form-control" v-model="editGatheringCode.bankAddress">
<label>卡户主:</label>
<input type="text" class="form-control" v-model="editGatheringCode.bankUsername">
</div>
<div class="form-group"
v-show="editGatheringCode.gatheringChannelCode != 'bankcard'">
<label>收款码:</label> <input type="file" class="form-control gathering-code-pic">
</div>
<button type="button" class="btn btn-danger btn-lg btn-block"
v-on:click="addOrUpdateGatheringCode">保存
</button>
<button type="button" class="btn btn-light btn-lg btn-block"
v-on:click="hideEditGatheringCodePage">返回
</button>
</form>
</div> </div>
</div> </div>
</div> </div>
<div th:replace="common/footer::html"></div> <div th:replace="common/footer::html"></div>
<script type="text/javascript" src="/js/gathering-code.js"></script> <script type="text/javascript" src="/js/gathering-code.js"></script>
</body> </body>
</html> </html>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论