Authored by wujiexiang

批量调价

Showing 27 changed files with 1609 additions and 179 deletions
... ... @@ -76,4 +76,27 @@ public interface SellerOrderGoodsMapper {
List<SellerOrderGoods> selectByUidStorageStatusGBBPSList(@Param("uid")int uid,
@Param("storageId")Integer storageId,
@Param("statusList") List<Integer> statusList);
/**
* 关联seller_order表查询
*
* @param payment
* @param record
* @param statusList
* @return
*/
List<SellerOrderGoods> selectByPayment(@Param("payment") int payment,
@Param("condition") SellerOrderGoods record,
@Param("statusList") Collection<Integer> statusList,
@Param("num") int num);
/**
* 根据条件更新
*
* @param condition
* @param updateTo
* @return
*/
int updateByCondition(@Param("condition") SellerOrderGoods condition, @Param("updateTo") SellerOrderGoods updateTo);
}
\ No newline at end of file
... ...
package com.yohoufo.dal.order;
import com.yohoufo.dal.order.model.SellerTaskDetail;
/**
* Created by jiexiang.wu on 2018/12/20.
*/
public interface SellerTaskDetailMapper {
long insert(SellerTaskDetail record);
}
... ...
package com.yohoufo.dal.order;
import com.yohoufo.dal.order.model.SellerTask;
/**
* Created by jiexiang.wu on 2018/12/20.
*/
public interface SellerTaskMapper {
long insert(SellerTask record);
}
... ...
package com.yohoufo.dal.order.model;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Builder;
import java.math.BigDecimal;
/**
* Created by jiexiang.wu on 2018/12/20.
*/
@Data
@ToString
@Builder
public class SellerTask {
private long id;
private int uid;
private int type;
private String taskDesc;
private int createTime;
}
... ...
package com.yohoufo.dal.order.model;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Builder;
import java.math.BigDecimal;
/**
* Created by jiexiang.wu on 2018/12/20.
*/
@Data
@ToString
@Builder
public class SellerTaskDetail {
private long id;
//对应seller_task表id
private long taskId;
private int skup;
private BigDecimal amount;
private int status;
private int createTime;
}
... ...
... ... @@ -24,6 +24,11 @@
id, uid, product_id, product_name, storage_id, depot_no, size_id, size_name,
color_id, color_name, goods_price, status, image_url, is_del, batch_no
</sql>
<sql id="Associated_Base_Column_List">
sog.id, sog.uid, sog.product_id, sog.product_name, sog.storage_id, sog.depot_no, sog.size_id, sog.size_name,
sog.color_id, sog.color_name, sog.goods_price, sog.status, sog.image_url, sog.is_del, sog.batch_no
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
... ... @@ -393,4 +398,44 @@
where storage_id = #{storageId,jdbcType=INTEGER}
and <include refid="sql_where_4_select_UidStatusGBBNList"/>
</select>
<select id="selectByPayment" resultMap="BaseResultMap">
select
<include refid="Associated_Base_Column_List" />
from seller_order_goods sog,seller_order so
where sog.id = so.skup
and sog.uid = #{condition.uid,jdbcType=INTEGER}
and sog.product_id = #{condition.productId,jdbcType=INTEGER}
and sog.storage_id = #{condition.storageId,jdbcType=INTEGER}
and so.payment = #{payment,jdbcType=INTEGER}
and sog.goods_price = #{condition.goodsPrice,jdbcType=DECIMAL}
and sog.status in
<foreach collection="statusList" item="status" open="(" close=")" separator=",">
#{status,jdbcType=TINYINT}
</foreach>
limit #{num}
</select>
<update id="updateByCondition">
update seller_order_goods
<set>
<if test="updateTo.goodsPrice != null">
goods_price = #{updateTo.goodsPrice,jdbcType=DECIMAL},
</if>
<if test="updateTo.status != null">
status = #{updateTo.status,jdbcType=TINYINT},
</if>
</set>
where id = #{condition.id,jdbcType=INTEGER}
and uid = #{condition.uid,jdbcType=INTEGER}
<if test="condition.goodsPrice != null">
and goods_price = #{condition.goodsPrice,jdbcType=DECIMAL}
</if>
<if test="condition.status != null">
and status = #{condition.status,jdbcType=TINYINT}
</if>
</update>
</mapper>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yohoufo.dal.order.SellerTaskDetailMapper">
<insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.yohoufo.dal.order.model.SellerTaskDetail"
useGeneratedKeys="true">
insert into seller_task_detail (task_id, skup,amount, status,create_time)
values ( #{taskId,jdbcType=BIGINT}, #{skup,jdbcType=INTEGER}, #{amount,jdbcType=DECIMAL},
#{status,jdbcType=INTEGER},#{createTime,jdbcType=INTEGER})
</insert>
</mapper>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yohoufo.dal.order.SellerTaskMapper">
<insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.yohoufo.dal.order.model.SellerTask"
useGeneratedKeys="true">
insert into seller_task (uid, type, task_desc, create_time)
values (#{uid,jdbcType=INTEGER}, #{type,jdbcType=INTEGER},#{taskDesc,jdbcType=VARCHAR}, #{createTime,jdbcType=INTEGER})
</insert>
</mapper>
\ No newline at end of file
... ...
... ... @@ -19,7 +19,6 @@ import com.yohoufo.order.service.handler.SellerOrderComputeHandler;
import com.yohoufo.order.service.impl.SellerOrderService;
import com.yohoufo.order.service.impl.SellerService;
import com.yohoufo.order.service.impl.SkupListService;
import org.apache.kafka.common.requests.LeaderAndIsrRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -29,7 +28,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import java.math.BigDecimal;
import java.util.Objects;
/**
... ... @@ -105,7 +104,7 @@ public class SellerOrderController {
}
/**
* 入驻商家的批量下架
* 入驻商家的批量下架 已经售出的不会下架
* @param uid
* @param batchNo
* @param num
... ... @@ -133,7 +132,13 @@ public class SellerOrderController {
}
/**
* 取消 出售中或售出都会取消
* @param uid
* @param orderCode
* @return
* @throws GatewayException
*/
@RequestMapping(params = "method=ufo.sellerOrder.cancel")
@ResponseBody
public ApiResponse cancel(@RequestParam(name = "uid", required = true)int uid,
... ... @@ -220,11 +225,12 @@ public class SellerOrderController {
@RequestParam(name = "skupList", required = true)String skupList
) throws GatewayException {
BatchChangePriceReq req = BatchChangePriceReq.builder()
.uid(uid).price(price)
.isShowPriceError(true)
.batchNo(batchNo).skupList(skupList)
.build();
BatchChangePriceReq req = new BatchChangePriceReq();
req.setUid(uid);
req.setPrice(price);
req.setShowPriceError(true);
req.setBatchNo(batchNo);
req.setSkupList(skupList);
logger.info("in ufo.sellerOrder.batchChangePrice, req {}", req);
BatchChangePriceResp result = sellerOrderService.batchChangePrice(req);
... ... @@ -239,17 +245,122 @@ public class SellerOrderController {
@RequestParam(name = "batchNo", required = false)String batchNo,
@RequestParam(name = "skupList", required = false)String skupList,
@RequestParam(name="num", defaultValue = "1", required = false)int num) throws GatewayException {
BatchChangePriceReq req = BatchChangePriceReq.builder()
.storageId(storage_id)
.uid(uid).price(price)
.batchNo(batchNo).skupList(skupList)
.isShowPriceError(false)
.build();
BatchChangePriceReq req = new BatchChangePriceReq();
req.setStorageId(storage_id);
req.setUid(uid);
req.setPrice(price);
req.setBatchNo(batchNo);
req.setSkupList(skupList);
req.setShowPriceError(false);
logger.info("in ufo.sellerOrder.computeChangePrice, req {}", req);
SoldPrdComputeBo computeBo = sellerOrderService.computeChangePrice(req);
return new ApiResponse.ApiResponseBuilder().code(200).data(computeBo).message("算费成功").build();
}
/**
* 调价计算
* @param uid
* @param storage_id
* @param old_price
* @param new_price
* @param product_id
* @param num
* @return
* @throws GatewayException
*/
@RequestMapping(params = "method=ufo.sellerOrder.computeAdjustPrice")
@ResponseBody
public ApiResponse computeAdjustPrice(@RequestParam(name = "uid") int uid,
@RequestParam(name = "storage_id") int storage_id,
@RequestParam(name = "old_price") BigDecimal old_price,
@RequestParam(name = "new_price") String new_price,
@RequestParam(name = "product_id") int product_id,
@RequestParam(name = "num") int num) throws GatewayException {
SellerBatchChangeReq req = new SellerBatchChangeReq();
req.setStorageId(storage_id);
req.setUid(uid);
req.setOldPrice(old_price);
req.setPrice(new_price);
req.setProductId(product_id);
req.setNum(num);
req.setShowPriceError(false);
logger.info("in ufo.sellerOrder.computeAdjustPrice, req {}", req);
try {
SoldPrdComputeBo computeBo = sellerOrderService.computeAdjustPrice(req);
return new ApiResponse.ApiResponseBuilder().code(200).data(computeBo).message("算费成功").build();
} catch (Exception ex) {
logger.error("exception happened in ufo.sellerOrder.computeAdjustPrice, req {}", req, ex);
throw ex;
}
}
/**
* 批量调价
* @param uid
* @param storage_id
* @param old_price
* @param new_price
* @param product_id
* @param num
* @return
* @throws GatewayException
*/
@RequestMapping(params = "method=ufo.sellerOrder.batchAdjustPrice")
@ResponseBody
public ApiResponse batchAdjustPrice(@RequestParam(name = "uid") int uid,
@RequestParam(name = "storage_id") int storage_id,
@RequestParam(name = "old_price") BigDecimal old_price,
@RequestParam(name = "new_price") String new_price,
@RequestParam(name = "product_id") int product_id,
@RequestParam(name = "num") int num) throws GatewayException {
SellerBatchChangeReq req = new SellerBatchChangeReq();
req.setStorageId(storage_id);
req.setUid(uid);
req.setOldPrice(old_price);
req.setPrice(new_price);
req.setProductId(product_id);
req.setNum(num);
req.setShowPriceError(true);
logger.info("in ufo.sellerOrder.batchAdjustPrice, req {}", req);
try {
BatchChangePriceResp result = sellerOrderService.batchAdjustPrice(req);
return new ApiResponse.ApiResponseBuilder().data(result).code(200).message(result.getTips()).build();
} catch (Exception ex) {
logger.error("exception happened in ufo.sellerOrder.batchAdjustPrice, req {}", req, ex);
throw ex;
}
}
/**
* 入驻商家的批量下架 已经售出的不会下架
* @param uid
* @param storage_id
* @param product_id
* @param num
* @return
*/
@RequestMapping(params = "method=ufo.sellerOrder.batchDownShelf")
@ResponseBody
public ApiResponse batchDownShelf(@RequestParam(name = "uid") int uid,
@RequestParam(name = "storage_id") int storage_id,
@RequestParam(name = "product_id") int product_id,
@RequestParam(name = "old_price") BigDecimal old_price,
@RequestParam(name = "num") int num) throws GatewayException {
SellerBatchChangeReq req = new SellerBatchChangeReq();
req.setStorageId(storage_id);
req.setUid(uid);
req.setProductId(product_id);
req.setOldPrice(old_price);
req.setNum(num);
logger.info("in ufo.sellerOrder.batchDownShelf, req {}", req);
boolean result = sellerOrderService.batchDownShelf(req);
String msg = "批量取消成功";
if (!result) {
msg = "批量取消失败";
}
return new ApiResponse.ApiResponseBuilder().data(result).code(200).message(msg).build();
}
@RequestMapping(params = "method=ufo.order.refresh")
@ResponseBody
... ...
package com.yohoufo.order.model.dto;
import com.yohoufo.order.service.handler.ISellerTaskHandler;
/**
* Created by jiexiang.wu on 2018/12/21.
*/
public class SellerTaskDTO<T> {
private int uid;
//任务生成后id
private long taskId;
//任务类型
private int taskType;
//任务描述,会保存,json
private String taskDesc;
private final ISellerTaskHandler taskHandler;
private T processData;
public SellerTaskDTO(int uid, int taskType, ISellerTaskHandler taskHandler, String taskDesc, T processData) {
this.uid = uid;
this.taskType = taskType;
this.taskHandler = taskHandler;
this.taskDesc = taskDesc;
this.processData = processData;
}
public int getUid() {
return uid;
}
public ISellerTaskHandler getTaskHandler() {
return taskHandler;
}
public T getProcessData() {
return processData;
}
public long getTaskId() {
return taskId;
}
public void setTaskId(long taskId) {
this.taskId = taskId;
}
public int getTaskType() {
return taskType;
}
public String getTaskDesc() {
return taskDesc;
}
}
... ...
package com.yohoufo.order.model.dto;
import com.yohoufo.dal.order.model.SellerWallet;
import java.util.Set;
/**
* Created by jiexiang.wu on 2018/12/21.
*/
public class SellerTaskResult {
//方法的业务结果数据;
public SellerWallet sellerWallet;
public Set<Integer> successSkups;
public int successCnt;
public int failCnt;
}
... ...
... ... @@ -408,13 +408,13 @@ public class MerchantOrderPaymentService extends AbstractOrderPaymentService {
// 支付保证金:明细记录+orders_pay记录
public void useEarnestAddWalletDetail(SellerWallet sw, List<OrderInfo> orderList) {
for(OrderInfo oi : orderList) {
SellerWalletDetail swd = addWalletDetail(sw, oi.getOrderCode(), oi.getAmount(), SellerWalletDetail.Type.PUBLISH);
SellerWalletDetail swd = addWalletDetail(sw, null,oi.getOrderCode(), oi.getAmount(), SellerWalletDetail.Type.PUBLISH);
addOrdersPay(swd);
}
}
// 修改价格:明细记录+orders_pay金额修改
public void changePriceAddWalletDetail(SellerWallet sw, List<OrderInfo> orderList) {
public void changePriceAddWalletDetail(SellerWallet sw, MerchantOrderAttachInfo attachInfo,List<OrderInfo> orderList) {
for(OrderInfo oi : orderList) {
SellerWalletDetail.Type t;
if (orderList.get(0).getAmount().compareTo(BigDecimal.ZERO) > 0) {
... ... @@ -422,7 +422,7 @@ public class MerchantOrderPaymentService extends AbstractOrderPaymentService {
} else {
t = SellerWalletDetail.Type.SUBTRACT_PRICE;
}
SellerWalletDetail swd = addWalletDetail(sw, oi.getOrderCode(), oi.getAmount(), t);
SellerWalletDetail swd = addWalletDetail(sw,attachInfo, oi.getOrderCode(), oi.getAmount(), t);
changePriceUpdateOrdersPay(swd);
}
}
... ... @@ -431,7 +431,7 @@ public class MerchantOrderPaymentService extends AbstractOrderPaymentService {
public void unshelveAddWalletDetail(SellerWallet sw, List<OrderInfo> orderList) {
SellerWalletDetail.Type type = SellerWalletDetail.Type.SELLER_OFF;
for(OrderInfo oi : orderList) {
SellerWalletDetail swd = addWalletDetail(sw, oi.getOrderCode(), oi.getAmount(), type);
SellerWalletDetail swd = addWalletDetail(sw, null,oi.getOrderCode(), oi.getAmount(), type);
addRefundRecord(swd, oi.getAmount());
}
}
... ... @@ -540,7 +540,7 @@ public class MerchantOrderPaymentService extends AbstractOrderPaymentService {
}
// 增加:明细
private SellerWalletDetail addWalletDetail(SellerWallet sw, long orderCode, BigDecimal amount, SellerWalletDetail.Type type) {
private SellerWalletDetail addWalletDetail(SellerWallet sw, MerchantOrderAttachInfo attachInfo,long orderCode, BigDecimal amount, SellerWalletDetail.Type type) {
Integer uid = sw.getUid();
SellerWalletDetail swd = new SellerWalletDetail();
swd.setOrderCode(orderCode);
... ... @@ -551,8 +551,8 @@ public class MerchantOrderPaymentService extends AbstractOrderPaymentService {
swd.setIsBatch(1);
swd.setCreateTime(TimeUtils.getTimeStampSecond());
swd.setUpdateTime(0);
swd.setAttachValue("");
swd.setAvailAmount(BigDecimal.ZERO);
swd.setAttachValue(attachInfo == null ? "" : JSON.toJSONString(attachInfo));
swd.setAvailAmount(BigDecimal.ZERO);
swd.setLockAmount(BigDecimal.ZERO);
swd.setIsSet(0);
logger.info("增加保证金明细({}),bean={}", type.getName(), swd);
... ...
package com.yohoufo.order.service.handler;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.dal.order.SellerOrderGoodsMapper;
import com.yohoufo.dal.order.SellerOrderMapper;
import com.yohoufo.dal.order.SellerOrderMetaMapper;
import com.yohoufo.dal.order.SellerTaskDetailMapper;
import com.yohoufo.dal.order.model.SellerOrder;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import com.yohoufo.dal.order.model.SellerOrderMeta;
import com.yohoufo.dal.order.model.SellerTaskDetail;
import com.yohoufo.order.constants.MetaKey;
import com.yohoufo.order.model.dto.*;
import com.yohoufo.order.service.MerchantOrderPaymentService;
import com.yohoufo.order.service.proxy.ProductProxyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
* Created by jiexiang.wu on 2018/12/21.
*/
public abstract class AbstractSellerAdjustPriceTaskHandler extends AbstractSellerTaskHandler<ChangePricePrepareDTO> {
@Autowired
protected MerchantOrderPaymentService merchantOrderPaymentService;
@Autowired
protected SkupAdjustPriceDBService skupAdjustPriceDBService;
@Autowired
protected SellerOrderMapper sellerOrderMapper;
@Autowired
protected ProductProxyService productProxyService;
@Override
protected List<FutureTask> getFutureTasks(SellerTaskResult result, SellerTaskDTO<ChangePricePrepareDTO> taskDto) {
ChangePricePrepareDTO cppDto = taskDto.getProcessData();
Map<Integer, SkupDto> skupDtoMap = cppDto.getSkupMap();
List<FutureTask> futureTasks = Lists.newArrayList();
for (Map.Entry<Integer, SkupDto> entry : skupDtoMap.entrySet()) {
FutureTask<Integer> futureTask = new FutureTask<>(new AdjustTask(taskDto.getUid(),
taskDto.getTaskId(), cppDto.getSalePrice(), cppDto.getDiffEarnestMoney(), cppDto.getComputeResult(), entry.getValue()));
futureTasks.add(futureTask);
}
return futureTasks;
}
private class AdjustTask implements Callable<Integer> {
public int uid;
public long taskId;
public BigDecimal salePrice;
public BigDecimal diffEarnestMoney;
public SellerOrderComputeResult computeResult;
public SkupDto skupDto;
public AdjustTask(int uid, long taskId, BigDecimal salePrice, BigDecimal diffEarnestMoney, SellerOrderComputeResult computeResult, SkupDto skupDto) {
this.uid = uid;
this.taskId = taskId;
this.salePrice = salePrice;
this.diffEarnestMoney = diffEarnestMoney;
this.computeResult = computeResult;
this.skupDto = skupDto;
}
@Override
public Integer call() throws Exception {
try {
skupAdjustPriceDBService.update(taskId, salePrice, diffEarnestMoney, computeResult, skupDto);
log.info("[{}-{}-{}] handle success", uid, taskId, skupDto.getSkup());
return skupDto.getSkup();
} catch (Throwable t) {
log.error("[{}-{}-{}] exception happened when atomic handle", uid, taskId, skupDto.getSkup(), t);
return null;
}
}
}
@Transactional
@Component
public static class SkupAdjustPriceDBService {
@Autowired
private SellerOrderMapper sellerOrderMapper;
@Autowired
private SellerOrderGoodsMapper sellerOrderGoodsMapper;
@Autowired
private SellerOrderMetaMapper somMapper;
@Autowired
private SellerTaskDetailMapper sellerTaskDetailMapper;
private Random random = new Random();
@Transactional
public void update(long taskId, BigDecimal newPrice, BigDecimal diffEarnestMoney, SellerOrderComputeResult computeResult, SkupDto skupDto) {
SellerOrderGoods sellerOrderGoods = skupDto.getSellerOrderGoods();
List<Integer> skups = Lists.newArrayList(sellerOrderGoods.getId());
//sell_order_goods(价格)
SellerOrderGoods sogUpdateTo = new SellerOrderGoods();
sogUpdateTo.setGoodsPrice(newPrice);
int num = sellerOrderGoodsMapper.updateByCondition(sellerOrderGoods, sogUpdateTo);
if (num != 1) {
throw new UfoServiceException(500, "update seller order goods price error by skup" + skupDto.getSkup());
}
//修改 seller_order(保证金 income)
SellerOrder condition = new SellerOrder();
condition.setEarnestMoney(computeResult.getEarnestMoney().getEarnestMoney());
condition.setIncome(computeResult.getIncome());
//todo 使用采用乐观锁 ?
num = sellerOrderMapper.updateBySkups(condition, skups);
if (num != 1) {
throw new UfoServiceException(500, "update seller order earnestMoney error by skup" + skupDto.getSkup());
}
//order_meta 算费
SellerOrderMeta som = new SellerOrderMeta();
String value = JSONObject.toJSONString(computeResult);
som.setMetaValue(value);
som.setMetaKey(MetaKey.SELLER_FEE);
somMapper.updateByPrimaryKeys(som, skups);
//增加明细状态
SellerTaskDetail detail = SellerTaskDetail.builder()
.taskId(taskId)
.skup(sellerOrderGoods.getId())
.amount(diffEarnestMoney)
.status(1)
.createTime(DateUtil.getCurrentTimeSecond()).build();
sellerTaskDetailMapper.insert(detail);
if (random.nextBoolean()) {
throw new IllegalStateException("random");
}
}
}
}
... ...
package com.yohoufo.order.service.handler;
import com.google.common.collect.Sets;
import com.yohoufo.order.model.dto.SellerTaskDTO;
import com.yohoufo.order.model.dto.SellerTaskResult;
import com.yohoufo.order.utils.LoggerUtils;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
/**
* Created by jiexiang.wu on 2018/12/21.
*/
public abstract class AbstractSellerTaskHandler<T> implements ISellerTaskHandler<T> {
protected final Logger log = LoggerUtils.getSellerOrderLogger();
private ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
@Override
public SellerTaskResult handle(SellerTaskDTO<T> taskDto) {
SellerTaskResult result = new SellerTaskResult();
if (preHandle(result, taskDto)) {
doHandle(result, taskDto);
}
postHandle(result, taskDto);
return result;
}
protected abstract boolean preHandle(SellerTaskResult result, SellerTaskDTO<T> taskDto);
protected abstract List<FutureTask> getFutureTasks(SellerTaskResult result, SellerTaskDTO<T> taskDto);
protected void doHandle(SellerTaskResult result, SellerTaskDTO<T> taskDto) {
List<FutureTask> futureTasks = getFutureTasks(result, taskDto);
if (CollectionUtils.isEmpty(futureTasks)) {
return;
}
for (FutureTask task : futureTasks) {
//线程池执行
executorService.submit(task);
}
//获取结果
handleFutureTasks(result, taskDto, futureTasks);
}
private void handleFutureTasks(SellerTaskResult result, SellerTaskDTO<T> taskDto, List<FutureTask> futureTasks) {
int successCnt = 0;
int failCnt = 0;
Set<Integer> successSkups = Sets.newHashSet();
for (FutureTask<Integer> task : futureTasks) {
try {
Integer taskResult = task.get();
if (taskResult != null) {
successCnt++;
successSkups.add(taskResult);
} else {
failCnt++;
}
} catch (Exception ex) {
log.error("future task error", ex);
failCnt++;
}
}
result.successSkups = successSkups;
result.successCnt = successCnt;
result.failCnt = failCnt;
log.info("[{}-{}] >>> success:{},fail:{},successSkups:{}", taskDto.getUid(), taskDto.getTaskId(), successCnt, failCnt, successSkups);
}
public abstract void postHandle(SellerTaskResult result, SellerTaskDTO<T> taskDto);
}
... ...
package com.yohoufo.order.service.handler;
import com.yohoufo.order.model.dto.SellerTaskDTO;
import com.yohoufo.order.model.dto.SellerTaskResult;
/**
* Created by jiexiang.wu on 2018/12/21.
*/
public interface ISellerTaskHandler<T> {
/**
* @param taskDto 调用方法需要使用的业务数据
* @return 方法执行后业务方法的结果
*/
SellerTaskResult handle(SellerTaskDTO<T> taskDto);
}
\ No newline at end of file
... ...
package com.yohoufo.order.service.handler;
import com.yohobuy.ufo.model.order.bo.MerchantOrderAttachInfo;
import com.yohobuy.ufo.model.order.bo.OrderInfo;
import com.yohoufo.dal.order.model.SellerOrder;
import com.yohoufo.dal.order.model.SellerWallet;
import com.yohoufo.dal.order.model.SellerWalletDetail;
import com.yohoufo.order.model.dto.ChangePricePrepareDTO;
import com.yohoufo.order.model.dto.SellerOrderComputeResult;
import com.yohoufo.order.model.dto.SellerTaskDTO;
import com.yohoufo.order.model.dto.SellerTaskResult;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Created by jiexiang.wu on 2018/12/21.
*/
@Component
public class SellerDecrPriceTaskHandler extends AbstractSellerAdjustPriceTaskHandler {
@Override
protected boolean preHandle(SellerTaskResult result, SellerTaskDTO<ChangePricePrepareDTO> taskDto) {
return true;
}
@Override
public void postHandle(SellerTaskResult result, SellerTaskDTO<ChangePricePrepareDTO> taskDto) {
if (result.successCnt > 0) {
ChangePricePrepareDTO cppDto = taskDto.getProcessData();
int uid = taskDto.getUid();
long taskId = taskDto.getTaskId();
BigDecimal preSalePrice = cppDto.getPreSalePrice(),
salePrice = cppDto.getSalePrice();
SellerOrderComputeResult computeResult = cppDto.getComputeResult();
//1 划账
BigDecimal diffEarnestMoney = cppDto.getDiffEarnestMoney();
BigDecimal totalDiffMoney = diffEarnestMoney.multiply(new BigDecimal(result.successCnt));
MerchantOrderAttachInfo moai = MerchantOrderAttachInfo.builder().uid(uid)
.afterProductPrice(salePrice)
.beforeEarnestMoney(cppDto.getPreEarnestMoney().toPlainString())
.beforeProductPrice(preSalePrice)
.afterEarnestMoney(computeResult.getEarnestMoney().getEarnestMoney().toPlainString())
.earnestMoney(totalDiffMoney).productCount(result.successCnt)
.seriNo(String.valueOf(taskId))
.type(SellerWalletDetail.Type.SUBTRACT_PRICE.getValue()).build();
try {
if (!cppDto.isSuper()) {
log.info("[{}-{}] post use total earnest:{},diff earnest:{},num:{}", uid, taskId, totalDiffMoney, diffEarnestMoney, result.successCnt);
SellerWallet sellerWallet = merchantOrderPaymentService.changePriceUseEarnest(uid, totalDiffMoney, moai);
if (Objects.nonNull(sellerWallet)) {
log.info("[{}-{}] begin to add wallet detail", uid, taskId);
//4 划账记录
List<SellerOrder> psoList = sellerOrderMapper.selectBySkups(result.successSkups);
List<OrderInfo> orderList = psoList.parallelStream().map(
so -> OrderInfo.builder().orderCode(so.getOrderCode()).amount(cppDto.getDiffEarnestMoney()).build())
.collect(Collectors.toList());
MerchantOrderAttachInfo attachInfo = MerchantOrderAttachInfo.builder().seriNo(String.valueOf(taskId)).build();
merchantOrderPaymentService.changePriceAddWalletDetail(sellerWallet, attachInfo, orderList);
log.info("[{}-{}] end to add wallet detail success", uid, taskId);
}
}
} catch (Exception ex) {
log.error(" [{}-{}] exception happened when operation seller wallet", uid, taskId, ex);
}
//通知商品
try {
productProxyService.batchUpdatePrice(result.successSkups, cppDto.getSalePrice());
log.info("[{}-{}] notify product to update price for skups:{} success", uid, taskId, result.successSkups);
} catch (Exception ex) {
log.error("[{}-{}] exception happened when notify product to update price,skups:{},salePrice:{}",
uid, taskId, result.successSkups, cppDto.getSalePrice());
}
}
}
}
... ...
package com.yohoufo.order.service.handler;
import com.google.common.collect.Lists;
import com.yohobuy.ufo.model.order.bo.MerchantOrderAttachInfo;
import com.yohobuy.ufo.model.order.bo.OrderInfo;
import com.yohobuy.ufo.model.order.common.SellerOrderStatus;
import com.yohobuy.ufo.model.order.common.SkupStatus;
import com.yohobuy.ufo.model.order.common.TabType;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.dal.order.SellerOrderGoodsMapper;
import com.yohoufo.dal.order.SellerOrderMapper;
import com.yohoufo.dal.order.SellerTaskDetailMapper;
import com.yohoufo.dal.order.model.*;
import com.yohoufo.order.model.dto.SellerTaskDTO;
import com.yohoufo.order.model.dto.SellerTaskResult;
import com.yohoufo.order.model.dto.SkupDto;
import com.yohoufo.order.service.MerchantOrderPaymentService;
import com.yohoufo.order.service.cache.CacheCleaner;
import com.yohoufo.order.service.cache.CacheKeyBuilder;
import com.yohoufo.order.service.impl.SellerService;
import com.yohoufo.order.service.proxy.InBoxFacade;
import com.yohoufo.order.service.proxy.ProductProxyService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.stream.Collectors;
/**
* Created by jiexiang.wu on 2018/12/21.
*/
@Component
public class SellerDownShelfTaskHandler extends AbstractSellerTaskHandler<Map<Integer, SkupDto>> {
@Autowired
private SellerOrderMapper sellerOrderMapper;
@Autowired
private ProductProxyService productProxyService;
@Autowired
private SkupDownShelfDBService skupDownShelfDBService;
@Autowired
private SellerService sellerService;
@Autowired
private MerchantOrderPaymentService merchantOrderPaymentService;
@Autowired
private InBoxFacade inBoxFacade;
@Autowired
private CacheCleaner cacheCleaner;
@Override
protected boolean preHandle(SellerTaskResult result, SellerTaskDTO<Map<Integer, SkupDto>> taskDto) {
Map<Integer, SkupDto> skupDtoMap = taskDto.getProcessData();
Set<Integer> skupSets = skupDtoMap.keySet();
List<SellerOrder> soList = sellerOrderMapper.selectBySkups(skupSets);
for (SellerOrder so : soList) {
skupDtoMap.get(so.getSkup()).setSellerOrder(so);
}
//先商品下架
return productProxyService.sellerBatchUpdateStatus(Lists.newArrayList(skupSets), ProductProxyService.PrdShelvelStatus.off);
}
@Override
protected List<FutureTask> getFutureTasks(SellerTaskResult result, SellerTaskDTO<Map<Integer, SkupDto>> taskDto) {
Map<Integer, SkupDto> skupDtoMap = taskDto.getProcessData();
List<FutureTask> futureTasks = Lists.newArrayList();
for (Map.Entry<Integer, SkupDto> entry : skupDtoMap.entrySet()) {
FutureTask<Integer> futureTask = new FutureTask<>(new DownShelfTask(taskDto.getUid(), taskDto.getTaskId(), entry.getValue()));
futureTasks.add(futureTask);
}
return futureTasks;
}
@Override
public void postHandle(SellerTaskResult result, SellerTaskDTO<Map<Integer, SkupDto>> taskDto) {
if (result.successCnt > 0) {
int uid = taskDto.getUid();
long taskId = taskDto.getTaskId();
Map<Integer, SkupDto> skupDtoMap = taskDto.getProcessData();
//下架成功的订单
List<SellerOrder> successOrders = Lists.newArrayList();
for (Integer skup : result.successSkups) {
successOrders.add(skupDtoMap.get(skup).getSellerOrder());
}
try {
boolean isSuper = sellerService.isSuperEntrySeller(uid);
//退保证金
SellerWallet sellerWallet = postRefundEarnest(uid, taskId, isSuper, result, successOrders);
//明细
addWalletDetail(uid, taskId, isSuper, sellerWallet, successOrders);
//消息盒子
inboxNotify(uid, skupDtoMap);
//清理缓存
cleanCache(uid, skupDtoMap);
} catch (Exception ex) {
log.error("[{}-{}] exception happened when post handle", uid, taskId, ex);
}
}
}
private SellerWallet postRefundEarnest(int uid, long taskId, boolean isSuper, SellerTaskResult result, List<SellerOrder> successOrders) {
if (isSuper || CollectionUtils.isEmpty(successOrders)) {
return null;
}
BigDecimal totalRefundEM = new BigDecimal(0);
for (SellerOrder so : successOrders) {
totalRefundEM = totalRefundEM.add(so.getEarnestMoney());
}
MerchantOrderAttachInfo moai = MerchantOrderAttachInfo.builder().uid(uid)
.earnestMoney(totalRefundEM).productCount(result.successCnt)
.seriNo(String.valueOf(taskId))
.type(SellerWalletDetail.Type.SELLER_OFF.getValue()).build();
try {
log.info("[{}-{}] post refund earnest:{},num:{}", uid, taskId, totalRefundEM, result.successCnt);
SellerWallet sellerWallet = merchantOrderPaymentService.refundEarnest(uid, totalRefundEM, moai, 0L, SellerWalletDetail.Type.SELLER_OFF);
log.info("[{}-{}] post refund earnest:{},num:{} success", uid, taskId, totalRefundEM, result.successCnt);
return sellerWallet;
} catch (Exception ex) {
log.error("[{}-{}] exception happened when refund earnest:{} to sellerWallet", uid, taskId, totalRefundEM, ex);
return null;
}
}
private void addWalletDetail(int uid, long taskId, boolean isSuper, SellerWallet sellerWallet, List<SellerOrder> successOrders) {
if (isSuper || Objects.isNull(sellerWallet) || CollectionUtils.isEmpty(successOrders)) {
return;
}
log.info("[{}-{}] begin to add wallet detail", uid, taskId);
//4 划账记录
List<OrderInfo> orderList = successOrders.parallelStream().map(so -> OrderInfo.builder()
.orderCode(so.getOrderCode()).amount(so.getEarnestMoney()).build()).collect(Collectors.toList());
try {
merchantOrderPaymentService.unshelveAddWalletDetail(sellerWallet, orderList);
log.info("[{}-{}] end to add wallet detail success", uid, taskId);
} catch (Exception ex) {
log.error("[{}-{}] exception happened when add wallet detail", uid, taskId, ex);
}
}
private void inboxNotify(int uid, Map<Integer, SkupDto> skupDtoMap) {
try {
String productName = skupDtoMap.values().iterator().next().getSellerOrderGoods().getProductName();
inBoxFacade.sellerPlaySelf(uid, productName);
} catch (Exception ex) {
log.error("[{}-{}] exception happened when inboxNotify", uid, ex);
}
}
private void cleanCache(int uid, Map<Integer, SkupDto> skupDtoMap) {
try {
//clean cache
cacheCleaner.delete(Arrays.asList(CacheKeyBuilder.orderListKey(uid, TabType.SELL.getValue()),
CacheKeyBuilder.sellerOrderDetailKey(skupDtoMap.values().iterator().next().getSellerOrderGoods())
));
} catch (Exception ex) {
log.error("[{}-{}] exception happened when cleanCache", uid, ex);
}
}
private class DownShelfTask implements Callable<Integer>{
public int uid;
public long taskId;
public SkupDto skupDto;
public DownShelfTask(int uid, long taskId, SkupDto skupDto) {
this.uid = uid;
this.taskId = taskId;
this.skupDto = skupDto;
}
@Override
public Integer call() throws Exception {
try {
skupDownShelfDBService.update(taskId, skupDto);
log.info("[{}-{}-{}] handle success", uid, taskId, skupDto.getSkup());
return skupDto.getSkup();
} catch (Throwable t) {
log.error("[{}-{}-{}] exception happened when atomic handle", uid, taskId, skupDto.getSkup(), t);
return null;
}
}
}
@Transactional
@Component
public static class SkupDownShelfDBService {
@Autowired
private SellerOrderMapper sellerOrderMapper;
@Autowired
private SellerOrderGoodsMapper sellerOrderGoodsMapper;
@Autowired
private SellerTaskDetailMapper sellerTaskDetailMapper;
@Transactional
public void update(long taskId, SkupDto skupDto) {
SellerOrderGoods sellerOrderGoods = skupDto.getSellerOrderGoods();
//修改 sell_order_goods(状态)
SellerOrderGoods sogUpdateTo = new SellerOrderGoods();
sogUpdateTo.setStatus(SkupStatus.SELLER_CANCEL_SELL.getCode());
int num = sellerOrderGoodsMapper.updateByCondition(sellerOrderGoods, sogUpdateTo);
if (num != 1) {
throw new UfoServiceException(500, "down shelf seller order goods error by skup" + skupDto.getSkup());
}
//修改 seller_order(状态)
SellerOrder soc = new SellerOrder();
soc.setStatus(SellerOrderStatus.PLAY_SELF.getCode());
sellerOrderMapper.updateBySkups(soc, Lists.newArrayList(skupDto.getSkup()));
//增加明细状态
SellerTaskDetail detail = SellerTaskDetail.builder()
.taskId(taskId)
.skup(sellerOrderGoods.getId())
.amount(skupDto.getSellerOrder().getEarnestMoney())
.status(1)
.createTime(DateUtil.getCurrentTimeSecond()).build();
sellerTaskDetailMapper.insert(detail);
}
}
}
... ...
package com.yohoufo.order.service.handler;
import com.yohobuy.ufo.model.order.bo.MerchantOrderAttachInfo;
import com.yohobuy.ufo.model.order.bo.OrderInfo;
import com.yohoufo.dal.order.model.SellerOrder;
import com.yohoufo.dal.order.model.SellerWallet;
import com.yohoufo.dal.order.model.SellerWalletDetail;
import com.yohoufo.order.model.dto.*;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Created by jiexiang.wu on 2018/12/21.
*/
@Component
public class SellerIncrPriceTaskHandler extends AbstractSellerAdjustPriceTaskHandler {
@Override
protected boolean preHandle(SellerTaskResult result, SellerTaskDTO<ChangePricePrepareDTO> taskDto) {
ChangePricePrepareDTO cppDto = taskDto.getProcessData();
int uid = taskDto.getUid();
long oprId = taskDto.getTaskId();
BigDecimal preSalePrice = cppDto.getPreSalePrice(),
salePrice = cppDto.getSalePrice();
Map<Integer, SkupDto> skupMap = cppDto.getSkupMap();
SellerOrderComputeResult computeResult = cppDto.getComputeResult();
//1 划账
BigDecimal diffEarnestMoney = cppDto.getDiffEarnestMoney();
BigDecimal totalDiffMoney = diffEarnestMoney.multiply(new BigDecimal(skupMap.size()));
SellerWalletDetail.Type swdType = SellerWalletDetail.Type.ADD_PRICE;
MerchantOrderAttachInfo moai = MerchantOrderAttachInfo.builder().uid(uid)
.afterProductPrice(salePrice)
.beforeEarnestMoney(cppDto.getPreEarnestMoney().toPlainString())
.beforeProductPrice(preSalePrice)
.afterEarnestMoney(computeResult.getEarnestMoney().getEarnestMoney().toPlainString())
.earnestMoney(totalDiffMoney).productCount(skupMap.size())
.seriNo(String.valueOf(oprId))
.type(swdType.getValue()).build();
log.info("[{}-{}] pre use total earnest:{},diff earnest:{},num:{}", uid, oprId, totalDiffMoney, diffEarnestMoney, skupMap.size());
SellerWallet sellerWallet = cppDto.isSuper() ? new SellerWallet() : merchantOrderPaymentService.changePriceUseEarnest(uid, totalDiffMoney, moai);
result.sellerWallet = sellerWallet;
return Objects.nonNull(sellerWallet);
}
@Override
public void postHandle(SellerTaskResult result, SellerTaskDTO<ChangePricePrepareDTO> taskDto) {
ChangePricePrepareDTO cppDto = taskDto.getProcessData();
int uid = taskDto.getUid();
long taskId = taskDto.getTaskId();
if (result.failCnt > 0 && !cppDto.isSuper()) {
BigDecimal totalDiffMoney = cppDto.getDiffEarnestMoney().multiply(BigDecimal.valueOf(-1 * result.failCnt));
MerchantOrderAttachInfo moai = MerchantOrderAttachInfo.builder().uid(uid)
.afterProductPrice(cppDto.getSalePrice())
.beforeEarnestMoney(cppDto.getPreEarnestMoney().toPlainString())
.beforeProductPrice(cppDto.getPreSalePrice())
.afterEarnestMoney(cppDto.getComputeResult().getEarnestMoney().getEarnestMoney().toPlainString())
.earnestMoney(totalDiffMoney).productCount(result.failCnt)
.seriNo(String.valueOf(taskId))
.type(SellerWalletDetail.Type.SUBTRACT_PRICE.getValue()).build();
try {
//返还金额
log.error("[{}-{}] has {} skup fail,need to return amount:{} to sellerWallet", uid, taskId, result.failCnt, totalDiffMoney);
merchantOrderPaymentService.changePriceUseEarnest(uid, totalDiffMoney, moai);
log.error("[{}-{}] return amount:{} to sellerWallet success", uid, taskId, totalDiffMoney);
} catch (Exception ex) {
log.warn("[{}-{}] exception happened when return amount:{} to sellerWallet", uid, taskId, totalDiffMoney);
}
}
if (result.successCnt > 0) {
log.info("[{}-{}] has {} skup success,need to add wallet detail", uid, taskId, result.successCnt);
try {
if (!cppDto.isSuper()) {
//4 划账记录
List<SellerOrder> psoList = sellerOrderMapper.selectBySkups(result.successSkups);
List<OrderInfo> orderList = psoList.parallelStream().map(
so -> OrderInfo.builder().orderCode(so.getOrderCode()).amount(cppDto.getDiffEarnestMoney()).build())
.collect(Collectors.toList());
MerchantOrderAttachInfo attachInfo = MerchantOrderAttachInfo.builder().seriNo(String.valueOf(taskId)).build();
merchantOrderPaymentService.changePriceAddWalletDetail(result.sellerWallet, attachInfo, orderList);
log.info("[{}-{}] end to add wallet detail success", uid, taskId);
}
} catch (Exception ex) {
log.warn("[{}-{}] exception happened when add wallet detail", uid, taskId, ex);
}
//通知商品
try {
productProxyService.batchUpdatePrice(result.successSkups, cppDto.getSalePrice());
log.info("[{}-{}] notify product to update price for skups:{} success", uid, taskId, result.successSkups);
} catch (Exception ex) {
log.error("[{}-{}] exception happened when notify product to update price,skups:{},salePrice:{}",
uid, taskId, result.successSkups, cppDto.getSalePrice());
}
}
}
}
... ...
package com.yohoufo.order.service.impl;
import com.alibaba.fastjson.JSON;
import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
import com.yoho.error.ServiceError;
import com.yoho.error.exception.ServiceException;
... ... @@ -28,9 +29,7 @@ import com.yohoufo.order.event.ErpCancelSellerOrderEvent;
import com.yohoufo.order.event.EventHandlerContainer;
import com.yohoufo.order.event.OrderCancelEvent;
import com.yohoufo.order.model.SellerOrderContext;
import com.yohoufo.order.model.dto.ChangePricePrepareDTO;
import com.yohoufo.order.model.dto.SellerOrderComputeResult;
import com.yohoufo.order.model.dto.SkupDto;
import com.yohoufo.order.model.dto.*;
import com.yohoufo.order.model.request.OrderListRequest;
import com.yohoufo.order.model.request.OrderRequest;
import com.yohoufo.order.model.response.OrderDetailInfo;
... ... @@ -44,12 +43,8 @@ import com.yohoufo.order.service.cache.CacheCleaner;
import com.yohoufo.order.service.cache.CacheKeyBuilder;
import com.yohoufo.order.service.cache.OrderCacheService;
import com.yohoufo.order.service.concurrent.ThreadPoolFactory;
import com.yohoufo.order.service.handler.SellerOrderComputeHandler;
import com.yohoufo.order.service.handler.SellerOrderSubmitHandler;
import com.yohoufo.order.service.impl.processor.ChangePricePrepareProcessor;
import com.yohoufo.order.service.impl.processor.PriceComputePrepareProcessor;
import com.yohoufo.order.service.impl.processor.SellerBatchCancelPrepareProcessor;
import com.yohoufo.order.service.impl.processor.SellerOrderPrepareProcessor;
import com.yohoufo.order.service.handler.*;
import com.yohoufo.order.service.impl.processor.*;
import com.yohoufo.order.service.impl.visitor.OffShelveCancelCase;
import com.yohoufo.order.service.impl.visitor.UserCancelCase;
import com.yohoufo.order.service.proxy.InBoxFacade;
... ... @@ -134,11 +129,29 @@ public class SellerOrderService implements IOrderListService, IOrderDetailServi
private ChangePricePrepareProcessor changePricePrepareProcessor;
@Autowired
private AdjustPricePrepareProcessor adjustPricePrepareProcessor;
@Autowired
private SellerDownShelfPrepareProcessor sellerDownShelfPrepareProcessor;
@Autowired
private SellerFeeService sellerFeeService;
@Autowired
private UserProxyService userProxyService;
@Autowired
private SellerTaskProcessor sellerTaskProcessor;
@Autowired
private SellerIncrPriceTaskHandler sellerIncrPriceTaskHandler;
@Autowired
private SellerDecrPriceTaskHandler sellerDecrPriceTaskHandler;
@Autowired
private SellerDownShelfTaskHandler sellerDownShelfTaskHandler;
public SoldPrdComputeBo computePublishPrd(SellerOrderComputeReq req) throws GatewayException {
log.info("in computePublishPrd, req {}", req);
... ... @@ -176,6 +189,15 @@ public class SellerOrderService implements IOrderListService, IOrderDetailServi
return spc;
}
public SoldPrdComputeBo computeAdjustPrice(SellerBatchChangeReq req) throws GatewayException {
log.info("in computeAdjustPrice, req {}", req);
ChangePricePrepareDTO pcn = adjustPricePrepareProcessor.checkAndAcquire(req);
SellerOrderComputeResult computeResult = pcn.getComputeResult();
SoldPrdComputeBo spc = SellerOrderConvertor.computeResult2SoldPrdComputeBo(computeResult);
spc.setTips(pcn.getTips());
return spc;
}
private OrderSubmitResp publishSinglePrd(SellerOrderSubmitReq req, SellerOrderContext context) throws GatewayException {
... ... @@ -614,7 +636,8 @@ public class SellerOrderService implements IOrderListService, IOrderDetailServi
List<OrderInfo> orderList = psoList.parallelStream().map(
so -> OrderInfo.builder().orderCode(so.getOrderCode()).amount(diffEarnestMoney).build())
.collect(Collectors.toList());
merchantOrderPaymentService.changePriceAddWalletDetail(sellerWallet, orderList);
merchantOrderPaymentService.changePriceAddWalletDetail(sellerWallet, null,orderList);
}
successCnt = skupMap.size();
SellerOrderGoods sampleSog = cppDto.getBaseSellerOrderGoods();
... ... @@ -658,6 +681,60 @@ public class SellerOrderService implements IOrderListService, IOrderDetailServi
return skupDetailRKBs;
}
/**
* 批量调价
* @param req
* @return
*/
public BatchChangePriceResp batchAdjustPrice(SellerBatchChangeReq req) throws GatewayException {
//校验及计算金额
ChangePricePrepareDTO cppDto = adjustPricePrepareProcessor.checkAndAcquire(req);
SellerTaskDTO<ChangePricePrepareDTO> taskDTO = null;
if (cppDto.getSalePrice().compareTo(cppDto.getPreSalePrice()) > 0) {
//涨价
taskDTO = new SellerTaskDTO(req.getUid(),
SellerWalletDetail.Type.ADD_PRICE.getValue(),
sellerIncrPriceTaskHandler,
JSON.toJSONString(req),cppDto);
} else if (cppDto.getSalePrice().compareTo(cppDto.getPreSalePrice()) < 0) {
//降价
taskDTO = new SellerTaskDTO(req.getUid(),
SellerWalletDetail.Type.SUBTRACT_PRICE.getValue(),
sellerDecrPriceTaskHandler,
JSON.toJSONString(req),cppDto);
} else {
throw new UfoServiceException(400, "价格没有变化");
}
SellerTaskResult result = sellerTaskProcessor.process(taskDTO);
if (result.successCnt > 0) {
//todo
//清理缓存
}
//返还结果
BatchChangePriceResp resp = BatchChangePriceResp.builder().successCnt(result.successCnt).failCnt(result.failCnt)
.tips(cppDto.getTips()).build();
ProductProxyService.PrdPrice prdPrice = cppDto.getPrdPrice();
if (prdPrice != null && prdPrice.getLeastPrice() != null) {
resp.setLeastPrice(prdPrice.getLeastPrice());
}
return resp;
}
public boolean batchDownShelf(SellerBatchChangeReq req) {
Map<Integer, SkupDto> skupDtoMap = sellerDownShelfPrepareProcessor.checkAndAcquire(req);
SellerTaskDTO<Map<Integer, SkupDto>> taskDTO = new SellerTaskDTO(req.getUid(),
SellerWalletDetail.Type.SELLER_OFF.getValue(),
sellerDownShelfTaskHandler,
JSON.toJSONString(req),
skupDtoMap);
SellerTaskResult result = sellerTaskProcessor.process(taskDTO);
return result.successCnt > 0 ? true : false;
}
private static final int MAX_DEAL = 10;
... ...
package com.yohoufo.order.service.impl.processor;
import com.yohobuy.ufo.model.order.common.OrderStatus;
import com.yohobuy.ufo.model.order.req.SellerBaseChangeReq;
import com.yohoufo.common.exception.GatewayException;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.dal.order.BuyerOrderGoodsMapper;
import com.yohoufo.dal.order.BuyerOrderMapper;
import com.yohoufo.dal.order.SellerOrderMapper;
import com.yohoufo.dal.order.model.BuyerOrder;
import com.yohoufo.dal.order.model.BuyerOrderGoods;
import com.yohoufo.dal.order.model.SellerOrder;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import com.yohoufo.order.model.dto.ChangePricePrepareDTO;
import com.yohoufo.order.model.dto.SellerOrderComputeResult;
import com.yohoufo.order.model.dto.SkupDto;
import com.yohoufo.order.service.handler.SellerOrderComputeHandler;
import com.yohoufo.order.service.impl.SellerService;
import com.yohoufo.order.service.proxy.ProductProxyService;
import com.yohoufo.order.utils.LoggerUtils;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Created by jiexiang.wu on 2018/12/19.
*/
public abstract class AbstractChangePricePrepareProcessor<T extends SellerBaseChangeReq> {
protected final Logger logger = LoggerUtils.getSellerOrderLogger();
@Autowired
private BuyerOrderGoodsMapper buyerOrderGoodsMapper;
@Autowired
private BuyerOrderMapper buyerOrderMapper;
@Autowired
private SellerOrderMapper sellerOrderMapper;
@Autowired
private SellerOrderPrepareProcessor sellerOrderPrepareProcessor;
@Autowired
private SellerOrderComputeHandler computeHandler;
@Autowired
private PriceComputePrepareProcessor priceComputePrepareProcessor;
@Autowired
private SellerService sellerService;
public ChangePricePrepareDTO checkAndAcquire(T req) throws GatewayException {
int uid = req.getUid();
if (uid <= 0){
logger.warn("ChangePrice checkAndAcquire uid illegal , req {}", req);
throw new UfoServiceException(400, "参数[uid]错误");
}
if(!sellerOrderPrepareProcessor.checkIsEntry(uid)){
logger.warn("ChangePrice checkAndAcquire uid is not entry shop , req {}", req);
throw new UfoServiceException(400, "您不是入驻商家");
}
// String skupList = req.getSkupList();
// if (StringUtils.isBlank(skupList)){
// logger.warn("ChangePrice checkAndAcquire uid illegal , req {}", req);
// throw new UfoServiceException(400, "参数[skupList]为空");
// }
//考虑到并发,需要进行过滤,将不是出售中状态的skup排除掉;
//不做过滤导致后面的数量 扣费检查都可能不对
// List<String> skupStrList = Splitter.on(',').trimResults().omitEmptyStrings().splitToList(skupList);
// List<Integer> needChangePriceSkupList = skupStrList.parallelStream().map(Integer::valueOf).collect(Collectors.toList());
//check batch no
// Long batchNo = checkNAcquireBatchNo(req.getBatchNo(), req);
//检查是否有买家下单,返回的是可售 待买家付款的skup
Map<Integer, SkupDto> skupOfSalingMap = checkExistWaitingBuyerPay(req);
BigDecimal salePrice = priceComputePrepareProcessor.checkAndAcquireSalePrice(req.getPrice());
//若needChangePriceSkupList中有skup出现不存在于skupOfSalingMap keys中,说明该skup走到了其他状态中
Map<Integer, SkupDto> skupMap = checkNeedProcessSkups(getExpectedSkups(req), req.getOldPrice(), salePrice, skupOfSalingMap);
// //
SkupDto sampleSkupDto = skupMap.values().iterator().next();
int sampleSkup = sampleSkupDto.getSkup();
SellerOrderGoods sampleSog = sampleSkupDto.getSellerOrderGoods();
BigDecimal preSalePrice = sampleSog.getGoodsPrice();
// if (preSalePrice.compareTo(salePrice) == 0){
// throw new UfoServiceException(401, "前后价格没有变化");
// }
SellerOrder sellerOrder = sellerOrderMapper.selectBySkup(sampleSkup);
BigDecimal sourceEM = sellerOrder.getEarnestMoney();
int storageId = sampleSog.getStorageId();
String tips = null;
ProductProxyService.PrdPrice prdPrice;
prdPrice = sellerOrderPrepareProcessor.checkPrice(storageId, salePrice, req.isShowPriceError());
try {
sellerOrderPrepareProcessor.checkSuggestPrice(prdPrice, salePrice);
}catch (UfoServiceException ex){
tips = ex.getErrorMessage();
}
// compute every fee from price
SellerOrderComputeResult computeResult = computeHandler.compute(salePrice);
int num = skupMap.size();
//作为入驻商户 检查钱包
BigDecimal targetEM = computeResult.getEarnestMoney().getEarnestMoney();
BigDecimal diffEarnestMoney = calDiffOfEM(sourceEM,targetEM);
boolean isSuper = sellerService.isSuperEntrySeller(uid);
if (diffEarnestMoney.compareTo(BigDecimal.ZERO)>0){
sellerOrderPrepareProcessor.checkNGetMergeEarnestMoney(uid, diffEarnestMoney, num, salePrice, isSuper);
}
sellerOrderPrepareProcessor.checkIncome(storageId, computeResult.getIncome());
return ChangePricePrepareDTO.builder()
.baseSellerOrderGoods(sampleSog)
.prdPrice(prdPrice)
.salePrice(salePrice)
.diffEarnestMoney(diffEarnestMoney)
.skupMap(skupMap)
.computeResult(computeResult)
.preEarnestMoney(sourceEM)
.preSalePrice(preSalePrice)
.tips(tips).isSuper(isSuper)
.build();
}
/**
* skup个数及价格校验
* @param expectedSkups 期望的skup
* @param oldPrice 老价
* @param newPrice 新价
* @param skupOfSalingMap
* @return
*/
protected abstract Map<Integer, SkupDto> checkNeedProcessSkups(List<Integer> expectedSkups,
BigDecimal oldPrice,
BigDecimal newPrice,
Map<Integer, SkupDto> skupOfSalingMap);
// Map<Integer, SkupDto> checkNeedProcessSkups(List<Integer> needChangePriceSkupList, Map<Integer, SkupDto> skupOfSalingMap){
// Map<Integer, SkupDto> map = new HashMap<>(needChangePriceSkupList.size());
//
// for(Integer skup: needChangePriceSkupList) {
//
// if (!skupOfSalingMap.containsKey(skup)) {
// logger.warn("ChangePrice checkNeedProcessSkups skup is in other status , skup {}", skup);
// throw new UfoServiceException(501, "部分商品不可调价");
// }
// map.put(skup, skupOfSalingMap.get(skup));
// }
//
// return map;
// }
private BigDecimal calDiffOfEM(BigDecimal sourceEM, BigDecimal targetEM){
return targetEM.subtract(sourceEM);
}
// private Long checkNAcquireBatchNo(String batchNoStr, BatchChangePriceReq req){
// Long batchNo = null;
// boolean isIllegalBatchNo;
// try {
// isIllegalBatchNo = (StringUtils.isBlank(batchNoStr) || (batchNo = Long.valueOf(batchNoStr)) <= 0L);
//
// }catch (Exception ex){
// isIllegalBatchNo = true;
// logger.warn("ChangePrice checkAndAcquire batchNoStr illegal , req {}", req, ex);
// }
//
// if (isIllegalBatchNo){
// throw new UfoServiceException(400, "参数[batchNoStr]非法");
// }
// return batchNo;
// }
/**
* 获取期望变价的skup
* @param req
* @return
*/
protected abstract List<Integer> getExpectedSkups(T req);
/**
* 获取实际调价的列表
* @param req
* @return
*/
protected abstract List<SellerOrderGoods> getRealSkupOrderGoodsList(T req);
private Map<Integer, SkupDto> checkExistWaitingBuyerPay(T req){
// SellerOrderGoods condition = new SellerOrderGoods();
// condition.setBatchNo(batchNo);
// List<SellerOrderGoods> sellerOrderGoodList = sellerOrderGoodsMapper.selectByBatchNo(condition, Arrays.asList(SkupStatus.CAN_SELL.getCode(), SkupStatus.SELL_OUT.getCode()));
List<SellerOrderGoods> sellerOrderGoodList = getRealSkupOrderGoodsList(req);
if (CollectionUtils.isEmpty(sellerOrderGoodList)){
logger.warn("ChangePrice checkAndAcquire not find skups by req {}", req);
throw new UfoServiceException(501, "商品不能变价");
}
List<Integer> skups = sellerOrderGoodList.parallelStream().map(SellerOrderGoods::getId).collect(Collectors.toList());
logger.info("batch change price checkExistWaitingBuyerPay req {} skups {}", req, skups);
List<BuyerOrderGoods> buyerOrderGoodsList = buyerOrderGoodsMapper.selectBySkups(skups);
List<BuyerOrder> buyerOrderList = null;
if (CollectionUtils.isNotEmpty(buyerOrderGoodsList)){
List<Long> orderCodeList = buyerOrderGoodsList.parallelStream()
.map(BuyerOrderGoods::getOrderCode).collect(Collectors.toList());
buyerOrderList = buyerOrderMapper.selectByOrderCodes(orderCodeList, Arrays.asList(OrderStatus.WAITING_PAY.getCode()));
}
if (CollectionUtils.isNotEmpty(buyerOrderList)){
List<Long> waitingPayOrderCodes = buyerOrderList.parallelStream().map(BuyerOrder::getOrderCode).collect(Collectors.toList());
logger.warn("ChangePrice checkAndAcquire exist waiting pay skup , req {} waitingPayOrderCodes {}", req, waitingPayOrderCodes);
throw new UfoServiceException(400, "部分商品正在等待买家支付");
}
return sellerOrderGoodList.parallelStream().collect(Collectors.toMap(SellerOrderGoods::getId,
(sog)-> SkupDto.builder().skup(sog.getId()).sellerOrderGoods(sog).batchNo(sog.getBatchNo()).build()));
}
}
... ...
package com.yohoufo.order.service.impl.processor;
import com.yohobuy.ufo.model.order.common.SkupStatus;
import com.yohobuy.ufo.model.order.req.SellerBatchChangeReq;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.dal.order.SellerOrderGoodsMapper;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import com.yohoufo.order.common.Payment;
import com.yohoufo.order.model.dto.SkupDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by jiexiang.wu on 2018/12/19.
*/
@Service
public class AdjustPricePrepareProcessor extends AbstractChangePricePrepareProcessor<SellerBatchChangeReq> {
@Autowired
private SellerOrderGoodsMapper sellerOrderGoodsMapper;
@Override
protected List<SellerOrderGoods> getRealSkupOrderGoodsList(SellerBatchChangeReq req) {
SellerOrderGoods condition = new SellerOrderGoods();
condition.setUid(req.getUid());
condition.setProductId(req.getProductId());
condition.setStorageId(req.getStorageId());
condition.setGoodsPrice(req.getOldPrice());
return sellerOrderGoodsMapper.selectByPayment(Payment.WALLET.getCode(), condition, Arrays.asList(SkupStatus.CAN_SELL.getCode()),req.getNum());
}
@Override
protected List<Integer> getExpectedSkups(SellerBatchChangeReq req) {
return null;
}
/**
* @param expectedSkups 期望的skup 为null
* @param oldPrice 老价
* @param newPrice 新价
* @param skupOfSalingMap
* @return
*/
@Override
protected Map<Integer, SkupDto> checkNeedProcessSkups(List<Integer> expectedSkups, BigDecimal oldPrice, BigDecimal newPrice, Map<Integer, SkupDto> skupOfSalingMap) {
Assert.notEmpty(skupOfSalingMap, "skupOfSalingMap must not be empty");
Map<Integer, SkupDto> map = new HashMap<>(skupOfSalingMap.size());
for (Map.Entry<Integer, SkupDto> entry : skupOfSalingMap.entrySet()) {
Integer skup = entry.getKey();
SkupDto skupDto = entry.getValue();
SellerOrderGoods sellerOrderGoods = skupDto.getSellerOrderGoods();
//校验价格
if (sellerOrderGoods.getGoodsPrice().compareTo(oldPrice) != 0) {
logger.warn("skup:{} goodsPrice:{} and oldPrice:{} must be equals",
skup, sellerOrderGoods.getGoodsPrice(), newPrice);
throw new UfoServiceException(401, "当前价格不对");
}
if (sellerOrderGoods.getGoodsPrice().compareTo(newPrice) == 0) {
logger.warn("skup:{} goodsPrice:{} and newPrice:{} must not be equals",
skup, sellerOrderGoods.getGoodsPrice(), newPrice);
throw new UfoServiceException(401, "前后价格没有变化");
}
map.put(skup, skupDto);
}
return map;
}
}
... ...
package com.yohoufo.order.service.impl.processor;
import com.google.common.base.Splitter;
import com.yohobuy.ufo.model.order.common.OrderStatus;
import com.yohobuy.ufo.model.order.common.SkupStatus;
import com.yohobuy.ufo.model.order.req.BatchChangePriceReq;
import com.yohoufo.common.exception.GatewayException;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.common.utils.BigDecimalHelper;
import com.yohoufo.dal.order.BuyerOrderGoodsMapper;
import com.yohoufo.dal.order.BuyerOrderMapper;
import com.yohoufo.dal.order.SellerOrderGoodsMapper;
import com.yohoufo.dal.order.SellerOrderMapper;
import com.yohoufo.dal.order.model.BuyerOrder;
import com.yohoufo.dal.order.model.BuyerOrderGoods;
import com.yohoufo.dal.order.model.SellerOrder;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import com.yohoufo.order.model.dto.ChangePricePrepareDTO;
import com.yohoufo.order.model.dto.SellerOrderComputeResult;
import com.yohoufo.order.model.dto.SkupDto;
import com.yohoufo.order.service.handler.SellerOrderComputeHandler;
import com.yohoufo.order.service.impl.SellerService;
import com.yohoufo.order.service.proxy.ProductProxyService;
import com.yohoufo.order.utils.LoggerUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.math.BigDecimal;
import java.util.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Created by chao.chen on 2018/11/21.
* 根据批次号来调价
*/
@Service
public class ChangePricePrepareProcessor {
private final Logger logger = LoggerUtils.getSellerOrderLogger();
@Autowired
private BuyerOrderGoodsMapper buyerOrderGoodsMapper;
@Autowired
private BuyerOrderMapper buyerOrderMapper;
@Autowired
private SellerOrderMapper sellerOrderMapper;
public class ChangePricePrepareProcessor extends AbstractChangePricePrepareProcessor<BatchChangePriceReq> {
@Autowired
private SellerOrderGoodsMapper sellerOrderGoodsMapper;
@Autowired
private SellerOrderPrepareProcessor sellerOrderPrepareProcessor;
@Autowired
private SellerOrderComputeHandler computeHandler;
@Autowired
private PriceComputePrepareProcessor priceComputePrepareProcessor;
@Autowired
private SellerService sellerService;
@Override
public ChangePricePrepareDTO checkAndAcquire(BatchChangePriceReq req) throws GatewayException {
int uid = req.getUid();
if (uid <= 0){
logger.warn("ChangePrice checkAndAcquire uid illegal , req {}", req);
throw new UfoServiceException(400, "参数[uid]错误");
}
if(!sellerOrderPrepareProcessor.checkIsEntry(uid)){
logger.warn("ChangePrice checkAndAcquire uid is not entry shop , req {}", req);
throw new UfoServiceException(400, "您不是入驻商家");
}
String skupList = req.getSkupList();
if (StringUtils.isBlank(skupList)){
if (StringUtils.isBlank(skupList)) {
logger.warn("ChangePrice checkAndAcquire uid illegal , req {}", req);
throw new UfoServiceException(400, "参数[skupList]为空");
}
//考虑到并发,需要进行过滤,将不是出售中状态的skup排除掉;
//不做过滤导致后面的数量 扣费检查都可能不对
List<String> skupStrList = Splitter.on(',').trimResults().omitEmptyStrings().splitToList(skupList);
List<Integer> needChangePriceSkupList = skupStrList.parallelStream().map(Integer::valueOf).collect(Collectors.toList());
//check batch no
Long batchNo = checkNAcquireBatchNo(req.getBatchNo(), req);
BigDecimal salePrice = priceComputePrepareProcessor.checkAndAcquireSalePrice(req.getPrice());
//检查是否有买家下单,返回的是可售 待买家付款的skup
Map<Integer, SkupDto> skupOfSalingMap = checkExistWaitingBuyerPay(batchNo, req);
//若needChangePriceSkupList中有skup出现不存在于skupOfSalingMap keys中,说明该skup走到了其他状态中
Map<Integer, SkupDto> skupMap = checkNeedProcessSkups(needChangePriceSkupList,skupOfSalingMap);
//
SkupDto sampleSkupDto = skupMap.values().iterator().next();
int sampleSkup = sampleSkupDto.getSkup();
SellerOrderGoods sampleSog = sampleSkupDto.getSellerOrderGoods();
BigDecimal preSalePrice = sampleSog.getGoodsPrice();
if (preSalePrice.compareTo(salePrice) == 0){
throw new UfoServiceException(401, "前后价格没有变化");
}
return super.checkAndAcquire(req);
}
SellerOrder sellerOrder = sellerOrderMapper.selectBySkup(sampleSkup);
BigDecimal sourceEM = sellerOrder.getEarnestMoney();
int storageId = sampleSog.getStorageId();
String tips = null;
ProductProxyService.PrdPrice prdPrice;
prdPrice = sellerOrderPrepareProcessor.checkPrice(storageId, salePrice, req.isShowPriceError());
try {
sellerOrderPrepareProcessor.checkSuggestPrice(prdPrice, salePrice);
}catch (UfoServiceException ex){
tips = ex.getErrorMessage();
}
// compute every fee from price
SellerOrderComputeResult computeResult = computeHandler.compute(salePrice);
int num = skupMap.size();
//作为入驻商户 检查钱包
BigDecimal targetEM = computeResult.getEarnestMoney().getEarnestMoney();
BigDecimal diffEarnestMoney = calDiffOfEM(sourceEM,targetEM);
boolean isSuper = sellerService.isSuperEntrySeller(uid);
if (diffEarnestMoney.compareTo(BigDecimal.ZERO)>0){
sellerOrderPrepareProcessor.checkNGetMergeEarnestMoney(uid, diffEarnestMoney, num, salePrice, isSuper);
}
sellerOrderPrepareProcessor.checkIncome(storageId, computeResult.getIncome());
return ChangePricePrepareDTO.builder()
.baseSellerOrderGoods(sampleSog)
.prdPrice(prdPrice)
.salePrice(salePrice)
.diffEarnestMoney(diffEarnestMoney)
.skupMap(skupMap)
.computeResult(computeResult)
.preEarnestMoney(sourceEM)
.preSalePrice(preSalePrice)
.tips(tips).isSuper(isSuper)
.build();
@Override
protected List<Integer> getExpectedSkups(BatchChangePriceReq req) {
List<String> skupStrList = Splitter.on(',').trimResults().omitEmptyStrings().splitToList(req.getSkupList());
return skupStrList.parallelStream().map(Integer::valueOf).collect(Collectors.toList());
}
@Override
protected List<SellerOrderGoods> getRealSkupOrderGoodsList(BatchChangePriceReq req) {
Long batchNo = checkNAcquireBatchNo(req.getBatchNo());
SellerOrderGoods condition = new SellerOrderGoods();
condition.setBatchNo(batchNo);
//按照批次,同一个批次不需要有两个价格,需要排除支付中的订单
return sellerOrderGoodsMapper.selectByBatchNo(condition, Arrays.asList(SkupStatus.CAN_SELL.getCode(), SkupStatus.SELL_OUT.getCode()));
}
Map<Integer, SkupDto> checkNeedProcessSkups(List<Integer> needChangePriceSkupList, Map<Integer, SkupDto> skupOfSalingMap){
Map<Integer, SkupDto> map = new HashMap<>(needChangePriceSkupList.size());
@Override
protected Map<Integer, SkupDto> checkNeedProcessSkups(List<Integer> expectedSkups,
BigDecimal oldPrice,
BigDecimal newPrice,
Map<Integer, SkupDto> skupOfSalingMap) {
Assert.notEmpty(expectedSkups,"expectedSkups must not be empty");
Assert.notEmpty(skupOfSalingMap,"skupOfSalingMap must not be empty");
Map<Integer, SkupDto> map = new HashMap<>(expectedSkups.size());
for(Integer skup: needChangePriceSkupList) {
for (Integer skup : expectedSkups) {
if (!skupOfSalingMap.containsKey(skup)) {
logger.warn("ChangePrice checkNeedProcessSkups skup is in other status , skup {}", skup);
throw new UfoServiceException(501, "部分商品不可调价");
}
SellerOrderGoods sellerOrderGoods = skupOfSalingMap.get(skup).getSellerOrderGoods();
//校验价格
if (sellerOrderGoods.getGoodsPrice().compareTo(newPrice) == 0) {
logger.warn("skup:{} goodsPrice:{} and newPrice:{} must not be equals",
skup, sellerOrderGoods.getGoodsPrice(), newPrice);
throw new UfoServiceException(401, "前后价格没有变化");
}
map.put(skup, skupOfSalingMap.get(skup));
}
return map;
}
private BigDecimal calDiffOfEM(BigDecimal sourceEM, BigDecimal targetEM){
return targetEM.subtract(sourceEM);
}
private Long checkNAcquireBatchNo(String batchNoStr, BatchChangePriceReq req){
private Long checkNAcquireBatchNo(String batchNoStr) {
Long batchNo = null;
boolean isIllegalBatchNo;
try {
isIllegalBatchNo = (StringUtils.isBlank(batchNoStr) || (batchNo = Long.valueOf(batchNoStr)) <= 0L);
}catch (Exception ex){
} catch (Exception ex) {
isIllegalBatchNo = true;
logger.warn("ChangePrice checkAndAcquire batchNoStr illegal , req {}", req, ex);
logger.warn("ChangePrice checkAndAcquire batchNoStr illegal , batchNoStr {}", batchNoStr, ex);
}
if (isIllegalBatchNo){
if (isIllegalBatchNo) {
throw new UfoServiceException(400, "参数[batchNoStr]非法");
}
return batchNo;
}
private Map<Integer, SkupDto> checkExistWaitingBuyerPay(long batchNo, BatchChangePriceReq req){
SellerOrderGoods condition = new SellerOrderGoods();
condition.setBatchNo(batchNo);
List<SellerOrderGoods> sellerOrderGoodList = sellerOrderGoodsMapper.selectByBatchNo(condition, Arrays.asList(SkupStatus.CAN_SELL.getCode(), SkupStatus.SELL_OUT.getCode()));
if (CollectionUtils.isEmpty(sellerOrderGoodList)){
logger.warn("ChangePrice checkAndAcquire not find skups by batchNo, req {}", req);
throw new UfoServiceException(501, "商品不能变价");
}
List<Integer> skups = sellerOrderGoodList.parallelStream().map(SellerOrderGoods::getId).collect(Collectors.toList());
logger.info("batch change price checkExistWaitingBuyerPay req {} skups {}", req, skups);
List<BuyerOrderGoods> buyerOrderGoodsList = buyerOrderGoodsMapper.selectBySkups(skups);
List<BuyerOrder> buyerOrderList = null;
if (CollectionUtils.isNotEmpty(buyerOrderGoodsList)){
List<Long> orderCodeList = buyerOrderGoodsList.parallelStream()
.map(BuyerOrderGoods::getOrderCode).collect(Collectors.toList());
buyerOrderList = buyerOrderMapper.selectByOrderCodes(orderCodeList, Arrays.asList(OrderStatus.WAITING_PAY.getCode()));
}
if (CollectionUtils.isNotEmpty(buyerOrderList)){
List<Long> waitingPayOrderCodes = buyerOrderList.parallelStream().map(BuyerOrder::getOrderCode).collect(Collectors.toList());
logger.warn("ChangePrice checkAndAcquire exist waiting pay skup , req {} waitingPayOrderCodes {}", req, waitingPayOrderCodes);
throw new UfoServiceException(400, "部分商品正在等待买家支付");
}
return sellerOrderGoodList.parallelStream().collect(Collectors.toMap(SellerOrderGoods::getId,
(sog)-> SkupDto.builder().skup(sog.getId()).sellerOrderGoods(sog).batchNo(sog.getBatchNo()).build()));
}
}
... ...
package com.yohoufo.order.service.impl.processor;
import com.yohobuy.ufo.model.order.common.SkupStatus;
import com.yohobuy.ufo.model.order.req.SellerBatchChangeReq;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.dal.order.SellerOrderGoodsMapper;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import com.yohoufo.order.common.Payment;
import com.yohoufo.order.model.dto.SkupDto;
import com.yohoufo.order.utils.LoggerUtils;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Created by jiexiang.wu on 2018/12/21.
*/
@Component
public class SellerDownShelfPrepareProcessor {
private final Logger logger = LoggerUtils.getSellerOrderLogger();
final static List<Integer> CAN_OFF_STATUS = Arrays.asList(SkupStatus.CAN_SELL.getCode());
@Autowired
private SellerOrderPrepareProcessor sellerOrderPrepareProcessor;
@Autowired
private SellerOrderGoodsMapper sellerOrderGoodsMapper;
public Map<Integer, SkupDto> checkAndAcquire(SellerBatchChangeReq req) {
int uid = req.getUid();
if (uid <= 0) {
logger.warn("batch off shelve checkAndAcquire uid illegal , req {}", req);
throw new UfoServiceException(400, "参数[uid]错误");
}
int num = req.getNum();
if (num <= 0) {
logger.warn("batch off shelve checkAndAcquire num is illegal, req {}", req);
throw new UfoServiceException(400, "数量不合法");
}
if (!sellerOrderPrepareProcessor.checkIsEntry(uid)) {
logger.warn("batch off shelve checkAndAcquire uid is not entry shop , req {}", req);
throw new UfoServiceException(400, "您不是入驻商家");
}
BigDecimal oldPrice = req.getOldPrice();
if (Objects.isNull(oldPrice)) {
logger.warn("batch off shelve checkAndAcquire uid illegal , req {}", req);
throw new UfoServiceException(400, "参数[oldPrice]不合法");
}
//检查
Map<Integer, SkupDto> skupMap = checkNeedProcessSkups(req);
return skupMap;
}
private Map<Integer, SkupDto> checkNeedProcessSkups(SellerBatchChangeReq req) {
SellerOrderGoods condition = new SellerOrderGoods();
condition.setUid(req.getUid());
condition.setProductId(req.getProductId());
condition.setStorageId(req.getStorageId());
condition.setGoodsPrice(req.getOldPrice());
List<SellerOrderGoods> sellerOrderGoodList = sellerOrderGoodsMapper.selectByPayment(Payment.WALLET.getCode(), condition, CAN_OFF_STATUS, req.getNum());
if (CollectionUtils.isEmpty(sellerOrderGoodList)) {
logger.warn("batch off shelve checkAndAcquire not find skups by batchNo, req {}", req);
throw new UfoServiceException(501, "商品不存在");
}
List<Integer> skups = sellerOrderGoodList.parallelStream().map(SellerOrderGoods::getId).collect(Collectors.toList());
logger.info("batch off shelve price checkExistWaitingBuyerPay req {} skups in db {}", req, skups);
return sellerOrderGoodList.parallelStream().collect(Collectors.toMap(SellerOrderGoods::getId,
(sog) -> SkupDto.builder().skup(sog.getId()).sellerOrderGoods(sog).batchNo(sog.getBatchNo()).build()));
}
}
... ...
package com.yohoufo.order.service.impl.processor;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.dal.order.SellerTaskMapper;
import com.yohoufo.dal.order.model.SellerTask;
import com.yohoufo.order.model.dto.*;
import com.yohoufo.order.service.handler.ISellerTaskHandler;
import com.yohoufo.order.utils.LoggerUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Created by jiexiang.wu on 2018/12/21.
*/
@Component
public class SellerTaskProcessor {
private final Logger log = LoggerUtils.getSellerOrderLogger();
@Autowired
private SellerTaskMapper sellerTaskMapper;
public SellerTaskResult process(SellerTaskDTO taskDto) {
int uid = taskDto.getUid();
log.info("[{}] begin to process", taskDto.getUid());
//记录操作记录
taskDto.setTaskId(createTask(taskDto));
log.info("[{}-{}] create seller task", uid, taskDto.getTaskId());
SellerTaskResult result = doProcess(taskDto);
log.info("[{}-{}] end to process", uid, taskDto.getTaskId());
return result;
}
/**
* @param taskDto
* @return
*/
private long createTask(SellerTaskDTO taskDto) {
SellerTask record = SellerTask.builder()
.uid(taskDto.getUid())
.type(taskDto.getTaskType())
.taskDesc(taskDto.getTaskDesc())
.createTime(DateUtil.getCurrentTimeSecond()).build();
sellerTaskMapper.insert(record);
return record.getId();
}
private SellerTaskResult doProcess(SellerTaskDTO sbpDto) {
ISellerTaskHandler handler = sbpDto.getTaskHandler();
return handler.handle(sbpDto);
}
}
... ...
... ... @@ -18,7 +18,7 @@
<properties>
<qiniu.version>7.0.5</qiniu.version>
<project-name>yohoufo-fore</project-name>
<model.version>3.0-SNAPSHOT</model.version>
<model.version>4.0-SNAPSHOT</model.version>
</properties>
<dependencyManagement>
... ... @@ -127,6 +127,7 @@
<module>deploy</module>
<module>inbox</module>
<module>msg-center</module>
<module>../concurrent</module>
</modules>
... ...
... ... @@ -59,7 +59,8 @@ datasources:
- com.yohoufo.dal.order.StoredSellerMapper
- com.yohoufo.dal.order.SuperEntrySellerMapper
- com.yohoufo.dal.order.QiniuLiveRecordMapper
- com.yohoufo.dal.order.SellerTaskMapper
- com.yohoufo.dal.order.SellerTaskDetailMapper
ufo_promotion:
servers:
- 192.168.102.219:3306
... ...
... ... @@ -59,6 +59,8 @@ datasources:
- com.yohoufo.dal.order.StoredSellerMapper
- com.yohoufo.dal.order.SuperEntrySellerMapper
- com.yohoufo.dal.order.QiniuLiveRecordMapper
- com.yohoufo.dal.order.SellerTaskMapper
- com.yohoufo.dal.order.SellerTaskDetailMapper
ufo_promotion:
servers:
... ...