Authored by LUOXC

Merge branch 'test6.9.13' of http://git.yoho.cn/ufo/yohoufo-fore into test6.9.13

Showing 34 changed files with 465 additions and 141 deletions
... ... @@ -91,4 +91,11 @@ public interface StoragePriceMapper {
* @return
*/
int updateBatchDepotNum(@Param("skupList") List<Integer> skupList, @Param("depotNum") Integer depotNo);
/**
* 查询现货各尺码的最低价
* @param productId
* @return
*/
List<StoragePrice> selectInStockLeastPByProductId(@Param("productId") Integer productId);
}
\ No newline at end of file
... ...
... ... @@ -29,7 +29,7 @@ public class BidStoragePrice {
private Integer createTime;
private Integer skupType;
private Integer attribute;
//0:未上架,1:上架
private Integer status;
... ...
... ... @@ -13,6 +13,8 @@ public interface IZhiMaCertDao {
int updateValidStatusByPrimaryKey(int id);
int updateIdleFishValidStatus(int id);
int updatePhotoStatusByPrimaryKeyAndValidStatus(@Param("id")int id,@Param("validPhoto")int validPhoto);
int updateBizNoByByPrimaryKey(@Param("id")int id, @Param("bizNo")String bizNo);
... ...
... ... @@ -11,11 +11,11 @@
<result column="price" jdbcType="DECIMAL" property="price"/>
<result column="update_time" jdbcType="INTEGER" property="updateTime"/>
<result column="create_time" jdbcType="INTEGER" property="createTime"/>
<result column="skup_type" jdbcType="INTEGER" property="skupType"/>
<result column="attribute" jdbcType="INTEGER" property="attribute"/>
<result column="status" jdbcType="INTEGER" property="status"/>
</resultMap>
<sql id="Base_Column_List">
id, skup, product_id, goods_id, storage_id, bid_uid,price, update_time,create_time,skup_type,status
id, skup, product_id, goods_id, storage_id, bid_uid,price, update_time,create_time,attribute,status
</sql>
<insert id="insert" parameterType="com.yohoufo.dal.product.model.BidStoragePrice">
insert into bid_storage_price (id, skup, product_id, goods_id,
... ... @@ -23,7 +23,7 @@
values (#{id,jdbcType=INTEGER}, #{skup,jdbcType=INTEGER}, #{productId,jdbcType=INTEGER}, #{goodsId,jdbcType=INTEGER},
#{storageId,jdbcType=INTEGER}, #{bidUid,jdbcType=INTEGER},
#{price,jdbcType=DECIMAL}, #{updateTime,jdbcType=INTEGER},
#{createTime,jdbcType=INTEGER},#{skupType,jdbcType=INTEGER},#{status,jdbcType=INTEGER})
#{createTime,jdbcType=INTEGER},#{attribute,jdbcType=INTEGER},#{status,jdbcType=INTEGER})
</insert>
<select id="selectBySkup" parameterType="java.lang.Integer" resultMap="BaseResultMap">
... ...
... ... @@ -270,4 +270,13 @@
#{item}
</foreach>
</update>
<select id="selectInStockLeastPByProductId" resultMap="BaseResultMap">
select * from (
select id, skup, storage_id, price, status, pre_sale_flag, region
from storage_price
where status = 1 and product_id = #{productId} and is_hide = 0 and region = 0 and pre_sale_flag = 0
order by storage_id,price asc limit 1000000
) a group by storage_id
</select>
</mapper>
\ No newline at end of file
... ...
... ... @@ -100,6 +100,12 @@
where id = #{id}
</update>
<update id="updateIdleFishValidStatus">
update zhima_cert
set valid_status = 1, is_idlefish = 1
where id = #{id}
</update>
<update id="updatePhotoToValidByPK">
update zhima_cert
set image_url = #{imageUrl} , valid_photo = #{validPhoto}
... ...
... ... @@ -6,6 +6,8 @@ import com.yohoufo.order.constants.BidTimeLimit;
import com.yohoufo.order.model.request.BuyerBidChangePriceRequest;
import com.yohoufo.order.model.request.BuyerBidPublishRequest;
import com.yohoufo.order.model.response.BidComputeResponse;
import com.yohoufo.order.model.response.BidConfigResponse;
import com.yohoufo.order.model.response.BidPrePublishResponse;
import com.yohoufo.order.model.response.BidPublishResponse;
import com.yohoufo.order.service.impl.BuyerBidPublishService;
import com.yohoufo.order.service.impl.BuyerBidPriceService;
... ... @@ -34,6 +36,16 @@ public class BuyerBidController {
private BuyerBidPriceService buyerBidPriceService;
/**
* 求购基础信息
*
* @return
*/
@RequestMapping(params = "method=ufo.buyer.bid.config")
public ApiResponse config() {
return new ApiResponse.ApiResponseBuilder().code(200).data(new BidConfigResponse()).message("ok").build();
}
/**
* 出价计算
*
* @param uid
... ... @@ -55,6 +67,31 @@ public class BuyerBidController {
return new ApiResponse.ApiResponseBuilder().code(200).data(response).message("ok").build();
}
/**
* 预发布
* 计算费用并提示
*
* @param uid
* @param storage_id
* @param price
*/
@RequestMapping(params = "method=ufo.buyer.bid.prePublish")
public ApiResponse prePublish(@RequestParam(name = "uid") int uid,
@RequestParam(name = "storage_id") int storage_id,
@RequestParam(name = "address_id", required = false) String address_id,
@RequestParam(name = "price") String price) {
logger.info("in ufo.buyer.bid.prePublish, uid:{},storage_id:{},address_id:{},price:{}", uid, storage_id, address_id, price);
//1.校验如下规则
//1.1求购价格以必须以9结尾的正整数
BuyerBidPublishRequest req = BuyerBidPublishRequest.builder().uid(uid).storageId(storage_id).addressId(address_id)
.price(priceComputePrepareProcessor.checkAndAcquireSalePrice(price, SkupType.IN_STOCK))
.build();
BidPrePublishResponse response = buyerBidPublishService.prePublish(req);
return new ApiResponse.ApiResponseBuilder().code(200).data(response).message("ok").build();
}
/**
* 出价预发布
*
... ... @@ -91,6 +128,7 @@ public class BuyerBidController {
/**
* 单个订单变价
*
* @param uid
* @param orderCode
* @param price
... ... @@ -99,8 +137,8 @@ public class BuyerBidController {
@RequestMapping(params = "method=ufo.buyer.bid.computeChangePrice")
@ResponseBody
public ApiResponse computeChangePrice(@RequestParam(name = "uid") int uid,
@RequestParam(name = "orderCode") long orderCode,
@RequestParam(name="price")String price) {
@RequestParam(name = "orderCode") long orderCode,
@RequestParam(name = "price") String price) {
logger.info("in ufo.buyer.bid.computeChangePrice, uid:{},orderCode:{},price:{}", uid, orderCode, price);
BuyerBidChangePriceRequest req = BuyerBidChangePriceRequest.builder().uid(uid).orderCode(orderCode)
.price(priceComputePrepareProcessor.checkAndAcquireSalePrice(price, SkupType.IN_STOCK))
... ... @@ -111,6 +149,7 @@ public class BuyerBidController {
/**
* 单个订单变价
*
* @param uid
* @param orderCode
* @param price
... ... @@ -120,7 +159,7 @@ public class BuyerBidController {
@ResponseBody
public ApiResponse changePriceOfSingleGoods(@RequestParam(name = "uid") int uid,
@RequestParam(name = "orderCode") long orderCode,
@RequestParam(name="price")String price,
@RequestParam(name = "price") String price,
@RequestParam(name = "channelNo", required = false) String channelNo,
@RequestParam(name = "client_type", required = false) String clientType) {
logger.info("in ufo.buyer.bid.changePrice, uid:{},orderCode:{},price:{}", uid, orderCode, price);
... ...
package com.yohoufo.order.model.bo;
import com.yoho.error.ServiceError;
import com.yoho.error.exception.ServiceException;
import com.yohobuy.ufo.model.order.common.EntrySellerType;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.order.model.response.BidComputeResponse;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.util.function.Supplier;
... ... @@ -10,6 +14,7 @@ import java.util.function.Supplier;
* 账户
* 根据entrySellerTyp
*/
@Slf4j(topic = "buyerOrderLog")
public abstract class Account {
protected int uid;
//入驻身份
... ... @@ -21,12 +26,21 @@ public abstract class Account {
}
/**
* 检测账户余额是否足够
* 余额是否足够
*
* @param amount
* @return
*/
public void checkBalanceEnough(BigDecimal amount) {
public boolean isBalanceEnough(BigDecimal amount) {
return true;
}
/**
* 检测账户余额是否足够,不足够抛出异常
*
* @param amount
*/
public void checkBalanceEnough(BigDecimal amount) {
}
/**
... ... @@ -40,9 +54,10 @@ public abstract class Account {
/**
* 记录支付明细
* 内部处理异常
* @param orderCode 支付订单号
* 记录支付明细
* 内部处理异常
*
* @param orderCode 支付订单号
* @param accountPayResult
*/
public void recordPayDetail(long orderCode, AccountPayResult accountPayResult) {
... ...
... ... @@ -2,6 +2,7 @@ package com.yohoufo.order.model.bo;
import com.yohobuy.ufo.model.order.bo.PrdPrice;
import com.yohoufo.common.exception.UfoServiceException;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
... ... @@ -10,22 +11,30 @@ import java.math.BigDecimal;
/**
* 出购价
*/
@Slf4j
public class BidPrice {
@Slf4j(topic = "buyerOrderLog")
@ToString
public class BidAndSuggestPrice {
//求购价
private BigDecimal price;
public BidPrice(BigDecimal prdPrice, PrdPrice prdPriceRange) {
//建议价 最低现货价*95%
private BigDecimal suggestPrice;
public BidAndSuggestPrice(BigDecimal prdPrice, PrdPrice prdPriceRange, BuyerBidConfig.BidAndSuggestConfig bidAndSuggestConfig) {
Assert.notNull(prdPrice, "price must not be null");
Assert.notNull(prdPrice, "prdPrice must not be null");
validate(prdPrice, prdPriceRange);
Assert.notNull(prdPrice, "buyerBidConfig must not be null");
validateBase(prdPrice, prdPriceRange);
validateBidPriceConfig(prdPrice, BigDecimal.valueOf(bidAndSuggestConfig.getMinBidPrice()));
this.price = prdPrice;
this.suggestPrice = calculateSuggestPrice(prdPriceRange.getLeastPrice(), bidAndSuggestConfig.getSuggestRate());
}
/**
* 校验价格
* 在商品价格范围内
*/
private void validate(BigDecimal prdPrice, PrdPrice prdPriceRange) {
private void validateBase(BigDecimal prdPrice, PrdPrice prdPriceRange) {
BigDecimal minPrice = prdPriceRange.getMinPrice();
BigDecimal maxPrice = prdPriceRange.getMaxPrice();
if (prdPrice.subtract(minPrice).doubleValue() < 0D) {
... ... @@ -39,7 +48,48 @@ public class BidPrice {
}
}
/**
* 校验价格
* 最小求购价格
*/
private void validateBidPriceConfig(BigDecimal prdPrice, BigDecimal minBidPrice) {
if (prdPrice.subtract(minBidPrice).doubleValue() < 0D) {
log.warn("BidPrice validate,prdPrice:{} < minBidPrice:{}", prdPrice, minBidPrice);
throw new UfoServiceException(501, "您的出价过低");
}
}
/**
* 计算建议价
*
* @param leastPrice 现货最低价
* @param suggestRate 建议比例
*/
public BigDecimal calculateSuggestPrice(BigDecimal leastPrice, double suggestRate) {
log.info("leastPrice:{},suggestRate:{}", leastPrice, suggestRate);
String priceText = leastPrice.multiply(BigDecimal.valueOf(suggestRate)).setScale(0, BigDecimal.ROUND_DOWN).toPlainString();
String endNumber = "9";
if (!priceText.endsWith(endNumber)) {
//最后一位替换成9
priceText = priceText.substring(0, priceText.length() - 1) + endNumber;
}
return new BigDecimal(priceText);
}
/**
* 是否建议
*
* @return
*/
public boolean isSuggest() {
return price.compareTo(suggestPrice) == -1;
}
public BigDecimal getPrice() {
return price;
}
public BigDecimal getSuggestPrice() {
return suggestPrice;
}
}
... ...
... ... @@ -5,21 +5,39 @@ import lombok.Data;
import org.apache.commons.lang3.StringUtils;
@Data
public class BidDepositConfig {
public class BuyerBidConfig {
//定金比例
private double rate = 0.02;
//最小金额
private double min = 20;
//最大金额
private double max = 200;
//求购价配置
private BidAndSuggestConfig basConfig;
public static BidDepositConfig convert(String json) {
//定金配置
private DepositConfig dConfig;
public static BuyerBidConfig convert(String json) {
if (StringUtils.isEmpty(json)) {
return new BidDepositConfig();
return new BuyerBidConfig();
} else {
BidDepositConfig config = BeanTool.string2Value(json, BidDepositConfig.class);
BuyerBidConfig config = BeanTool.string2Value(json, BuyerBidConfig.class);
return config;
}
}
@Data
public static class BidAndSuggestConfig {
//最小求购价
private double minBidPrice = 29;
//建议比例,影响建议价
private double suggestRate = 0.95;
}
//定金配置
@Data
public static class DepositConfig {
//定金比例
private double rate = 0.02;
//最小金额
private double min = 20;
//最大金额
private double max = 200;
}
}
... ...
... ... @@ -3,7 +3,6 @@ package com.yohoufo.order.model.bo;
import com.yohoufo.common.utils.YHMath;
import lombok.Getter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
/**
* 定金
... ... @@ -15,15 +14,15 @@ public class Deposit {
private double amount;
@Getter
private BidDepositConfig config;
private BuyerBidConfig.DepositConfig config;
public Deposit(BidPrice bidPrice, BidDepositConfig config) {
public Deposit(BidAndSuggestPrice bidPrice, BuyerBidConfig.DepositConfig config) {
this.amount = compute(bidPrice.getPrice().doubleValue(), config);
this.config = config;
}
private double compute(double bidPrice, BidDepositConfig config) {
private double compute(double bidPrice, BuyerBidConfig.DepositConfig config) {
//根据比例计算的金额
double depositAmount = YHMath.mul(bidPrice, config.getRate());
depositAmount = Math.max(depositAmount, config.getMin());
... ...
... ... @@ -20,6 +20,9 @@ import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;
/**
* 入驻商家
*/
@Slf4j(topic = "buyerOrderLog")
public class WalletAccount extends Account {
... ... @@ -37,15 +40,27 @@ public class WalletAccount extends Account {
}
/**
* 余额是否足够
*
* @param earestMoney
* @return
*/
@Override
public void checkBalanceEnough(BigDecimal earestMoney) {
public boolean isBalanceEnough(BigDecimal earestMoney) {
if (!SellerHelper.isSuper(entrySellerType)) {
boolean isEnough = sellerAuthCheckService.isEnough(uid, earestMoney);
if (!isEnough) {
log.warn("[{}] checkBalanceEnough,wallet is not enough,earestMoney {}",
uid, earestMoney);
throw new ServiceException(ServiceError.WALLET_EARNESTMONEY_IS_NOT_ENOUGH);
}
return sellerAuthCheckService.isEnough(uid, earestMoney);
} else {
return true;
}
}
@Override
public void checkBalanceEnough(BigDecimal earestMoney) {
if (!isBalanceEnough(earestMoney)) {
log.warn("[{}] checkBalanceEnough,wallet is not enough,earestMoney {}",
uid, earestMoney);
throw new ServiceException(ServiceError.WALLET_EARNESTMONEY_IS_NOT_ENOUGH);
}
}
... ...
... ... @@ -16,8 +16,6 @@ public class BidPublishResult {
private long orderCode;
//发布时间
private int publishTime;
//定金已支付
private boolean finishedDepositPay;
//定金金额
private BigDecimal orderAmount;
}
... ...
... ... @@ -19,45 +19,10 @@ import java.util.stream.Collectors;
@NoArgsConstructor
public class BidComputeResponse {
Deposit deposit;
String amount;
/**
* 费用列表
*/
List<PromotionFormula> promotionFormulaList;
//时限
private TimeLimit timeLimit = TIME_LIMIT;
@Data
@Builder
public static class Deposit {
private double amount;
}
private static final TimeLimit TIME_LIMIT = new TimeLimit();
@Data
public static class TimeLimit {
private TimeLimitItem defaultItem;
private List<TimeLimitItem> items;
public TimeLimit() {
defaultItem = new TimeLimitItem(BidTimeLimit.DAY_7.getId(), BidTimeLimit.DAY_7.getDesc());
items = Arrays.stream(BidTimeLimit.values()).map(e -> {
return new TimeLimitItem(e.getId(), e.getDesc());
}).collect(Collectors.toList());
}
}
@Data
public static class TimeLimitItem {
private int id;
private String desc;
public TimeLimitItem(int id, String desc) {
this.id = id;
this.desc = desc;
}
}
}
... ...
package com.yohoufo.order.model.response;
import com.yohoufo.order.constants.BidTimeLimit;
import lombok.Builder;
import lombok.Data;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Data
public class BidConfigResponse {
//
private String tips = "求购须支付定金。卖家接单后,你需要在24小时内支付商品款。卖家将在你付款后36小时内发货。";
//时限
private TimeLimit timeLimit = TIME_LIMIT;
private static final TimeLimit TIME_LIMIT = new TimeLimit();
@Data
public static class TimeLimit {
private TimeLimitItem defaultItem;
private List<TimeLimitItem> items;
public TimeLimit() {
defaultItem = new TimeLimitItem(BidTimeLimit.DAY_7.getId(), BidTimeLimit.DAY_7.getDesc());
items = Arrays.stream(BidTimeLimit.values()).map(e -> {
return new TimeLimitItem(e.getId(), e.getDesc());
}).collect(Collectors.toList());
}
}
@Data
public static class TimeLimitItem {
private int id;
private String desc;
public TimeLimitItem(int id, String desc) {
this.id = id;
this.desc = desc;
}
}
}
... ...
package com.yohoufo.order.model.response;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class BidPrePublishResponse {
String amount;
/**
* 对话框
*/
private Dialog dialog;
//对话框
@Data
@Builder
public static class Dialog {
//对话框类型 1:金额 2:建议
private String type;
private String title;
private String content;
private String cancel;
private String confirm;
}
}
... ...
... ... @@ -6,7 +6,6 @@ import com.yoho.error.exception.ServiceException;
import com.yohobuy.ufo.model.order.bo.OrderInfo;
import com.yohobuy.ufo.model.order.common.OrderCodeType;
import com.yohobuy.ufo.model.order.common.OrderStatus;
import com.yohobuy.ufo.model.order.common.Payment;
import com.yohobuy.ufo.model.order.constants.OrderConstant;
import com.yohoufo.dal.order.BuyerOrderGoodsMapper;
import com.yohoufo.dal.order.BuyerOrderMapper;
... ... @@ -128,11 +127,6 @@ public class BuyerBidDepositPaymentService extends AbstractOrderPaymentService {
orderInfo.getOrderCode(), orderInfo.getUid());
throw new ServiceException(ServiceError.ORDER_PAY_NOT_ALLOW);
}
if (orderInfo.getPayment() == Payment.WALLET.getCode()) {
logger.warn("deposit is already payment by wallet, orderCode is {}, uid is {}", orderInfo.getOrderCode(), orderInfo.getUid());
throw new ServiceException(ServiceError.ORDER_PAY_NOT_ALLOW);
}
}
@Override
... ...
... ... @@ -142,5 +142,13 @@ public interface DepositService {
* @return
*/
int updateSellLock(Integer uid, String depositCode, Integer sellLock);
/**
* 把记录置为无效
* @param uid
* @param depositCode
* @return
*/
int updateDelStatus(Integer uid, String depositCode);
}
... ...
... ... @@ -86,8 +86,8 @@ public class CacheKeyBuilder {
LARGE_SETTLEMENT_SUPER_NOTICE_WALLET_NOT_ENOUGH("ufo:seller:largeSettlement:walletNotEnough:notice:","uid:{}:funcLevel:{}:cnt"),
DEPOSIT_PLATFORM_FEE("ufo:order:deposit:platform:fee", ""),
SELLER_SALE_PRICE_LIMIT("ufo:order:seller:salePrice:limit:config",""),
//求购定金
BID_DEPOSIT_FEE("ufo:order:bid:deposit:fee:config",""),
//买家求购
BUYER_BID_CONFIG("ufo:order:buyer:bid:config",""),
DISTRIBUTED_LOCK_DEPOSIT_GOODS(DISTRIBUTED_LOCK_PREFIX, "depositCode:{}"),
... ...
... ... @@ -114,7 +114,7 @@ public class BuyerBidPriceService {
}
// 返回结果
return BidPublishResponse.builder().skup(bidPublishResult.getSkup()).orderCode(bidPublishResult.getOrderCode())
.paymentStatus(bidPublishResult.isFinishedDepositPay() ? OrderConstant.Y_STR : OrderConstant.N_STR)
.paymentStatus(OrderConstant.N_STR)
.build();
}
... ...
... ... @@ -25,6 +25,7 @@ import com.yohoufo.order.model.OrderBuilderFactory;
import com.yohoufo.order.model.request.BuyerBidPublishRequest;
import com.yohoufo.order.model.request.ShoppingRequest;
import com.yohoufo.order.model.response.BidComputeResponse;
import com.yohoufo.order.model.response.BidPrePublishResponse;
import com.yohoufo.order.model.response.BidPublishResponse;
import com.yohoufo.order.service.BuyerOrderStateChangers;
import com.yohoufo.order.service.cache.CacheCleaner;
... ... @@ -112,18 +113,14 @@ public class BuyerBidPublishService {
//1.1 sku必须存在的
//1.2求购价格满足商品的最低和最高红线价,不满足提示价格过低,或者价格过高
//求购金额
BidPrice bidPrice = new BidPrice(request.getPrice(), productProxyService.getPrdPriceRange(request.getUid(), request.getStorageId()));
BuyerBidConfig buyerBidConfig = metaConfigService.getBuyerBidConfig();
BidAndSuggestPrice bidPrice = new BidAndSuggestPrice(request.getPrice(),
productProxyService.getPrdPriceRange(request.getUid(), request.getStorageId()),
buyerBidConfig.getBasConfig());
//2.计算定金
Deposit deposit = computeDeposit(bidPrice);
Deposit deposit = computeDeposit(bidPrice, buyerBidConfig.getDConfig());
logger.info("[{}] buyerBid compute deposit result:{}", uid, deposit);
//定金金额
BigDecimal earestMoney = BigDecimal.valueOf(deposit.getAmount());
//账户
Account account = accountFactory.get(uid);
//检测入驻用户账户金额
account.checkBalanceEnough(earestMoney);
//3.计算商品金额 + 运费
ChargeContext chargeContext = computeGoods(request, bidPrice);
... ... @@ -132,12 +129,45 @@ public class BuyerBidPublishService {
//返回结果
BidComputeResponse response = new BidComputeResponse();
response.setPromotionFormulaList(shoppingSupport.getPromotionFormula(chargeResult));
response.setDeposit(BidComputeResponse.Deposit.builder().amount(deposit.getAmount()).build());
response.setAmount(MathUtils.formatStr(deposit.getAmount()));
return response;
}
/**
* 计算及提示
* 主要包括两部分
* 1.定金(出价 * 比例)
* 2.商品金额 + 运费
*/
public BidPrePublishResponse prePublish(BuyerBidPublishRequest request) {
int uid = request.getUid();
//1.校验如下规则
//1.1 sku必须存在的
//1.2求购价格满足商品的最低和最高红线价,不满足提示价格过低,或者价格过高
//比例配置
BuyerBidConfig buyerBidConfig = metaConfigService.getBuyerBidConfig();
//求购金额
BidAndSuggestPrice bidAndSuggestPrice = new BidAndSuggestPrice(request.getPrice(),
productProxyService.getPrdPriceRange(request.getUid(), request.getStorageId()), buyerBidConfig.getBasConfig());
//2.计算定金
Deposit deposit = computeDeposit(bidAndSuggestPrice, buyerBidConfig.getDConfig());
logger.info("[{}] buyerBid compute deposit result:{}", uid, deposit);
BidPrePublishResponse.Dialog dialog = null;
if (bidAndSuggestPrice.isSuggest()) {
logger.warn("[{}] Suggest,bidAndSuggestPrice:{}", uid, bidAndSuggestPrice);
//建议求购价
dialog = BidPrePublishResponse.Dialog.builder().type("suggest")
.title("建议求购价:" + OrderConstant.MONEY_SIGN + bidAndSuggestPrice.getSuggestPrice().toPlainString())
.content("高于建议求购价可以迅速提升求购速度成功率!").cancel("调整价格").confirm("继续求购").build();
}
return BidPrePublishResponse.builder().amount(MathUtils.formatStr(deposit.getAmount())).dialog(dialog).build();
}
/**
* 预发布
*/
... ... @@ -151,20 +181,21 @@ public class BuyerBidPublishService {
// 返回结果
return BidPublishResponse.builder().skup(bidPublishResult.getSkup()).orderCode(bidPublishResult.getOrderCode())
.paymentStatus(bidPublishResult.isFinishedDepositPay() ? OrderConstant.Y_STR : OrderConstant.N_STR)
.paymentStatus(OrderConstant.N_STR)
.build();
}
/**
* 计算定金
*
* @param bidPrice 求购价
* @return
*/
private Deposit computeDeposit(BidPrice bidPrice) {
return new Deposit(bidPrice, metaConfigService.getBidDepositConfig());
private Deposit computeDeposit(BidAndSuggestPrice bidPrice, BuyerBidConfig.DepositConfig depositConfig) {
return new Deposit(bidPrice, depositConfig);
}
private ChargeContext computeGoods(BuyerBidPublishRequest request, BidPrice bidPrice) {
private ChargeContext computeGoods(BuyerBidPublishRequest request, BidAndSuggestPrice bidPrice) {
//构建算费上下文
ChargeContext chargeContext = chargeContextFactory.buildChargeContext(newShoppingRequest(request),
newSellerOrderGoods(0, 0, bidPrice.getPrice()),
... ... @@ -207,6 +238,7 @@ public class BuyerBidPublishService {
/**
* 发布
*
* @param request
* @return
*/
... ... @@ -217,21 +249,15 @@ public class BuyerBidPublishService {
//1.1 sku必须存在的
//1.2求购价格满足商品的最低和最高红线价,不满足提示价格过低,或者价格过高
//求购金额
BidPrice bidPrice = new BidPrice(request.getPrice(), productProxyService.getPrdPriceRange(uid, storageId));
BuyerBidConfig buyerBidConfig = metaConfigService.getBuyerBidConfig();
BidAndSuggestPrice bidPrice = new BidAndSuggestPrice(request.getPrice(), productProxyService.getPrdPriceRange(uid, storageId),
buyerBidConfig.getBasConfig());
//2.计算定金
Deposit deposit = computeDeposit(bidPrice);
Deposit deposit = computeDeposit(bidPrice, buyerBidConfig.getDConfig());
logger.info("[{}] bid compute deposit result:{}", uid, deposit);
//3.计算商品金额 + 运费
ChargeContext chargeContext = computeGoods(request, bidPrice);
//定金金额
BigDecimal earestMoney = BigDecimal.valueOf(deposit.getAmount());
//账户
Account account = accountFactory.get(uid);
//检测入驻用户账户金额
account.checkBalanceEnough(earestMoney);
//获取商品信息
GoodsInfo goodsInfo = skupService.getProductDetail(uid, storageId, bidPrice.getPrice(), SkupType.getSkupType(request.getSkupType()));
... ... @@ -239,9 +265,6 @@ public class BuyerBidPublishService {
final int skup = createCannotSellSellerSkup(uid, goodsInfo);
logger.info("[{}] generate new skup:{}", uid, skup);
//支付定金
AccountPayResult accountPayResult = account.tryPay(earestMoney,OrderConstant.PAY_LEVEL_DEPOSIT, () -> skup);
// 生成订单号
long orderCode = orderCodeGenerator.generate(OrderCodeType.BUYER_TYPE);
logger.info("[{}] generate new orderCode:{}", uid, orderCode);
... ... @@ -255,19 +278,12 @@ public class BuyerBidPublishService {
chargeContext);
//求购 定金
BidOrderMetaBo bidOrderMetaBo = BidOrderMetaBo.builder().depositAmount(deposit.getAmount()).days(request.getDays()).build();
if (accountPayResult.isFinishPay()) {
//钱包
bidOrderMetaBo.setPayment(Payment.WALLET.getCode());
}
// 创建买家订单
BuyerOrderSubmitResult submitResult = buyerBidOrderSubmitService.submitOrder(orderBuilder, bidOrderMetaBo);
//记录支付明细
account.recordPayDetail(orderCode, accountPayResult);
BidPublishResult publishResult = BidPublishResult.builder().skup(skup).orderCode(orderCode)
.publishTime(submitResult.getSubmitTime())
.finishedDepositPay(accountPayResult.isFinishPay())
.orderAmount(orderBuilder.getAmount())
.build();
... ... @@ -305,10 +321,6 @@ public class BuyerBidPublishService {
* @param bidPublishResult
*/
public void processAfterBidPublish(int uid, BidPublishResult bidPublishResult) {
//已完成定金支付,直接变更订单状态为求购中
if (bidPublishResult.isFinishedDepositPay()) {
buyerOrderStateChangers.selectOneToChange(uid, bidPublishResult.getOrderCode(), OrderStatus.WAITING_PAY_DEPOSIT, OrderStatus.BIDING);
}
//触发事件
fireCreateAsyncEvent(uid, bidPublishResult);
//clean cache
... ...
... ... @@ -135,6 +135,12 @@ public class BuyerOrderServiceImpl implements IBuyerOrderService {
private StorageDepositMapper storageDepositMapper;
@Autowired
private AppraiseOrderMapper appraiseOrderMapper;
@Autowired
private BuyerOrderAssistant buyerOrderAssistant;
@Autowired
private BuyerOrderStateChangers buyerOrderStateChangers;
/**
... ... @@ -773,9 +779,6 @@ public class BuyerOrderServiceImpl implements IBuyerOrderService {
return false;
}
@Autowired
private AppraiseOrderMapper appraiseOrderMapper;
@Override
public void confirmReceive(long orderCode) {
... ... @@ -830,7 +833,9 @@ public class BuyerOrderServiceImpl implements IBuyerOrderService {
OrderStatus expectStatus = OrderStatus.SELLER_SEND_OUT;
OrderStatus targetStatus = OrderStatus.PLATFORM_RECEIVE;
BuyerOrder buyerOrder = buyerOrderMapper.selectByOrderCode(orderCode);
BuyerOrderAssistant.PreparedData preparedData = buyerOrderAssistant.prepare(orderCode);
BuyerOrder buyerOrder = preparedData.getBuyerOrder();
if (buyerOrder != null && buyerOrder.getStatus() == expectStatus.getCode()){
int uid = buyerOrder.getUid();
... ... @@ -844,6 +849,8 @@ public class BuyerOrderServiceImpl implements IBuyerOrderService {
logger.info("in confirmReceive record status change, orderCode {},uid {} ,sellerUid {}", orderCode,uid,sellerUid);
buyerNoticeFacade.platformReceiveGoods(uid,orderCode);
orderStatusFlowService.addAsy(buyerOrder.getOrderCode(),targetStatus.getCode());
//
finishDepositGoodsIf(preparedData);
}else{
logger.warn("in confirmReceive not record status change cause of update empty num , orderCode {},uid {} ,sellerUid {}", orderCode,uid,sellerUid);
}
... ... @@ -858,6 +865,30 @@ public class BuyerOrderServiceImpl implements IBuyerOrderService {
}
}
/**
* 现货寄存订单
* 卖家使用寄存商品发货
* @param preparedData
*/
private void finishDepositGoodsIf(BuyerOrderAssistant.PreparedData preparedData){
BuyerOrder buyerOrder = preparedData.getBuyerOrder();
int uid = buyerOrder.getUid();
Long orderCode = buyerOrder.getOrderCode();
SellerOrderGoods psog = preparedData.getSellerOrderGoods();
SkupType skupType = SkupType.getSkupType(psog.getAttributes());
boolean isInstockDepositOrder = BuyerOrderUtils.isInstockDeposit(skupType, buyerOrder.getAttributes());
logger.info("platform confirmReceive orderCode {} buyerUid {} isInstockDepositOrder {}", orderCode, uid, isInstockDepositOrder);
if(isInstockDepositOrder){
String depositCode = buyerOrderMetaService.getDepositCode(uid, orderCode);
logger.info("platform confirmReceive orderCode {} buyerUid {} isInstockDepositOrder {} depositCode {}",
orderCode, uid, isInstockDepositOrder, depositCode);
if (StringUtils.isNotBlank(depositCode)){
int depositUpdate = depositService.updateDelStatus(psog.getUid(), depositCode);
logger.info("platform confirmReceive update deposit DelStatus {} orderCode {} buyerUid {} depositCode {}",
depositUpdate, orderCode, uid, depositCode);
}
}
}
// 质检通过,不需要记录物流调拨信息
@Override
... ... @@ -1108,6 +1139,7 @@ public class BuyerOrderServiceImpl implements IBuyerOrderService {
//寄存商品 出库准备
int rows = 0;
/*
boolean isInstockDepositOrder = dscNode.isInstockDepositOrder();
if (isInstockDepositOrder){
//上架的寄存商品 || 未上架的寄存商品
... ... @@ -1126,7 +1158,11 @@ public class BuyerOrderServiceImpl implements IBuyerOrderService {
rows = depositService.updateDepositWaitToPick(ownerUid, depositCode, orderCode, Optional.ofNullable(preparedData.getBuyerOrderGoods())
.map(BuyerOrderGoods::getSkup).orElse(0));
logger.info("processOrderDeliverByDepositGoods orderCode {} depositCode {} updateDepositWaitToPick {}", orderCode, depositCode, rows);
}
}*/
rows = depositService.updateDepositWaitToPick(ownerUid, depositCode, orderCode, Optional.ofNullable(preparedData.getBuyerOrderGoods())
.map(BuyerOrderGoods::getSkup).orElse(0));
logger.info("processOrderDeliverByDepositGoods orderCode {} depositCode {} updateDepositWaitToPick {}", orderCode, depositCode, rows);
if (rows>0){
//bind deposit code 2 buyer order
... ...
... ... @@ -872,6 +872,22 @@ public class DepositServiceImpl implements DepositService {
}
@Override
public int updateDelStatus(Integer uid, String depositCode) {
StorageDeposit deposit = storageDepositMapper.queryByDepositCode(uid, depositCode);
if(null == deposit) {
throw new UfoServiceException(400, "寄存商品不存在");
}
LOGGER.info("updateDelStatus, uid is {}, depositCode is {}, old depositInfo is {}", uid, depositCode, deposit);
//当前记录置为无效
int num = storageDepositMapper.updateDelStatusByCode(uid, depositCode, deposit.getStatus());
//清缓存
clearCache(uid, deposit.getProductId(), deposit.getStorageId());
return num;
}
@Override
public boolean updateDepositAfterCancelBuy(Integer uid, String depositCode) {
StorageDeposit deposit = storageDepositMapper.queryByDepositCode(uid, depositCode);
if(null == deposit) {
... ...
... ... @@ -259,6 +259,7 @@ public class ExpressInfoServiceImpl implements IExpressInfoService {
BuyerOrderAssistant.DepositSkuCheckNode dscNode,
SellerDeliverToDepotReq req4Log
){
/*
final BuyerOrder pbo = preparedData.getBuyerOrder();
Long orderCode = pbo.getOrderCode();
... ... @@ -281,6 +282,8 @@ public class ExpressInfoServiceImpl implements IExpressInfoService {
sellerNoticeFacade.appraisePassCore(buyerUid, orderCode, psog, true, MsgSendFlg.OTHER);
}
return updateOrderCnt;
*/
return processBuyerOrderOfNotInstockDepositUsingDepositGoods(preparedData, dscNode, req4Log);
}
private int processBuyerOrderOfNotInstockDepositUsingDepositGoods(BuyerOrderAssistant.PreparedData preparedData,
... ...
... ... @@ -15,7 +15,7 @@ import com.yohoufo.common.cache.CacheClient;
import com.yohoufo.dal.order.MetaConfigMapper;
import com.yohoufo.dal.order.model.MetaConfig;
import com.yohoufo.order.charge.model.FeeNRate;
import com.yohoufo.order.model.bo.BidDepositConfig;
import com.yohoufo.order.model.bo.BuyerBidConfig;
import com.yohoufo.order.model.dto.*;
import com.yohoufo.order.service.cache.CacheKeyBuilder;
import com.yohoufo.order.service.cache.ExpiredTime;
... ... @@ -377,11 +377,11 @@ public class MetaConfigService {
* 求购定金配置(比例、最小、最大金额)
* @return
*/
public BidDepositConfig getBidDepositConfig() {
CacheKeyBuilder.KeyTemp kt = CacheKeyBuilder.KeyTemp.BID_DEPOSIT_FEE;
public BuyerBidConfig getBuyerBidConfig() {
CacheKeyBuilder.KeyTemp kt = CacheKeyBuilder.KeyTemp.BUYER_BID_CONFIG;
RedisKeyBuilder rkb = kt.builderKeyOnlyFixed();
final String key = MetaConfigKey.BID_DEPOSIT_FEE;
final String key = MetaConfigKey.BUYER_BID_CONFIG;
String configVal = new DataProcesser(rkb, key, ExpiredTime.ORDER_BASE_CONFIG).getConfigVal();
return BidDepositConfig.convert(configVal);
return BuyerBidConfig.convert(configVal);
}
}
... ...
... ... @@ -118,7 +118,7 @@ public class SellerBidPublishService {
//2.算费
//2.获取算费配置
int storageId = saleableBidSkup.getStorageId();
SkupType skupType = SkupType.getSkupType(saleableBidSkup.getSkupType());
SkupType skupType = SkupType.getSkupType(saleableBidSkup.getAttribute());
logger.info("[{}] compute seller bid skup fee,skup:{},storageId:{},skupType:{}", uid, saleableBidSkup.getSkup(), storageId, skupType);
boolean isImperfect = SellerGoodsHelper.isImperfectGoods(skupType);
PrdQueryReq pqr = PrdQueryReq.builder().uid(uid)
... ...
package com.yohoufo.order.service.proxy;
import com.yohobuy.ufo.model.BidStoragePriceVo;
import com.yohobuy.ufo.model.order.constants.SkupType;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohobuy.ufo.model.order.common.OrderAttributes;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -32,7 +31,7 @@ public class BidProductProxyService extends AbsProxyService {
.storageId(goods.getStorageId())
.bidUid(bidUid)
.price(goods.getGoodsPrice())
.skupType(SkupType.IN_STOCK.getCode())
.attribute(OrderAttributes.COMMON_IN_STOCK.getCode())
.build();
ufoServiceCaller.call(CREATE_API, bidStoragePriceBo);
}
... ...
... ... @@ -105,7 +105,17 @@ public class ShoppingSupport {
private String getDeliveryWayStr(int deliveryWay) {
return deliveryWay == DeliveryWayEnum.SELF_FETCH.getCode() ? OrderConstant.DELIVERY_WAY_STORE_NAME : OrderConstant.DELIVERY_WAY_SF_NAME;
String deliverWayName;
if (deliveryWay == DeliveryWayEnum.SELF_FETCH.getCode()){
deliverWayName = OrderConstant.DELIVERY_WAY_STORE_NAME;
}else if(deliveryWay == DeliveryWayEnum.OVERSEAS_HONGHONG.getCode()){
//中通国际 TODO 加到model
deliverWayName = "中通国际";
}else{
deliverWayName = OrderConstant.DELIVERY_WAY_SF_NAME;
}
return deliverWayName;
}
... ...
... ... @@ -170,7 +170,7 @@ public class BidProductService {
sp.setSkup(skup);
sp.setCreateTime((int) (System.currentTimeMillis() / 1000));
sp.setUpdateTime(0);
sp.setSkupType(skupVo.getSkupType());
sp.setAttribute(skupVo.getAttribute());
logger.info("BidStoragePrice : {}", sp);
return sp;
}
... ... @@ -186,7 +186,7 @@ public class BidProductService {
.storageId(storagePrice.getStorageId())
.price(storagePrice.getPrice())
.skup(storagePrice.getSkup())
.skupType(storagePrice.getSkupType())
.attribute(storagePrice.getAttribute())
.bidUid(storagePrice.getBidUid())
.build();
logger.info("BidStoragePriceBo : {}", vo);
... ...
... ... @@ -158,6 +158,9 @@ public class ProductServiceImpl implements ProductService {
@Autowired
private StorageService storageService;
@Autowired
private StoragePriceService storagePriceService;
@Override
public ProductDetailResp queryProductDetailById(Integer productId) {
ProductDetailResp productDetailResp = new ProductDetailResp();
... ... @@ -2253,6 +2256,8 @@ public class ProductServiceImpl implements ProductService {
if (!CollectionUtils.isEmpty(goodsBOList)) {
List<GoodsSize> goodsSizes = storageService.getSizeList(productId, goodsBOList.get(0));
storagePriceService.setStoragePrice(goodsSizes, productId); // 设置库存,最低价 skup等信息
goodsBOList.get(0).setSizeList(goodsSizes);
storageService.setMaxMinPrice(goodsSizes, product.getMinPrice(), product.getMaxPrice()); //设置商品最高价和最低价
... ...
package com.yohoufo.product.service.impl;
import com.yohobuy.ufo.model.GoodsSize;
import com.yohoufo.dal.product.StoragePriceMapper;
import com.yohoufo.dal.product.model.StoragePrice;
import com.yohoufo.product.cache.UfoProductCacheService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* Created by li.ma on 2019/6/27.
... ... @@ -24,4 +31,34 @@ public class StoragePriceService {
}
/**
* 查询现货各尺码的最低价
* @param productId
* @return
*/
private Map<Integer, StoragePrice> selectInStockLeastPByProductId(@Param("productId") Integer productId) {
return storagePriceMapper.selectInStockLeastPByProductId(productId).stream().collect(Collectors.toMap(StoragePrice::getStorageId, Function.identity()));
}
public void setStoragePrice(List<GoodsSize> goodsSizes, Integer productId) {
if (CollectionUtils.isEmpty(goodsSizes)) {
return;
}
Map<Integer, StoragePrice> storagePriceMap = selectInStockLeastPByProductId(productId);
goodsSizes.stream().forEach(item -> {
StoragePrice storagePrice = storagePriceMap.get(item.getId());//大陆现货
if (null != storagePrice && null != item.getSuggestHighPrice()
&& storagePrice.getPrice().compareTo(item.getSuggestHighPrice()) > 0) { //高于建议价,不展示skup
item.setStorageNum(0);
item.setSkup(0);
} else {
item.setLeastPrice(storagePrice == null ? null : storagePrice.getPrice());
item.setStatus(storagePrice == null ? null : storagePrice.getStatus());
item.setSkup(storagePrice == null ? 0 : storagePrice.getSkup());
item.setStorageNum(item.getSkup() == null || item.getSkup() == 0 ? 0 : 1);
}
});
}
}
... ...
... ... @@ -43,5 +43,7 @@ public class RealNameAuthorizeReqVO extends BaseBO {
//版本
private String app_version;
private String client_type;
}
... ...
... ... @@ -34,6 +34,14 @@ public class AlipayServiceImpl implements IAlipayService {
@Override
public void beginAlipayCert(RealNameAuthorizeReqVO reqVO, ZhiMaCert zhiMaCert, AuthorizeResultRespVO respBO){
logger.info("BeginAlipayCert: Begin alipay certification. reqVO is {}, zhiMaCert is {}", reqVO, zhiMaCert);
// 闲鱼用户不进行百度刷脸认证,直接认证成功
if("h5".equals(reqVO.getClient_type())){
logger.info("BeginAlipayCert: client_type is h5, reqVO is {}, zhiMaCert is {}", reqVO, zhiMaCert);
zhiMaCertDao.updateIdleFishValidStatus(zhiMaCert.getId());
respBO.setCallZhiMa("1");
respBO.setZhiMaCertId(zhiMaCert.getId());
return;
}
//(1)支付宝刷脸认证初始化
String certifyId = AlipayCertHelper.alipayCertifyInit(reqVO.getCertName(), reqVO.getCertNo());
logger.info("BeginAlipayCert: alipay init result. uid is {}, certNO is {}, certName is {}, certifyId is {}", reqVO.getUid(), reqVO.getCertNo(), reqVO.getCertName(), certifyId);
... ...
... ... @@ -115,7 +115,7 @@ public class CertificationServiceImpl implements ICertificationService {
logger.info("BeginCertificate: call alipay certify end. reqVO is {}, zhiMaCert is {}, respBO is {}", reqVO, zhiMaCert, respBO);
}
//(9)删除实名认证信息
//(9)删除实名认证信息缓存
try {
cacheService.delZhiMaCert(reqVO.getUid());
}catch(Exception e){
... ...