Authored by mali

Merge branch 'test6.9.0' into test6.9.1

... ... @@ -4,17 +4,13 @@ package com.yohoufo.dal.order;
import com.yohoufo.dal.order.model.InviteActivity;
public interface InviteActivityMapper {
int deleteByPrimaryKey(Integer id);
int insert(InviteActivity record);
int insertSelective(InviteActivity record);
InviteActivity selectByPrimaryKey(Integer id);
InviteActivity selectLastActivtiy();
int updateByPrimaryKeySelective(InviteActivity record);
int updateByPrimaryKey(InviteActivity record);
}
\ No newline at end of file
... ...
... ... @@ -2,6 +2,7 @@ package com.yohoufo.dal.order;
import com.yohoufo.dal.order.model.InviteSettlementItem;
import com.yohoufo.dal.order.model.InviteSettlementItemStats;
import org.apache.ibatis.annotations.Param;
import java.util.List;
... ... @@ -32,4 +33,17 @@ public interface InviteSettlementItemMapper {
@Param("type") Integer type,
@Param("inviteSettlementId") Integer inviteSettlementId);
InviteSettlementItemStats selectStats(@Param("uid") Integer uid,
@Param("type") Integer type,
@Param("startTime") Integer startTime,
@Param("endTime") Integer endTime);
List<InviteSettlementItem> select(@Param("uid") Integer uid,
@Param("type") Integer type,
@Param("startTime") Integer startTime,
@Param("endTime") Integer endTime,
@Param("start") Integer start,
@Param("limit") Integer limit);
}
\ No newline at end of file
... ...
... ... @@ -17,4 +17,6 @@ public interface InviteSettlementMapper {
@Param("uid") Integer uid, @Param("status") Integer status,
@Param("start") Integer start, @Param("limit") Integer limit);
List<InviteSettlement> selectByUidAndIds(@Param("uid") Integer uid, @Param("ids") List<Integer> ids);
}
\ No newline at end of file
... ...
package com.yohoufo.dal.order.model;
import lombok.Data;
@Data
public class InviteActivity {
private Integer id;
private String name;
... ... @@ -11,53 +15,10 @@ public class InviteActivity {
private Integer rewardDays;
private Integer createTime;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
private String productSortLimit;
public Integer getStartTime() {
return startTime;
}
private String orderAttributesLimit;
public void setStartTime(Integer startTime) {
this.startTime = startTime;
}
public Integer getEndTime() {
return endTime;
}
public void setEndTime(Integer endTime) {
this.endTime = endTime;
}
public Integer getRewardDays() {
return rewardDays;
}
public void setRewardDays(Integer rewardDays) {
this.rewardDays = rewardDays;
}
public Integer getCreateTime() {
return createTime;
}
private Integer createTime;
public void setCreateTime(Integer createTime) {
this.createTime = createTime;
}
}
\ No newline at end of file
... ...
... ... @@ -38,6 +38,8 @@ public class InviteSettlementItem {
private Integer type;
private BigDecimal settleAmount;
private Integer inviteSettlementId;
private Integer status;
... ...
package com.yohoufo.dal.order.model;
import lombok.Data;
import java.math.BigDecimal;
/**
* @author LUOXC
* @date 2019/4/11 9:41
*/
@Data
public class InviteSettlementItemStats {
Integer totalElements;
BigDecimal totalOrderAmount;
BigDecimal totalSettleAmount;
}
... ...
... ... @@ -7,10 +7,12 @@
<result column="start_time" property="startTime" jdbcType="INTEGER" />
<result column="end_time" property="endTime" jdbcType="INTEGER" />
<result column="reward_days" property="rewardDays" jdbcType="INTEGER" />
<result column="product_sort_limit" property="productSortLimit" jdbcType="VARCHAR" />
<result column="order_attributes_limit" property="orderAttributesLimit" jdbcType="VARCHAR" />
<result column="create_time" property="createTime" jdbcType="INTEGER" />
</resultMap>
<sql id="Base_Column_List" >
id, name, start_time, end_time, reward_days, create_time
id, name, start_time, end_time, reward_days,product_sort_limit,order_attributes_limit, create_time
</sql>
... ... @@ -29,63 +31,29 @@
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
delete from invite_activity
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.yohoufo.dal.order.model.InviteActivity" >
insert into invite_activity (id, name, start_time,
end_time, reward_days, create_time
)
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{startTime,jdbcType=INTEGER},
#{endTime,jdbcType=INTEGER}, #{rewardDays,jdbcType=INTEGER}, #{createTime,jdbcType=INTEGER}
)
</insert>
<insert id="insertSelective" parameterType="com.yohoufo.dal.order.model.InviteActivity" >
insert into invite_activity
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="name != null" >
name,
</if>
<if test="startTime != null" >
start_time,
</if>
<if test="endTime != null" >
end_time,
</if>
<if test="rewardDays != null" >
reward_days,
</if>
<if test="createTime != null" >
create_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=INTEGER},
</if>
<if test="name != null" >
#{name,jdbcType=VARCHAR},
</if>
<if test="startTime != null" >
#{startTime,jdbcType=INTEGER},
</if>
<if test="endTime != null" >
#{endTime,jdbcType=INTEGER},
</if>
<if test="rewardDays != null" >
#{rewardDays,jdbcType=INTEGER},
</if>
<if test="createTime != null" >
#{createTime,jdbcType=INTEGER},
</if>
</trim>
insert into invite_activity (
id,
name,
start_time,
end_time,
reward_days,
product_sort_limit,
order_attributes_limit,
create_time
)
values (
#{id,jdbcType=INTEGER},
#{name,jdbcType=VARCHAR},
#{startTime,jdbcType=INTEGER},
#{endTime,jdbcType=INTEGER},
#{rewardDays,jdbcType=INTEGER},
#{productSortLimit,jdbcType=VARCHAR},
#{orderAttributesLimit,jdbcType=VARCHAR},
#{createTime,jdbcType=INTEGER}
)
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.yohoufo.dal.order.model.InviteActivity" >
update invite_activity
<set >
... ... @@ -107,13 +75,5 @@
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.yohoufo.dal.order.model.InviteActivity" >
update invite_activity
set name = #{name,jdbcType=VARCHAR},
start_time = #{startTime,jdbcType=INTEGER},
end_time = #{endTime,jdbcType=INTEGER},
reward_days = #{rewardDays,jdbcType=INTEGER},
create_time = #{createTime,jdbcType=INTEGER}
where id = #{id,jdbcType=INTEGER}
</update>
</mapper>
\ No newline at end of file
... ...
... ... @@ -10,6 +10,7 @@
<result column="order_amount" property="orderAmount" jdbcType="DECIMAL" />
<result column="order_create_time" property="orderCreateTime" jdbcType="INTEGER" />
<result column="type" property="type" jdbcType="INTEGER" />
<result column="settle_amount" property="settleAmount" jdbcType="DECIMAL" />
<result column="invite_settlement_id" property="inviteSettlementId" jdbcType="INTEGER" />
<result column="status" property="status" jdbcType="INTEGER" />
<result column="status_desc" property="statusDesc" jdbcType="VARCHAR" />
... ... @@ -17,17 +18,35 @@
<result column="order_num" property="orderNum" jdbcType="INTEGER" />
</resultMap>
<sql id="Base_Column_List" >
id, uid, buyer_uid, buyer_order_code, seller_uid, order_amount,order_create_time,type, invite_settlement_id,
id, uid, buyer_uid, buyer_order_code, seller_uid, order_amount,order_create_time,type,settle_amount, invite_settlement_id,
status, status_desc, create_time
</sql>
<insert id="insert" parameterType="com.yohoufo.dal.order.model.InviteSettlementItem" >
insert into invite_settlement_item (id, uid, buyer_uid,
buyer_order_code, seller_uid, order_amount,order_create_time,type,
invite_settlement_id, status, status_desc,
insert into invite_settlement_item (id,
uid,
buyer_uid,
buyer_order_code,
seller_uid,
order_amount,
order_create_time,
type,
settle_amount,
invite_settlement_id,
status,
status_desc,
create_time)
values (#{id,jdbcType=INTEGER}, #{uid,jdbcType=INTEGER}, #{buyerUid,jdbcType=INTEGER},
#{buyerOrderCode,jdbcType=BIGINT}, #{sellerUid,jdbcType=INTEGER}, #{orderAmount,jdbcType=DECIMAL}, #{orderCreateTime,jdbcType=INTEGER}, #{type,jdbcType=INTEGER},
#{inviteSettlementId,jdbcType=INTEGER}, #{status,jdbcType=INTEGER}, #{statusDesc,jdbcType=VARCHAR},
values (#{id,jdbcType=INTEGER},
#{uid,jdbcType=INTEGER},
#{buyerUid,jdbcType=INTEGER},
#{buyerOrderCode,jdbcType=BIGINT},
#{sellerUid,jdbcType=INTEGER},
#{orderAmount,jdbcType=DECIMAL},
#{orderCreateTime,jdbcType=INTEGER},
#{type,jdbcType=INTEGER},
#{settleAmount,jdbcType=DECIMAL},
#{inviteSettlementId,jdbcType=INTEGER},
#{status,jdbcType=INTEGER},
#{statusDesc,jdbcType=VARCHAR},
#{createTime,jdbcType=INTEGER})
</insert>
... ... @@ -74,4 +93,28 @@
from invite_settlement_item
where uid = #{uid,jdbcType=INTEGER} and type = #{type,jdbcType=INTEGER} and invite_settlement_id = #{inviteSettlementId,jdbcType=INTEGER}
</select>
<select id="selectStats" resultType="com.yohoufo.dal.order.model.InviteSettlementItemStats" >
select
count(1) as 'totalElements',
sum(order_amount) as 'totalOrderAmount'
from invite_settlement_item
where uid = #{uid,jdbcType=INTEGER}
and type = #{type,jdbcType=INTEGER}
and status in (1,3)
and order_create_time between #{startTime,jdbcType=INTEGER} and #{endTime,jdbcType=INTEGER}
</select>
<select id="select" resultMap="BaseResultMap" >
select
<include refid="Base_Column_List" />
from invite_settlement_item
where uid = #{uid,jdbcType=INTEGER}
and type = #{type,jdbcType=INTEGER}
and status in (1,3)
and order_create_time between #{startTime,jdbcType=INTEGER} and #{endTime,jdbcType=INTEGER}
order by order_create_time desc
limit #{start,jdbcType=INTEGER},#{limit,jdbcType=INTEGER}
</select>
</mapper>
\ No newline at end of file
... ...
... ... @@ -59,4 +59,15 @@
limit #{start,jdbcType=INTEGER}, #{limit,jdbcType=INTEGER}
</select>
<select id="selectByUidAndIds" resultMap="BaseResultMap" >
select
<include refid="Base_Column_List" />
from invite_settlement
where uid = #{uid,jdbcType=INTEGER}
and id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
</mapper>
\ No newline at end of file
... ...
package com.yohoufo.order.controller;
import com.yohoufo.common.ApiResponse;
import com.yohoufo.order.model.InviteSettlementItemListVO;
import com.yohoufo.order.model.InviteSettlementItemListVO;
import com.yohoufo.order.model.InviteSettlementListVO;
import com.yohoufo.order.service.IInviteSettlementService;
import lombok.extern.slf4j.Slf4j;
... ... @@ -20,7 +22,7 @@ import java.util.Objects;
public class InviteSettlementController {
@Autowired
private IInviteSettlementService inviterService;
private IInviteSettlementService inviteSettlementService;
/**
* 我的收款记录
... ... @@ -31,16 +33,32 @@ public class InviteSettlementController {
@RequestMapping(params = "method=ufo.invite.getInviteSettlementList")
public ApiResponse getInviteSettlementList(@RequestParam(value = "uid") int uid) {
log.info("get inviter settlement list, uid is {}", uid);
InviteSettlementListVO inviteSettlementListVO = inviterService.getInviteSettlementList(uid);
InviteSettlementListVO inviteSettlementListVO = inviteSettlementService.getInviteSettlementList(uid);
return new ApiResponse.ApiResponseBuilder().code(200).data(inviteSettlementListVO).message("ok").build();
}
/**
* 我的收款记录明细
*
* @param uid
* @return
*/
@RequestMapping(params = "method=ufo.invite.getInviteSettlementItemList")
public ApiResponse getInviteSettlementItemList(@RequestParam(value = "uid") Integer uid,
@RequestParam(value = "month") String month,
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "10") Integer limit) {
log.info("get inviter settlement item list, uid is {}", uid);
InviteSettlementItemListVO resp = inviteSettlementService.getInviteSettlementItemList(uid, month, page, limit);
return new ApiResponse.ApiResponseBuilder().code(200).data(resp).message("ok").build();
}
@RequestMapping(value = "/erp/invite/settlement/help/settle")
public ApiResponse settle(@RequestParam(value = "uid", required = false) Integer uid) {
if (Objects.nonNull(uid)) {
inviterService.settle(uid);
inviteSettlementService.settle(uid);
} else {
inviterService.settle();
inviteSettlementService.settle();
}
return new ApiResponse.ApiResponseBuilder().code(200).message("ok").build();
}
... ...
package com.yohoufo.order.model;
import lombok.Data;
import lombok.experimental.Builder;
import java.util.List;
/**
* @author LUOXC
* @date 2019/4/2 15:00
*/
@Builder
@Data
public class InviteSettlementItemListVO {
int page;
int pageTotal;
int pageSize;
int totalElements;
String totalOrderAmount;
String totalSettleAmount;
List<InviteSettlementItemVO> list;
@Data
public static class InviteSettlementItemVO {
String buyerOrderCode;
String sellerName;
String orderAmount;
String orderCreateTime;
String settleAmount;
String statusDesc;
}
}
... ...
... ... @@ -19,8 +19,12 @@ public class InviteSettlementItemCreateRequest {
private Integer orderCreateTime;
private Integer orderAttributes;
private Integer sellerUid;
private Integer sellerOrderPayment;
private Integer skup;
}
... ...
package com.yohoufo.order.service;
import com.yohoufo.order.model.InviteSettlementItemListVO;
import com.yohoufo.order.model.InviteSettlementListVO;
public interface IInviteSettlementService {
... ... @@ -12,6 +13,8 @@ public interface IInviteSettlementService {
*/
InviteSettlementListVO getInviteSettlementList(Integer uid);
InviteSettlementItemListVO getInviteSettlementItemList(Integer uid, String month, Integer page, Integer limit);
/**
* 结算
*/
... ...
package com.yohoufo.order.service.impl;
import com.google.common.base.Splitter;
import com.yohobuy.ufo.model.order.common.OrderStatus;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.dal.order.*;
import com.yohoufo.dal.order.model.*;
import com.yohoufo.dal.product.ProductMapper;
import com.yohoufo.dal.product.StoragePriceMapper;
import com.yohoufo.dal.product.model.Product;
import com.yohoufo.dal.product.model.StoragePrice;
import com.yohoufo.order.common.Payment;
import com.yohoufo.order.constants.InviteConstant;
import com.yohoufo.order.model.request.InviteSettlementItemCreateRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Objects;
import static com.yohoufo.order.constants.InviteConstant.INVITER_TYPE_AGENT;
... ... @@ -44,6 +52,12 @@ public class InviteSettlementItemCreator {
@Autowired
private InviteActivityMapper inviteActivityMapper;
@Autowired
private StoragePriceMapper storagePriceMapper;
@Autowired
private ProductMapper productMapper;
public void createInviteSettlementItem(Long buyerOrderCode, Integer status) {
if (status == OrderStatus.WAITING_RECEIVE.getCode() || status == OrderStatus.DONE.getCode()) {
BuyerOrder buyerOrder = buyerOrderMapper.selectByOrderCode(buyerOrderCode);
... ... @@ -54,6 +68,8 @@ public class InviteSettlementItemCreator {
request.setBuyerOrderCode(buyerOrder.getOrderCode());
request.setSellerUid(buyerOrder.getSellerUid());
request.setOrderAmount(buyerOrder.getAmount());
request.setOrderAttributes(buyerOrder.getAttributes());
request.setSkup(buyerOrderGoods.getSkup());
// 卖家商家单子上架时间
request.setOrderCreateTime(sellerOrder.getCreateTime());
request.setSellerOrderPayment(sellerOrder.getPayment());
... ... @@ -67,11 +83,6 @@ public class InviteSettlementItemCreator {
String tag = String.format("create invite settlement item %s-%s", request.getSellerUid(), buyerOrderCode);
log.info("{} start", tag);
if (request.getSellerOrderPayment() != Payment.WALLET.getCode()) {
log.info("{} fail, seller order is not a stored create", tag);
return;
}
InviteRecord invitee = inviteRecordMapper.selectByInviteeUid(request.getSellerUid());
if (Objects.isNull(invitee)) {
log.info("{} fail, seller is not a invitee", tag);
... ... @@ -79,7 +90,7 @@ public class InviteSettlementItemCreator {
}
int inviterUid = invitee.getInviterUid();
int orderCreateTime = request.getOrderCreateTime();
Inviter inviter = inviterMapper.selectByPrimaryKey(invitee.getInviterId());
if (Objects.isNull(inviter)) {
log.warn("{} fail, can not find inviter", tag);
... ... @@ -90,12 +101,14 @@ public class InviteSettlementItemCreator {
return;
}
if (!checkWithInviteActivity(tag, invitee, orderCreateTime, inviter)){
if (!checkActivity(tag, request, invitee, inviter)) {
return;
}
log.info("{}, start create", tag);
InviteSettlementItem inviteSettlementItem = buildInviteSettlementItem(request, invitee, inviter);
inviteSettlementItemMapper.insert(inviteSettlementItem);
log.info("{} success", tag);
... ... @@ -115,56 +128,108 @@ public class InviteSettlementItemCreator {
inviteSettlementItem.setOrderCreateTime(request.getOrderCreateTime());
// 结算方式选择
Integer inviteSettlementItemType = buildInviteSettlementItemType(inviter);
inviteSettlementItem.setType(inviteSettlementItemType);
// 待结算订单状态
Pair<Integer, String> status = buildInviteSettlementItemStatus(request, invitee, inviter);
inviteSettlementItem.setStatus(status.getLeft());
inviteSettlementItem.setStatusDesc(status.getRight());
inviteSettlementItem.setCreateTime(DateUtil.getCurrentTimeSecond());
return inviteSettlementItem;
}
private Integer buildInviteSettlementItemType(Inviter inviter) {
// 入驻商家角色以type1方式结算
if (inviter.getType() == INVITER_TYPE_STORED_SELLER) {
inviteSettlementItem.setType(1);
return 1;
}
// 一级代理角色以type2方式结算
else if (inviter.getType() == INVITER_TYPE_AGENT) {
inviteSettlementItem.setType(2);
return 2;
}
// 其他以type1方式结算
else {
inviteSettlementItem.setType(1);
return 1;
}
}
// 待结算订单状态
private Pair<Integer, String> buildInviteSettlementItemStatus(InviteSettlementItemCreateRequest request, InviteRecord invitee, Inviter inviter) {
// 受邀人无效
if (invitee.getStatus() == InviteRecord.STATUS_DISABLE) {
inviteSettlementItem.setStatus(InviteSettlementItem.STATUS_DISABLE);
inviteSettlementItem.setStatusDesc(invitee.getStatusDesc());
return Pair.of(InviteSettlementItem.STATUS_DISABLE, Objects.nonNull(invitee.getStatusDesc()) ? invitee.getStatusDesc() : "INVITEE_DISABLE");
}
// 邀请人无效
else if (inviter.getStatus() == InviteConstant.INVITER_STATUS_DISABLE) {
inviteSettlementItem.setStatus(InviteSettlementItem.STATUS_DISABLE);
inviteSettlementItem.setStatusDesc(inviter.getStatusDesc());
return Pair.of(InviteSettlementItem.STATUS_DISABLE, Objects.nonNull(inviter.getStatusDesc()) ? inviter.getStatusDesc() : "INVITER_DISABLE");
}
// 受邀人非入驻商家
else if (nonStoredSellerOfInvitee(request)) {
return Pair.of(InviteSettlementItem.STATUS_DISABLE, "NON_STORED_SELLER");
} else {
inviteSettlementItem.setStatus(InviteSettlementItem.STATUS_ENABLE);
return Pair.of(InviteSettlementItem.STATUS_ENABLE, "OK");
}
}
inviteSettlementItem.setCreateTime(DateUtil.getCurrentTimeSecond());
return inviteSettlementItem;
private boolean nonStoredSellerOfInvitee(InviteSettlementItemCreateRequest request) {
return request.getSellerOrderPayment() != Payment.WALLET.getCode();
}
private boolean checkWithInviteActivity(String tag, InviteRecord invitee, int orderCreateTime, Inviter inviter) {
int inviterType = inviter.getType();
int inviteTime = invitee.getCreateTime();
private boolean checkActivity(String tag, InviteSettlementItemCreateRequest request, InviteRecord invitee, Inviter inviter) {
// 入驻商家
if (inviterType == INVITER_TYPE_STORED_SELLER) {
if (inviter.getType() == INVITER_TYPE_STORED_SELLER) {
InviteActivity activity = inviteActivityMapper.selectByPrimaryKey(invitee.getInviteActivityId());
if (Objects.isNull(activity)) {
log.warn("{} fail, can not find inviter ", tag);
return false;
}
// 验证品类是否满足条件
if (!checkActivityProductSortLimit(request.getSkup(), activity.getProductSortLimit())) {
log.warn("{} fail, can not hit product sort limit is {}", tag, activity.getProductSortLimit());
return false;
}
// 验证订单属性是否满足条件
if (!checkActivityOrderAttributesLimit(request.getOrderAttributes(), activity.getOrderAttributesLimit())) {
log.warn("{} fail, can not hit order attributes limit is {}", tag, activity.getOrderAttributesLimit());
return false;
}
// 验证是否过了奖励时间
int days = activity.getRewardDays() * 24 * 60 * 60;
if (inviteTime + days < orderCreateTime) {
if (!checkActivityRewardDays(request, invitee, activity.getRewardDays())) {
log.warn("{} fail, reward end.", tag);
return false;
}
}
return true;
}
private boolean checkActivityProductSortLimit(Integer skup, String productSortLimit) {
if (StringUtils.isBlank(productSortLimit)) {
return true;
}
List<String> productSortLimitList = Splitter.on(",").splitToList(productSortLimit);
StoragePrice storagePrice = storagePriceMapper.selectBySkup(skup);
Product product = productMapper.selectByPrimaryKey(storagePrice.getProductId());
String maxSortId = product.getMaxSortId().toString();
return productSortLimitList.contains(maxSortId);
}
private boolean checkActivityOrderAttributesLimit(Integer orderAttributes, String orderAttributesLimit) {
if (StringUtils.isBlank(orderAttributesLimit)) {
return true;
}
List<String> orderAttributesLimitList = Splitter.on(",").splitToList(orderAttributesLimit);
return orderAttributesLimitList.contains(orderAttributes.toString());
}
private boolean checkActivityRewardDays(InviteSettlementItemCreateRequest request, InviteRecord invitee, int rewardDays) {
int orderCreateTime = request.getOrderCreateTime();
int inviteTime = invitee.getCreateTime();
int rewardTime = inviteTime + (rewardDays * 24 * 60 * 60);
return rewardTime >= orderCreateTime;
}
}
... ...
package com.yohoufo.order.service.impl;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.dal.order.InviteSettlementItemMapper;
import com.yohoufo.dal.order.InviteSettlementMapper;
import com.yohoufo.dal.order.InviterMapper;
import com.yohoufo.dal.order.model.InviteSettlement;
import com.yohoufo.dal.order.model.InviteSettlementItem;
import com.yohoufo.dal.order.model.InviteSettlementItemStats;
import com.yohoufo.dal.order.model.Inviter;
import com.yohoufo.order.model.InviteSettlementItemListVO;
import com.yohoufo.order.model.InviteSettlementListVO;
import com.yohoufo.order.service.IInviteSettlementService;
import com.yohoufo.order.utils.InviteSettlementUtils;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.RoundingMode;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.yohoufo.order.utils.ServiceExceptions.throwServiceException;
/**
* @author LUOXC
* @date 2019/4/2 15:27
... ... @@ -34,6 +51,9 @@ public class InviteSettlementServiceImpl implements IInviteSettlementService {
private InviteSettlementMapper inviteSettlementMapper;
@Autowired
private InviteSettlementItemMapper inviteSettlementItemMapper;
@Autowired
private InviteSettlementItemCreator inviteSettlementItemCreator;
@Override
... ... @@ -43,12 +63,12 @@ public class InviteSettlementServiceImpl implements IInviteSettlementService {
List<InviteSettlement> inviteSettlementList = inviteSettlementMapper.selectByUidAndStatusWithLimit(uid, InviteSettlement.STATUS_PAID, 0, 100);
// build vo
ZoneOffset zoneOffset = ZoneOffset.of("+8");
List<InviteSettlementListVO.InviteSettlementVO> items = inviteSettlementList.stream()
.map(inviteSettlement -> {
InviteSettlementListVO.InviteSettlementVO item = new InviteSettlementListVO.InviteSettlementVO();
item.setSettleCode(String.format("%010d", inviteSettlement.getSettleCode()));
item.setSettleAmount("+" + inviteSettlement.getSettleAmount().setScale(1, RoundingMode.FLOOR));
item.setSettleAmount(InviteSettlementUtils.format("+%s", inviteSettlement.getSettleAmount()));
item.setSettleTime(DateUtil.formatYYMMddHHmmssPoint(inviteSettlement.getSettleTime()));
item.setPaidTime(DateUtil.formatYYMMddHHmmssPoint(inviteSettlement.getPaidTime()));
return item;
... ... @@ -60,6 +80,73 @@ public class InviteSettlementServiceImpl implements IInviteSettlementService {
}
@Override
public InviteSettlementItemListVO getInviteSettlementItemList(Integer uid, String month, Integer page, Integer limit) {
Pair<Integer, Integer> time = getTimeRangeOfMonth(month);
// 只查询结算规则1的记录
int settlementType = 1;
InviteSettlementItemStats stats = inviteSettlementItemMapper.selectStats(uid, settlementType, time.getLeft(), time.getRight());
int totalElements = Objects.isNull(stats.getTotalElements()) ? 0 : stats.getTotalElements();
BigDecimal totalOrderAmount = Objects.isNull(stats.getTotalOrderAmount()) ? BigDecimal.ZERO : stats.getTotalOrderAmount();
BigDecimal totalSettleAmount = Objects.isNull(stats.getTotalSettleAmount()) ? BigDecimal.ZERO : stats.getTotalSettleAmount();
InviteSettlementItemListVO.InviteSettlementItemListVOBuilder builder = InviteSettlementItemListVO.builder();
builder.page(page)
.pageSize(limit)
.pageTotal((totalElements % limit == 0) ? (totalElements / limit) : (totalElements / limit + 1))
.totalElements(totalElements)
.totalOrderAmount(InviteSettlementUtils.format(totalOrderAmount))
.totalSettleAmount(InviteSettlementUtils.format(totalSettleAmount));
if (totalElements == 0) {
return builder.list(Lists.newArrayList()).build();
}
int start = (page - 1) * limit;
List<InviteSettlementItem> list = inviteSettlementItemMapper.select(uid, settlementType, time.getLeft(), time.getRight(), start, limit);
Map<Integer, Integer> settlementStatusMap = buildInviteSettlementIdStatusMap(uid, list);
return builder
.list(list.stream().map(item -> {
Integer settlementStatus = settlementStatusMap.getOrDefault(item.getInviteSettlementId(), InviteSettlement.STATUS_WAIT_SETTLE);
InviteSettlementItemListVO.InviteSettlementItemVO vo = new InviteSettlementItemListVO.InviteSettlementItemVO();
vo.setBuyerOrderCode(item.getBuyerOrderCode().toString());
vo.setSellerName(item.getSellerUid().toString());
vo.setOrderAmount(InviteSettlementUtils.format(item.getOrderAmount()));
vo.setOrderCreateTime(DateUtil.formatYYMMddHHmmssPoint(item.getOrderCreateTime()));
vo.setSettleAmount(InviteSettlementUtils.format(item.getSettleAmount()));
vo.setStatusDesc(settlementStatus.equals(InviteSettlement.STATUS_PAID) ? "已付款" : "待付款");
return vo;
}).collect(Collectors.toList()))
.build();
}
private Map<Integer, Integer> buildInviteSettlementIdStatusMap(Integer uid, List<InviteSettlementItem> list) {
val inviteSettlementIds = list.stream()
.map(InviteSettlementItem::getInviteSettlementId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(inviteSettlementIds)) {
return Collections.emptyMap();
} else {
return inviteSettlementMapper.selectByUidAndIds(uid, inviteSettlementIds).stream()
.collect(Collectors.toMap(InviteSettlement::getId, InviteSettlement::getStatus));
}
}
@VisibleForTesting
Pair<Integer, Integer> getTimeRangeOfMonth(String month) {
LocalDateTime requestMonth = null;
try {
requestMonth = LocalDateTime.parse(month, DateTimeFormatter.ofPattern("yyyyMM"));
} catch (Exception e) {
throwServiceException("日期格式不正确");
}
ZoneOffset zoneOffset = ZoneOffset.of("+8");
int startTime = (int) LocalDateTime.of(requestMonth.getYear(), requestMonth.getMonthValue(), 1, 0, 0, 0)
.toEpochSecond(zoneOffset);
int endTime = (int) LocalDateTime.of(requestMonth.getYear(), requestMonth.getMonthValue() + 1, 1, 0, 0, 0)
.toEpochSecond(zoneOffset) - 1;
return Pair.of(startTime, endTime);
}
@Override
public void settle() {
inviterMapper.selectAll().stream()
.map(Inviter::getUid)
... ...
package com.yohoufo.order.utils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;
/**
* @author LUOXC
* @date 2019/4/11 11:04
*/
public class InviteSettlementUtils {
public static String format(BigDecimal src) {
return format("%s", src);
}
public static String format(String format, BigDecimal src) {
if (Objects.isNull(src)) {
return null;
} else {
return String.format(format, src.setScale(1, RoundingMode.FLOOR));
}
}
}
... ...
package com.yohoufo.order.service.impl;
import org.apache.commons.lang3.tuple.Pair;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.*;
public class InviteSettlementServiceImplTest {
@Test
public void getTimeRangeOfMonth() {
Pair<Integer, Integer> integerIntegerPair = new InviteSettlementServiceImpl().getTimeRangeOfMonth("201903");
Assert.assertEquals(integerIntegerPair.getLeft().intValue(),1551369600);
Assert.assertEquals(integerIntegerPair.getRight().intValue(),1554047999);
}
}
\ No newline at end of file
... ...
... ... @@ -117,4 +117,6 @@ offline.store.seller=${offline.store.seller}
ip.port.uic.server = ${ip.port.uic.server}
ufo.nfc.syncBlockChain.url=${ufo.nfc.syncBlockChain.url}
\ No newline at end of file
ufo.nfc.syncBlockChain.url=${ufo.nfc.syncBlockChain.url}
ufo.invite.productSortLimit=16,20,40
\ No newline at end of file
... ...
... ... @@ -5,148 +5,318 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<style>
img {
border: 0;
display: block;
margin: 0 auto;
max-width: 100%;
}
.open-wechat-QR {
display: none;
}
.top-downloadbar.wechat .download-go {
position: absolute;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
font-size: .7rem;
padding: 0 .5rem;
height: 1.35rem;
line-height: 1.35rem;
border-radius: .165rem;
color: #fff;
text-decoration: none;
right: 5.375rem;
background: #000;
}
.top-downloadbar.wechat .open-wechat-QR {
display: block;
position: absolute;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
font-size: .7rem;
padding: 0 .5rem;
height: 1.35rem;
line-height: 1.35rem;
border-radius: .165rem;
color: #fff;
text-decoration: none;
right: .375rem;
background: red;
}
.mini-app-container {
display: none;
position: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 99;
}
.mini-app-container.show {
display: block;
}
.mini-app-container .mini-app-dialog {
position: absolute;
width: 12.5rem;
left: 50%;
top: 50%;
background-color: #fff;
-webkit-border-radius: 0.2rem;
border-radius: 0.2rem;
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
overflow: hidden;
}
.mini-app-dialog .mini-app-header {
position: relative;
width: 100%;
height: 2rem;
line-height: 2rem;
}
.mini-app-dialog .mini-app-close {
width: 0.75rem;
height: 0.75rem;
position: absolute;
right: 0.25rem;
top: 0.25rem;
background-size: cover;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmFJREFUeNrMl99OE0EUxrdL9bYYbWoEJajUP5ckXsM2IZJe0IQQqY9AGq0+QY0vUExs+gqQkCblAi0ktPckvUQoQoyihDbE6qWELN9pzjbr6O7MlK7xJB/Tdg/nN+fszOzZkG3bhszK5fIlDI+hKegRdAe6wpe/Q/vQFrQBradSqV+ymCE/MICDGF5AGeiaoWYnUAHKYwJtbTCgaQyLUMzozZpQFvAlJTCAAxjecJb9sCL0DBM48wQzlGY4Z/TXStATN9wUHBYDgJLNchX/zBjZznO2QdpT5553wLx6dy6wkFStBcVptTulzvpAJ3jfNhQCb0Mj0LTH9Sj0snOPke1lyQr+ihkeYExAexKoBd/P9D8+fhlimnwaRX0c38FxCAEpmOUBJ2gCPk34UsarPvGu0ilo8lHoZ2PQpgsuZv6BocfwuYXPVWhUErMDHle4d3GG3wDgkOEfGWq5oDUFKNm4yRkZPcCtHjLtVjGMPxGN7XCP4RbDaSveZOhtjTgRytjW3Iu24m++RuCfGv67XN4jZDoMXcfnL1z2A404P0zJ3hShlgPl8lZd8EkN+B6B67qZMvQudJ/vuS68TuCKxKnB0G8C1LEHDI9plL1icp/U8nFKuqCbAtQNrzKcjswZSWtUcZ5OOXx55eFI5aNM3ivseTo6k9BDaM3D5zUmlwvzF3pIL3g8oWoaq5WAnySPxXy3A+FuMGsEb8+dzrPb+uCHZQxvA4QW3B2n2HNRD70SALQkVvQ3MHeBaW7I+2VFscP8vxr6v7zCZLk1iv6TVxiFl7ZBvtwWXtoqAJ7KYp4LMACryxGMnWAbNgAAAABJRU5ErkJggg==");
}
.mini-app-dialog .mini-app-content {
padding: 0.625rem;
text-align: center;
}
#mini_app_img {
width: 6.45rem;
height: 6.45rem;
}
.mini-app-footer {
height: 3.65rem;
line-height: 3.65rem;
font-size: 0.7rem;
text-align: center;
}
</style>
<script type="text/javascript">
(function(d,c){var e=d.documentElement,a="orientationchange" in window?"orientationchange":"resize",b=function(){var f=e.clientWidth;if(!f){return}if(f>=750){e.style.fontSize="40px"}else{e.style.fontSize=40*(f/750)+"px"}};if(!d.addEventListener){return}b();c.addEventListener(a,b,false);d.addEventListener("DOMContentLoaded",b,false)})(document,window);
(function (d, c) {
var e = d.documentElement, a = "orientationchange" in window ? "orientationchange" : "resize", b = function () {
var f = e.clientWidth;
if (!f) {
return
}
if (f >= 750) {
e.style.fontSize = "40px"
} else {
e.style.fontSize = 40 * (f / 750) + "px"
}
};
if (!d.addEventListener) {
return
}
b();
c.addEventListener(a, b, false);
d.addEventListener("DOMContentLoaded", b, false)
})(document, window);
</script>
<link href="https://cdn.yoho.cn/ufo/1.0.1/css/swiper-4.4.1.min.css" rel="stylesheet" type="text/css"/>
<link href="https://cdn.yoho.cn/ufo/1.0.1/css/goodsDetail.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"></script>
<link href="//cdn.yoho.cn/ufo/1.0.1/css/swiper-4.4.1.min.css" rel="stylesheet" type="text/css"/>
<link href="//cdn.yoho.cn/ufo/1.0.1/css/goodsDetail.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.1.0.js"></script>
</head>
<body>
<div class="top-downloadbar" id="top-downloadbar">
<a href="javascript:void(0);" class="download-close" id="download-close"></a>
<span class="download-icon"></span>
<span class="download-text">Yoho!Buy有货</span>
<p class="download-text-desc">新用户送惊喜礼包</p>
<a class="download-go" id="download-go" href=''>立即打开</a>
</div>
<div class="goods-detail-page">
<div class="head">
<div class="swiper-pagination"></div>
<div class="top-downloadbar" id="top-downloadbar">
<a href="javascript:void(0);" class="download-close" id="download-close"></a>
<span class="download-icon"></span>
<span class="download-text">Yoho!Buy有货</span>
<p class="download-text-desc">新用户送惊喜礼包</p>
<a class="download-go" id="download-go" href=''>立即打开</a>
<a class="open-wechat-QR" id="open_wechat-qr">进入小程序</a>
</div>
<!--小程序二维码在微信中展示-->
<div class="mini-app-container">
<div class="mini-app-dialog">
<div class="mini-app-header">
<span class="mini-app-close" id="mini_app_close"></span>
</div>
<div class="swiper-container">
<div class="swiper-wrapper">
</div>
<div class="mini-app-content">
<img id="mini_app_img">
</div>
<h2 class="goods-title"></h2>
<ul class="goods-info">
<li>
<div class="label">颜色</div>
<div class="cont color"></div>
</li>
<li>
<div class="label">品牌</div>
<div class="cont brand-name"></div>
</li>
<li>
<div class="label">系列</div>
<div class="cont series-name"></div>
</li>
<li>
<div class="label">发货时间</div>
<div class="cont sale-time"></div>
</li>
<li>
<div class="label">货号</div>
<div class="cont product-code"></div>
</li>
</ul>
<img src="https://cdn.yoho.cn/ufoapp/productdetail/service.png" class="goods-dec">
<div class="mini-app-footer">长按识别小程序码进入</div>
</div>
<script src="https://cdn.yoho.cn/ufo/1.0.1/js/jquery-1.11.3.min.js" type="text/javascript"></script>
<script src="https://cdn.yoho.cn/ufo/1.0.1/js/swiper-4.4.1.min.js" type="text/javascript"></script>
<script src="https://cdn.yoho.cn/ufo/1.0.1/js/share.js"></script>
<script>
function getUrlParam(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) {
return unescape(r[2]);
}
</div>
<div class="goods-detail-page">
<div class="head">
<div class="swiper-pagination"></div>
</div>
<div class="swiper-container">
<div class="swiper-wrapper">
</div>
</div>
<h2 class="goods-title"></h2>
<ul class="goods-info">
<li>
<div class="label">颜色</div>
<div class="cont color"></div>
</li>
<li>
<div class="label">品牌</div>
<div class="cont brand-name"></div>
</li>
<li>
<div class="label">系列</div>
<div class="cont series-name"></div>
</li>
<li>
<div class="label">发货时间</div>
<div class="cont sale-time"></div>
</li>
<li>
<div class="label">货号</div>
<div class="cont product-code"></div>
</li>
</ul>
<img src="//cdn.yoho.cn/ufoapp/productdetail/service.png" class="goods-dec">
</div>
<script src="//cdn.yoho.cn/ufo/1.0.1/js/jquery-1.11.3.min.js" type="text/javascript"></script>
<script src="//cdn.yoho.cn/ufo/1.0.1/js/swiper-4.4.1.min.js" type="text/javascript"></script>
<script src="//cdn.yoho.cn/ufo/1.0.1/js/share.js"></script>
<script>
function getUrlParam(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) {
return unescape(r[2]);
}
return null;
}
function getImgUrl(src, width = 300, height = 300, mode = 2) {
return src ? src.replace(/(\{width}|\{height}|\{mode})/g, function ($0) {
const dict = {
'{width}': width,
'{height}': height,
'{mode}': mode || 2
};
return dict[$0];
}).replace(/https?:/, '') : '';
};
return null;
$(function () {
var productId = getUrlParam('id');
var ajaxUrl = location.pathname.indexOf('ufo-gateway') > -1 ? '/ufo-gateway' : '/';
var qrDomain = '//m.yohobuy.com/api/wechat/miniapp.jpg'; // 小程序二维码图片生成地址
/*if (location.hostname.indexOf('localhost') > -1) {
ajaxUrl = 'http://2.yohobuy.com/';
qrDomain = '//api-test3.dev.yohocorp.com/wechat/miniapp/img-check.jpg';
}*/
var isWechat = /MicroMessenger/.test(navigator.userAgent);
var errorCount = 0; // 加载二维码错误次数
if (isWechat) { // 判断如果在微信中则显示二维码,头部展示进入小程序按钮
$('#top-downloadbar').addClass('wechat');
var qrImage = qrDomain + '?param={"id":' + productId + '}&miniQrType=23&miniapp_type=63'; // 小程序二维码图片生成地址+参数获取二维码
$('#mini_app_img').attr('src', qrImage);
$('#mini_app_img')[0].onload = function() {
$('.mini-app-container').addClass('show'); // 打开页面就显示二维码
};
$('#mini_app_img')[0].onerror = function () {
if (errorCount < 5) {
errorCount += 1;
setTimeout(function(){
$('#mini_app_img').attr('src', qrImage);
}, 1000);
} else {
console.log('二维码图片无法加载');
}
}
$('#mini_app_close').on('click', function() { // 点击X按钮关闭二维码
$('.mini-app-container').removeClass('show');
});
$('#open_wechat-qr').on('click', function() { // 点击进入小程序按钮显示二维码
$('.mini-app-container').addClass('show');
})
}
function getImgUrl(src, width = 300, height = 300, mode = 2) {
return src ? src.replace(/(\{width}|\{height}|\{mode})/g, function($0) {
const dict = {
'{width}': width,
'{height}': height,
'{mode}': mode || 2
};
$('.download-go').attr('href', '//union.yoho.cn/union/app-downloads.html?openby:yohobuy={"action":"go.ufo","params":{"pagename":"productDetail","productId":' + productId + '}}')
return dict[$0];
}).replace(/https?:/, '') : '';
};
$('.download-close').on('click', function () {
$('.top-downloadbar').hide();
});
$.get(ajaxUrl, {
method: 'ufo.product.data',
product_id: productId
}, function (ret) {
if (ret && ret.code == 200) {
var data = ret.data && ret.data.product_info || {};
var goodsList = data.goods_list && data.goods_list[0] || {};
$(function() {
var productId = getUrlParam('id');
var ajaxUrl = location.pathname.indexOf('ufo-gateway') > -1 ? '/ufo-gateway' : '/';
$('.download-go').attr('href', 'https://union.yoho.cn/union/app-downloads.html?openby:yohobuy={"action":"go.ufo","params":{"pagename":"productDetail","productId":' + productId + '}}')
$('.download-close').on('click', function() {
$('.top-downloadbar').hide();
});
$.get(ajaxUrl, {
method: 'ufo.product.data',
product_id: productId
}, function(ret) {
if (ret && ret.code == 200) {
var data = ret.data && ret.data.product_info || {};
var goodsList = data.goods_list && data.goods_list[0] || {};
$('.color').html(goodsList.color_name || '');
$('.brand-name').html(data.brand_name || '');
$('.series-name').html(data.series_name || '');
$('.sale-time').html(data.sale_time || '');
$('.product-code').html(data.product_code || '');
$('.goods-title').html(data.product_name || '');
$('title').html(data.product_name || '商品详情');
goodsList.image_list.map(function(item) {
if(item.image_url) {
$('.swiper-wrapper').append('<div class="swiper-slide"><img src="' + getImgUrl(item.image_url, 750, 750) + '"></div>');
}
});
if ($('.swiper-slide').length > 0) {
new Swiper('.swiper-container', {
autoplay: true,
pagination: {
el: '.swiper-pagination',
type: 'fraction',
renderFraction: function (currentClass, totalClass) {
return '<span class="' + currentClass + '"></span>' +
'|' +
'<span class="' + totalClass + '"></span>';
}
}
});
}
var shareImg = '';
if (goodsList && goodsList.image_list && goodsList.image_list.length > 0) {
shareImg = getImgUrl(goodsList.image_list[0].image_url);
}
share({
shareTitle: data.product_name + '-UFO潮流好物',
shareDesc: '我在UFO飞碟好物发现了一件超棒的商品,戳进来看>>>',
shareImg: 'http:' + shareImg,
shareLink: location.href
})
}
})
$('.color').html(goodsList.color_name || '');
$('.brand-name').html(data.brand_name || '');
$('.series-name').html(data.series_name || '');
$('.sale-time').html(data.sale_time || '');
$('.product-code').html(data.product_code || '');
$('.goods-title').html(data.product_name || '');
$('title').html(data.product_name || '商品详情');
goodsList.image_list.map(function (item) {
if (item.image_url) {
$('.swiper-wrapper').append('<div class="swiper-slide"><img src="' + getImgUrl(item.image_url, 750, 750) + '"></div>');
}
});
</script>
if ($('.swiper-slide').length > 0) {
new Swiper('.swiper-container', {
autoplay: true,
pagination: {
el: '.swiper-pagination',
type: 'fraction',
renderFraction: function (currentClass, totalClass) {
return '<span class="' + currentClass + '"></span>' +
'|' +
'<span class="' + totalClass + '"></span>';
}
}
});
}
var shareImg = '';
if (goodsList && goodsList.image_list && goodsList.image_list.length > 0) {
shareImg = getImgUrl(goodsList.image_list[0].image_url);
}
share({
shareTitle: data.product_name + '-UFO潮流好物',
shareDesc: '我在UFO飞碟好物发现了一件超棒的商品,戳进来看>>>',
shareImg: 'http:' + shareImg,
shareLink: location.href
})
}
})
});
</script>
</body>
</html>
\ No newline at end of file
... ...