Commit 8dfa0c1e authored by shiyu's avatar shiyu

保证金缴纳

parent e9b58bb7
......@@ -48,6 +48,11 @@ public interface CommConsts {
*/
public static final String AUCTION_LOCK_KEY_PRE = "AUCTION:OFFER:";
/**
* 拍卖保证金额度更新的锁
*/
public static final String EARNEST_ACCOUNT_LOCK = "EARNEST:ACCOUNT:";
public static final Long SYSTEM_ACCOUNT = 8888888888L;
......@@ -156,6 +161,12 @@ public interface CommConsts {
public final static String EARNEST_REBATE = "0.05";
/**
* 每个用户赠送50元初始保证金额度
*/
public final static Long GIFT_EARNEST_AMOUNT = 5000L;
/**
* 平台收货地址
*/
......
......@@ -12,6 +12,7 @@ public interface EarnestOrderDao {
*/
boolean insert(EarnestOrder earnestOrder);
boolean update(EarnestOrder earnestOrder);
EarnestOrder findByOrderId(String orderId);
}
package com.wwdz.ch.db.domain.openShop;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import com.xxdxxs.entity.Entity;
import lombok.Data;
/**
......@@ -11,7 +11,7 @@ import lombok.Data;
* @date 2024/11/06
*/
@Data
public class UserAccount implements Serializable {
public class UserAccount implements Entity {
private Long id;
/**
......
......@@ -19,6 +19,13 @@ public class EarnestOrderDaoImpl implements EarnestOrderDao {
return earnestOrderMapper.insert(earnestOrder) > 0;
}
@Override
public boolean update(EarnestOrder earnestOrder) {
EarnestOrderExample example = new EarnestOrderExample();
EarnestOrderExample.Criteria criteria = example.createCriteria();
criteria.andEarnestOrderIdEqualTo(earnestOrder.getEarnestOrderId());
return earnestOrderMapper.updateByExampleSelective(earnestOrder, example) > 0;
}
@Override
public EarnestOrder findByOrderId(String orderId) {
......
......@@ -28,6 +28,7 @@ public class EarnestRecordDaoImpl implements EarnestRecordDao {
EarnestRecordExample.Criteria criteria = example.createCriteria();
criteria.andUserIdEqualTo(earnestRecord.getUserId());
criteria.andItemIdEqualTo(earnestRecord.getItemId());
JdbcHelper.ifPresent(earnestRecord.getType(), criteria::andTypeEqualTo);
return earnestRecordMapper.updateByExampleSelective(earnestRecord, example) > 0;
}
......
......@@ -2,11 +2,14 @@ package com.wwdz.ch.db.impl.openShop;
import com.wwdz.ch.db.dao.openShop.UserAccountDao;
import com.wwdz.ch.db.domain.openShop.UserAccount;
import com.wwdz.ch.db.domain.openShop.UserAccountExample;
import com.wwdz.ch.db.mapper.UserMapper;
import com.wwdz.ch.db.mapper.openShop.UserAccountMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.Date;
@Repository
public class UserAccountDaoImpl implements UserAccountDao {
......@@ -21,7 +24,11 @@ public class UserAccountDaoImpl implements UserAccountDao {
@Override
public boolean update(UserAccount userAccount) {
return false;
UserAccountExample example = new UserAccountExample();
UserAccountExample.Criteria criteria = example.createCriteria();
criteria.andUserIdEqualTo(userAccount.getUserId());
userAccount.setUpdateTime(new Date());
return userAccountMapper.updateByExampleSelective(userAccount, example) > 0;
}
@Override
......
......@@ -3,8 +3,11 @@ package com.wwdz.ch.db.mapper.openShop;
import com.wwdz.ch.db.domain.openShop.UserAccount;
import com.wwdz.ch.db.domain.openShop.UserAccountExample;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface UserAccountMapper {
long countByExample(UserAccountExample example);
......
......@@ -18,14 +18,10 @@ import com.wwdz.ch.core.util.RedisUtils;
import com.wwdz.ch.core.util.TimeUtil;
import com.wwdz.ch.db.dao.CollectorWhiteListDao;
import com.wwdz.ch.db.dao.distribution.*;
import com.wwdz.ch.db.dao.openShop.GuaranteeMoneyRecordDao;
import com.wwdz.ch.db.dao.openShop.OpenShopApplyOrderDao;
import com.wwdz.ch.db.dao.openShop.OpenShopCostRecordDao;
import com.wwdz.ch.db.dao.openShop.*;
import com.wwdz.ch.db.domain.CollectorWhiteList;
import com.wwdz.ch.db.domain.distribution.*;
import com.wwdz.ch.db.domain.openShop.GuaranteeMoneyRecord;
import com.wwdz.ch.db.domain.openShop.OpenShopApplyOrder;
import com.wwdz.ch.db.domain.openShop.OpenShopCostRecord;
import com.wwdz.ch.db.domain.openShop.*;
import com.wwdz.ch.db.dto.request.distribution.DistributionOrderRequestDto;
import com.wwdz.ch.core.entity.DistributionOrderNoticeMsg;
import com.wwdz.ch.core.entity.PayNoticeMsg;
......@@ -35,6 +31,8 @@ import com.wwdz.ch.wx.service.distribution.*;
import com.xxdxxs.utils.DateUtils;
import com.xxdxxs.utils.JsonUtils;
import com.xxdxxs.utils.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -56,6 +54,7 @@ import java.time.temporal.TemporalUnit;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* 微信支付回调通知
......@@ -138,6 +137,15 @@ public class WxPayCallbackController {
@Autowired
CollectorWhiteListDao collectorWhiteListDao;
@Autowired
EarnestOrderDao earnestOrderDao;
@Autowired
UserAccountDao userAccountDao;
@Autowired
RedissonClient redissonClient;
@RequestMapping(value ="/getPayNotify")
public String payNotify(HttpServletRequest request) throws IOException {
logger.info("------------------ 收到微信支付回调通知 ------------------");
......@@ -201,7 +209,11 @@ public class WxPayCallbackController {
} else if (systemOrderId.startsWith(CommConsts.GUARANTEE_MONEY_ORDER_PREFIX)) {
//质保金缴纳订单
handleOrderOfGuaranteeMoney(transaction);
} else if (systemOrderId.startsWith(CommConsts.DISTRIBUTION_ORDER_PREFIX)) {
} else if (systemOrderId.startsWith(CommConsts.AUCTION_EARNEST_ORDER_PREFIX)) {
//拍卖保证金缴纳订单
handleOrderOfEarnest(transaction);
}
else if (systemOrderId.startsWith(CommConsts.DISTRIBUTION_ORDER_PREFIX)) {
//查询系统中订单现在的状态,避免重复更新
DistributionOrder distributionOrder = distributionOrderDao.findById(systemOrderId);
if (distributionOrder.getState() == DistributionEnum.DistributionOrderStateEnum.PRE_PAY.getCode()) {
......@@ -631,6 +643,58 @@ public class WxPayCallbackController {
return Result.failed();
}
/**
* 拍卖保证金订单回调
* @param transaction
* @return
*/
public Result handleOrderOfEarnest(Transaction transaction) {
//商户订单号,分销订单号
String systemOrderId = transaction.getOutTradeNo();
//微信支付交易id
String transactionId = transaction.getTransactionId();
//支付成功时间
String payTime = transaction.getSuccessTime();
EarnestOrder oldEarnestOrder = earnestOrderDao.findByOrderId(systemOrderId);
long userId = oldEarnestOrder.getUserId();
long amount = oldEarnestOrder.getAmount();
String lockKey = CommConsts.EARNEST_ACCOUNT_LOCK + userId;
RLock lock = redissonClient.getLock(lockKey);
try {
if (!lock.tryLock(5, 5, TimeUnit.SECONDS)) {
return Result.failed("未获取到锁");
}
//支付成功,更新订单状态为待发货
EarnestOrder earnestOrder = new EarnestOrder();
earnestOrder.setEarnestOrderId(systemOrderId);
earnestOrder.setTransactionId(transactionId);
earnestOrder.setPayTime(TimeUtil.wxTimeConvertToDate(payTime));
earnestOrder.setState(EarnestEnum.EarnestOrderStateEnum.PAYED.getCode());
earnestOrder.setUpdateTime(new Date());
earnestOrderDao.update(earnestOrder);
//用户账户,更新保证金额度
UserAccount userAccount = userAccountDao.findByUserId(userId);
long earnestUsableAmount = userAccount.getEarnestUsableAmount();
long newEarnestUsableAmount = earnestUsableAmount + amount;
UserAccount newUserAccount = new UserAccount();
newUserAccount.setUserId(userId);
newUserAccount.setEarnestAmount(userAccount.getEarnestAmount() + amount);
newUserAccount.setEarnestUsableAmount(newEarnestUsableAmount);
userAccountDao.update(newUserAccount);
logger.info(">>>>>>>>>>>> 拍卖保证金订单,微信支付回调通知处理成功 <<<<<<<<<<<<");
return Result.success();
} catch (Exception e) {
logger.error(">>>>>>>>>>>> 拍卖保证金订单,微信支付回调通知处理失败 error :{}", e);
} finally {
if (lock != null && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
return Result.failed();
}
/**
* 获取请求体
......
......@@ -16,6 +16,8 @@ import com.wwdz.ch.db.dto.request.distribution.DistributionOrderRequestDto;
import com.wwdz.ch.db.dto.request.openShop.EarnestOrderRequestDto;
import com.wwdz.ch.db.dto.request.openShop.EarnestRecordRequestDto;
import com.wwdz.ch.wx.service.openShop.AuctionEarnestService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -25,6 +27,7 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.math.BigDecimal;
import java.util.Date;
import java.util.concurrent.TimeUnit;
@Service
public class AuctionEarnestServiceImpl implements AuctionEarnestService {
......@@ -43,6 +46,9 @@ public class AuctionEarnestServiceImpl implements AuctionEarnestService {
@Autowired
UserAccountDao userAccountDao;
@Autowired
RedissonClient redissonClient;
@Override
public Result payEarnest(EarnestOrderRequestDto dto) {
try {
......@@ -87,15 +93,31 @@ public class AuctionEarnestServiceImpl implements AuctionEarnestService {
}
@Override
public Result checkEnoughEarnest(EarnestRecordRequestDto dto) {
try {
return Result.success();
} catch (Exception e) {
logger.error("检查是否有足够的保证金失败 error : {}", e);
}
return Result.failed();
}
@Transactional
@Override
public Result occupyEarnest(EarnestRecordRequestDto dto) {
String lockKey = CommConsts.EARNEST_ACCOUNT_LOCK + dto.getUserId();
RLock lock = redissonClient.getLock(lockKey);
try {
if (!lock.tryLock(5, 5, TimeUnit.SECONDS)) {
return Result.failed("操作过快,稍后再试");
}
EarnestRecord earnestRecord = new EarnestRecord();
long auctionPrice = dto.getAuctionPrice();
BigDecimal earnestAmount = new BigDecimal(String.valueOf(auctionPrice)).multiply(new BigDecimal(CommConsts.EARNEST_REBATE));
//换算成对应占用的保证金
long occupyAmount = earnestAmount.longValue();
earnestRecord.setUserId(dto.getUserId());
earnestRecord.setAmount(earnestAmount.longValue());
earnestRecord.setItemId(dto.getItemId());
earnestRecord.setSpecialPerformanceId(dto.getSpecialPerformanceId());
......@@ -106,26 +128,75 @@ public class AuctionEarnestServiceImpl implements AuctionEarnestService {
earnestRecord.setState(EarnestEnum.StateEnum.VALID.getCode());
earnestRecordDao.insert(earnestRecord);
//用户账户,更新保证金额度
UserAccount userAccount = new UserAccount();
userAccount.setUserId(dto.getUserId());
UserAccount userAccount = userAccountDao.findByUserId(dto.getUserId());
long earnestUsableAmount = userAccount.getEarnestUsableAmount();
long newEarnestUsableAmount = earnestUsableAmount - occupyAmount;
UserAccount newUserAccount = new UserAccount();
newUserAccount.setUserId(dto.getUserId());
newUserAccount.setEarnestUsableAmount(newEarnestUsableAmount);
userAccountDao.update(newUserAccount);
return Result.success();
} catch (Exception e) {
logger.error("占用保证金失败 error : {}", e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
} finally {
if (lock != null && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
return Result.failed();
}
@Transactional
@Override
public Result releaseEarnest(EarnestRecordRequestDto dto) {
String itemIdKey = CommConsts.EARNEST_ACCOUNT_LOCK + dto.getUserId();
RLock lock = redissonClient.getLock(itemIdKey);
try {
if (!lock.tryLock(5, 5, TimeUnit.SECONDS)) {
return Result.failed("操作过快,稍后再试");
}
long auctionPrice = dto.getAuctionPrice();
BigDecimal earnestAmount = new BigDecimal(String.valueOf(auctionPrice)).multiply(new BigDecimal(CommConsts.EARNEST_REBATE));
//换算成对应占用的保证金
long occupyAmount = earnestAmount.longValue();
EarnestRecord earnestRecord = new EarnestRecord();
earnestRecord.setUserId(dto.getUserId());
earnestRecord.setAmount(earnestAmount.longValue());
earnestRecord.setItemId(dto.getItemId());
earnestRecord.setSpecialPerformanceId(dto.getSpecialPerformanceId());
earnestRecord.setEntryType(EarnestEnum.EntryEnum.INCREASE.getCode());
earnestRecord.setCreateTime(new Date());
earnestRecord.setUpdateTime(new Date());
earnestRecord.setType(EarnestEnum.TypeEnum.RELEASE.getCode());
earnestRecord.setState(EarnestEnum.StateEnum.VALID.getCode());
earnestRecordDao.insert(earnestRecord);
//把上一次的占用记录状态更改为已释放
EarnestRecord newEarnestRecord = new EarnestRecord();
newEarnestRecord.setUserId(dto.getUserId());
newEarnestRecord.setItemId(dto.getItemId());
newEarnestRecord.setType(EarnestEnum.TypeEnum.OCCUPY.getCode());
earnestRecordDao.update(newEarnestRecord);
//更新用户账户,更新保证金额度
UserAccount userAccount = userAccountDao.findByUserId(dto.getUserId());
long earnestUsableAmount = userAccount.getEarnestUsableAmount();
long newEarnestUsableAmount = earnestUsableAmount + occupyAmount;
UserAccount newUserAccount = new UserAccount();
newUserAccount.setUserId(dto.getUserId());
newUserAccount.setEarnestUsableAmount(newEarnestUsableAmount);
userAccountDao.update(newUserAccount);
return Result.success();
} catch (Exception e) {
logger.error("释放保证金失败 error : {}", e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
} finally {
if (lock != null && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
return Result.failed();
}
......
......@@ -21,6 +21,13 @@ public interface AuctionEarnestService {
*/
Result getPayParam(EarnestOrderRequestDto dto);
/**
* 检查是否有足够的保证金出价
* @param dto
* @return
*/
Result checkEnoughEarnest(EarnestRecordRequestDto dto);
/**
* 占用保证金
* @return
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment