Commit 8e58abbb authored by shiyu's avatar shiyu

扣减库存

parent 7b0a912f
......@@ -24,4 +24,15 @@ public interface SupplierItemDao {
* @return
*/
SupplierItem findById(long itemId);
int update(SupplierItem supplierItem);
/**
* 更新库存
* @param itemId
* @param stock
* @return
*/
int updateStock(long itemId, int stock);
}
......@@ -10,7 +10,10 @@ import com.xxdxxs.db.component.JdbcHelper;
import com.xxdxxs.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Repository
public class SupplierItemDaoImpl implements SupplierItemDao {
......@@ -39,4 +42,24 @@ public class SupplierItemDaoImpl implements SupplierItemDao {
criteria.andIdEqualTo(itemId);
return supplierItemMapper.selectOneByExampleWithBLOBs(supplierItemExample);
}
@Override
public int update(SupplierItem supplierItem) {
supplierItem.setUpdateTime(new Date());
SupplierItemExample supplierItemExample = new SupplierItemExample();
SupplierItemExample.Criteria criteria = supplierItemExample.createCriteria();
criteria.andIdEqualTo(supplierItem.getId());
return supplierItemMapper.updateByExampleSelective(supplierItem, supplierItemExample);
}
@Override
public int updateStock(long itemId, int stock) {
SupplierItem supplierItem = new SupplierItem();
supplierItem.setUpdateTime(new Date());
supplierItem.setStock(stock);
SupplierItemExample supplierItemExample = new SupplierItemExample();
SupplierItemExample.Criteria criteria = supplierItemExample.createCriteria();
criteria.andIdEqualTo(supplierItem.getId());
return supplierItemMapper.updateByExampleSelective(supplierItem, supplierItemExample);
}
}
......@@ -10,12 +10,19 @@ import com.wwdz.ch.core.type.Result;
import com.wwdz.ch.core.util.RedisUtils;
import com.wwdz.ch.core.util.TimeUtil;
import com.wwdz.ch.db.dao.distribution.DistributionOrderDao;
import com.wwdz.ch.db.dao.distribution.DistributorProfitDao;
import com.wwdz.ch.db.dao.distribution.SupplierItemDao;
import com.wwdz.ch.db.domain.distribution.DistributionOrder;
import com.wwdz.ch.db.domain.distribution.DistributorProfit;
import com.wwdz.ch.db.domain.distribution.SupplierItem;
import com.wwdz.ch.db.dto.request.distribution.DistributionOrderRequestDto;
import com.wwdz.ch.wx.service.distribution.SupplierItemService;
import com.xxdxxs.utils.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
......@@ -24,6 +31,7 @@ import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
......@@ -48,6 +56,15 @@ public class WxPayCallbackController {
@Autowired
WxPayServiceApi wxPayServiceApi;
@Autowired
DistributorProfitDao distributorProfitDao;
@Autowired
SupplierItemDao supplierItemDao;
@Autowired
SupplierItemService supplierItemService;
@RequestMapping(value ="/getPayNotify")
public synchronized String payNotify(HttpServletRequest request) throws IOException {
logger.info("------------------ 收到微信支付回调通知 ------------------");
......@@ -107,6 +124,32 @@ public class WxPayCallbackController {
//查询系统中订单现在的状态,避免重复更新
DistributionOrder distributionOrder = distributionOrderDao.findById(distributionOrderId);
if (distributionOrder.getState() == DistributionEnum.DistributionOrderStateEnum.PRE_PAY.getCode()) {
Result updateResult = updateOrderStateAndInsertProfit(transaction);
if (!updateResult.getSuccess()) {
return JsonUtils.from(returnMap);
}
}
}
returnMap.put("code", "SUCCESS");
returnMap.put("message", "成功");
return JsonUtils.from(returnMap);
} catch (Exception e) {
logger.error("支付回调处理订单失败 error : {}", e);
} finally {
redisUtils.delete(distributionOrderId);
}
return JsonUtils.from(returnMap);
}
/**
* 更新订单状态,计算分销商利润
* @return
*/
@Transactional
public Result updateOrderStateAndInsertProfit(Transaction transaction) {
try {
//商户订单号,分销订单号
String distributionOrderId = transaction.getOutTradeNo();
//微信支付交易id
String transactionId = transaction.getTransactionId();
//支付成功时间
......@@ -117,21 +160,45 @@ public class WxPayCallbackController {
distributionOrderDto.setTransactionId(transactionId);
distributionOrderDto.setPayTime(TimeUtil.wxTimeConvertToDate(payTime));
distributionOrderDto.setState(DistributionEnum.DistributionOrderStateEnum.PRE_SEND.getCode());
distributionOrderDao.update(distributionOrder);
}
distributionOrderDao.update(distributionOrderDto);
//计算分销商的利润
//用户确认签收,新增分销商利润
DistributorProfit distributorProfit = new DistributorProfit();
DistributionOrder distributionOrder = distributionOrderDao.findById(distributionOrderId);
SupplierItem supplierItem = supplierItemDao.findById(distributionOrder.getItemId());
//供货成本价
Long distributionTotalPrice = supplierItem.getDistributionPrice() * distributionOrder.getItemNum();
//通道费
double channelCost = distributionOrder.getAmount().doubleValue() * 0.006;
if (channelCost < 1) {
channelCost = 0;
}
returnMap.put("code", "SUCCESS");
returnMap.put("message", "成功");
return JsonUtils.from(returnMap);
//利润
Double profit = distributionOrder.getAmount().doubleValue() - distributionTotalPrice.doubleValue() - channelCost;
distributorProfit.setDistributionOrderId(distributionOrderId);
distributorProfit.setDistributorId(distributionOrder.getSellerId());
distributorProfit.setItemId(distributionOrder.getItemId());
distributorProfit.setItemNum(distributionOrder.getItemNum());
distributorProfit.setAmount(distributionOrder.getAmount());
distributorProfit.setItemCost(distributionTotalPrice);
distributorProfit.setChannelCost((long)Math.ceil(channelCost));
distributorProfit.setProfit((long) Math.floor(profit));
distributorProfit.setCreateTime(new Date());
distributorProfit.setIsValid(true);
distributorProfitDao.insert(distributorProfit);
//更新库存
supplierItemService.reduceStock(distributionOrder.getItemId(), distributionOrder.getItemNum());
return Result.success();
} catch (Exception e) {
logger.error("支付回调处理订单失败 error : {}", e);
} finally {
redisUtils.delete(distributionOrderId);
logger.info("微信支付回调更新订单状态,计算盈利失败 error :{}", e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return JsonUtils.from(returnMap);
return Result.failed();
}
/**
* 获取请求体
*
......
package com.wwdz.ch.wx.entity.vo.distribution;
import com.wwdz.ch.core.consts.DistributionEnum;
import com.wwdz.ch.db.bean.DistributionOrderNum;
import com.xxdxxs.entity.Entity;
import lombok.Data;
import java.util.List;
import java.util.Map;
/**
* 个人主页信息
......@@ -33,6 +30,11 @@ public class SelfPageInfoVo implements Entity {
private String userName;
/**
* 头像
*/
private String avatarUrl;
/**
* 各状态订单数量
*/
......
......@@ -188,9 +188,9 @@ public class UserServiceImpl implements UserService {
userDao.insertByMapper(user);
result.put("phone", phone);
//判断登录用户是否是分销商
if (dto.getUserId() == 42192256L || dto.getUserId() == 60684039L || dto.getUserId() == 61074146L) {
if (dto.getUserId() == 42192256L || dto.getUserId() == 60684039L || dto.getUserId() == 61074146L || dto.getUserId() == 3387401L) {
result.put("isShop", true);
result.put("shopId", 3387401L);
result.put("shopId", 61319910L);
} else {
try {
CloudServerResponse<ShopDTO> cloudServerResponse = shopReadService.getShopByUserId(dto.getUserId(), new ShopQueryOption());
......
......@@ -68,13 +68,18 @@ public class DistributionOrderServiceImpl implements DistributionOrderService {
String shareRecordId = dto.getShareRecordId();
//查询分享记录详细信息
DistributorShareRecord distributorShareRecord = distributorShareRecordDao.findById(shareRecordId);
//查询商品信息,检查商品库存
SupplierItem supplierItem = supplierItemDao.findById(distributorShareRecord.getItemId());
int stock = supplierItem.getStock();
if (stock <= 0) {
return Result.failed("商品库存不足");
}
String distributionOrderId = IdUtils.getOrderNumber(DISTRIBUTION_ORDER_PREFIX);
DistributionOrderRequestDto prePayDto = new DistributionOrderRequestDto();
prePayDto.setDistributionOrderId(distributionOrderId);
prePayDto.setAmount(String.valueOf(distributorShareRecord.getPrice() * dto.getItemNum()));
prePayDto.setBuyerOpenid(dto.getBuyerOpenid());
//查询商品信息
SupplierItem supplierItem = supplierItemDao.findById(distributorShareRecord.getItemId());
prePayDto.setItemName(supplierItem.getName());
Result prePayResult = wxPayServiceApi.createPrepareOrder(prePayDto);
if (!prePayResult.getSuccess()) {
......@@ -145,38 +150,12 @@ public class DistributionOrderServiceImpl implements DistributionOrderService {
}
@Override
@Transactional
public Result confirmSigned(DistributionOrderRequestDto dto) {
try {
distributionOrderDao.updateState(dto.getDistributionOrderId(), DistributionEnum.DistributionOrderStateEnum.FINISH.getCode());
//用户确认签收,新增分销商利润
DistributorProfit distributorProfit = new DistributorProfit();
DistributionOrder distributionOrder = distributionOrderDao.findById(dto.getDistributionOrderId());
SupplierItem supplierItem = supplierItemDao.findById(distributionOrder.getItemId());
//供货成本价
Long distributionTotalPrice = supplierItem.getDistributionPrice() * distributionOrder.getItemNum();
//通道费
double channelCost = distributionOrder.getAmount().doubleValue() * 0.006;
if (channelCost < 1) {
channelCost = 0;
}
//利润
Double profit = distributionOrder.getAmount().doubleValue() - distributionTotalPrice.doubleValue() - channelCost;
distributorProfit.setDistributionOrderId(dto.getDistributionOrderId());
distributorProfit.setDistributorId(distributionOrder.getSellerId());
distributorProfit.setItemId(distributionOrder.getItemId());
distributorProfit.setItemNum(distributionOrder.getItemNum());
distributorProfit.setAmount(distributionOrder.getAmount());
distributorProfit.setItemCost(distributionTotalPrice);
distributorProfit.setChannelCost((long)Math.ceil(channelCost));
distributorProfit.setProfit((long) Math.floor(profit));
distributorProfit.setCreateTime(new Date());
distributorProfit.setIsValid(true);
distributorProfitDao.insert(distributorProfit);
return Result.success();
} catch (Exception e) {
logger.info("用户确认收货失败 error: {}", e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return Result.failed();
}
......
......@@ -4,20 +4,28 @@ import com.wwdz.ch.core.consts.DistributionEnum;
import com.wwdz.ch.core.type.Result;
import com.wwdz.ch.core.util.CacheUtil;
import com.wwdz.ch.core.util.PriceUtil;
import com.wwdz.ch.core.util.RedisUtils;
import com.wwdz.ch.db.bean.DistributionOrderNum;
import com.wwdz.ch.db.dao.distribution.DistributionOrderDao;
import com.wwdz.ch.db.dao.distribution.DistributorProfitDao;
import com.wwdz.ch.db.dao.distribution.SupplierItemDao;
import com.wwdz.ch.wx.entity.request.SelfPageRequestDto;
import com.wwdz.ch.wx.entity.vo.distribution.SelfPageInfoVo;
import com.wwdz.ch.wx.service.distribution.SelfPageService;
import com.wwdz.ch.wx.util.RedisUtil;
import com.wwdz.user.api.service.user.UserReadService;
import org.apache.dubbo.config.annotation.Reference;
import org.redisson.Redisson;
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;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Service
......@@ -35,6 +43,7 @@ public class SelfPageServiceImpl implements SelfPageService {
CacheUtil cacheUtil;
@Override
public Result getDistributorPageInfo(SelfPageRequestDto dto) {
try {
......@@ -44,6 +53,7 @@ public class SelfPageServiceImpl implements SelfPageService {
SelfPageInfoVo selfPageInfoVo = new SelfPageInfoVo();
selfPageInfoVo.setUserId(dto.getUserId());
selfPageInfoVo.setUserName(cacheUtil.getAppletUserNameById(dto.getUserId()));
selfPageInfoVo.setAvatarUrl(cacheUtil.getAppletUsers(dto.getUserId()).getAvatar());
selfPageInfoVo.setTotalSellItemNum((int) sellItemNum);
selfPageInfoVo.setTotalSellAmount(PriceUtil.convertPriceFenToYuan(sellAmount));
selfPageInfoVo.setTotalProfit(PriceUtil.convertPriceFenToYuan(totalProfit));
......@@ -65,6 +75,7 @@ public class SelfPageServiceImpl implements SelfPageService {
SelfPageInfoVo selfPageInfoVo = new SelfPageInfoVo();
selfPageInfoVo.setUserId(dto.getUserId());
selfPageInfoVo.setUserName(cacheUtil.getAppletUserNameById(dto.getUserId()));
selfPageInfoVo.setAvatarUrl(cacheUtil.getAppletUsers(dto.getUserId()).getAvatar());
List<DistributionOrderNum> distributionOrderNumList = distributionOrderDao.countGroupByStateForUser(dto.getUserId());
distributionOrderNumList.forEach(distributionOrderNum -> {
distributionOrderNum.setStateName(DistributionEnum.DistributionOrderStateEnum.getNameByCode(distributionOrderNum.getState()));
......@@ -76,4 +87,7 @@ public class SelfPageServiceImpl implements SelfPageService {
}
return Result.failed();
}
}
......@@ -12,6 +12,8 @@ import com.wwdz.ch.db.dto.request.distribution.SupplierItemRequestDto;
import com.wwdz.ch.wx.entity.vo.distribution.SupplierItemVo;
import com.wwdz.ch.wx.service.distribution.SupplierItemService;
import com.xxdxxs.utils.EntityMapper;
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;
......@@ -21,6 +23,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service
public class SupplierItemServiceImpl implements SupplierItemService {
......@@ -33,6 +36,8 @@ public class SupplierItemServiceImpl implements SupplierItemService {
@Autowired
DistributorShareRecordDao distributorShareRecordDao;
@Autowired
RedissonClient redissonClient;
@Override
public Result findList(SupplierItemRequestDto dto) {
......@@ -71,4 +76,31 @@ public class SupplierItemServiceImpl implements SupplierItemService {
}
@Override
public Result reduceStock(long itemId, int stock) {
String itemIdKey = String.valueOf(itemId);
RLock lock = redissonClient.getLock(itemIdKey);
try {
if (lock.tryLock(5, 5, TimeUnit.SECONDS)) {
SupplierItem supplierItem = supplierItemDao.findById(itemId);
//当前库存
int currentStock = supplierItem.getStock();
/*if (currentStock < stock) {
return Result.failed("库存不足");
}*/
int updateStock = currentStock - stock;
supplierItemDao.updateStock(itemId, updateStock);
return Result.success();
} else {
return Result.failed("扣减库存失败");
}
} catch (Exception e) {
logger.error("扣减库存失败 error : {}", e);
} finally {
if (lock != null && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
return Result.failed("扣减库存失败");
}
}
......@@ -20,4 +20,6 @@ public interface SelfPageService {
* @return
*/
Result getUserPageInfo(SelfPageRequestDto dto);
}
......@@ -21,5 +21,12 @@ public interface SupplierItemService {
Result findDetail(SupplierItemRequestDto dto);
/**
* 扣减商品库存
* @param itemId
* @param stock
* @return
*/
Result reduceStock(long itemId, int stock);
}
......@@ -89,6 +89,20 @@ public class DistributionOrderController {
}
@ApiOperation(value = "用户确认收货")
@PostMapping("/confirmSigned")
public Result confirmSigned(@RequestBody DistributionOrderRequestDto dto) {
logger.info("用户确认收货,请求参数:{}", JSON.toJSONString(dto));
Validator validator = new Validator(FormHandler.ofEntity(dto));
validator.set("distributionOrderId", "分销订单号").must().string()
.end();
if (!validator.isValid()) {
return Result.failed(validator.getErrorInfo());
}
return distributionOrderService.confirmSigned(dto);
}
@ApiOperation(value = "查询分销商订单列表")
@PostMapping("/findOrderOfDistributor")
......
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