admin
2020-04-02 ae18b82458f50dd07ea5afff9b8cd0be4608fb45
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
package com.yeshi.fanli.service.impl.order;
 
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
 
import javax.annotation.Resource;
 
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import com.yeshi.fanli.dao.mybatis.order.InviteOrderSubsidyMapper;
import com.yeshi.fanli.entity.bus.user.HongBaoV2;
import com.yeshi.fanli.entity.bus.user.vip.UserLevelEnum;
import com.yeshi.fanli.entity.order.CommonOrder;
import com.yeshi.fanli.entity.order.HongBaoOrder;
import com.yeshi.fanli.entity.order.InviteOrderSubsidy;
import com.yeshi.fanli.exception.order.CommonOrderException;
import com.yeshi.fanli.exception.order.InviteOrderSubsidyException;
import com.yeshi.fanli.exception.order.OrderTeamRewardException;
import com.yeshi.fanli.service.inter.order.CommonOrderService;
import com.yeshi.fanli.service.inter.order.HongBaoOrderService;
import com.yeshi.fanli.service.inter.order.HongBaoV2Service;
import com.yeshi.fanli.service.inter.order.InviteOrderSubsidyServiceV2;
import com.yeshi.fanli.service.inter.order.OrderHongBaoMapService;
import com.yeshi.fanli.service.inter.order.OrderHongBaoMoneyComputeService;
import com.yeshi.fanli.service.inter.order.config.HongBaoManageService;
import com.yeshi.fanli.service.inter.user.invite.ThreeSaleSerivce;
import com.yeshi.fanli.service.inter.user.vip.UserVIPInfoService;
import com.yeshi.fanli.service.manger.user.UserLevelManager;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.TimeUtil;
 
@Service
public class InviteOrderSubsidyServiceImplV2 implements InviteOrderSubsidyServiceV2 {
 
    @Resource
    private InviteOrderSubsidyMapper inviteOrderSubsidyMapper;
 
    @Resource
    private HongBaoV2Service hongBaoV2Service;
 
    @Resource
    private HongBaoOrderService hongBaoOrderService;
 
    @Resource
    private OrderHongBaoMapService orderHongBaoMapService;
 
    @Resource
    private CommonOrderService commonOrderService;
 
    @Resource
    private HongBaoManageService hongBaoManageService;
 
    @Resource
    private UserVIPInfoService userVIPInfoService;
 
    @Resource
    private UserLevelManager userLevelManager;
 
    @Resource
    private OrderHongBaoMoneyComputeService orderHongBaoMoneyComputeService;
 
    @Resource
    private ThreeSaleSerivce threeSaleSerivce;
 
    @Override
    public InviteOrderSubsidy getByOrderNoAndType(Long uid, String orderNo, Integer type) {
        return inviteOrderSubsidyMapper.getByOrderNoAndType(uid, orderNo, type);
    }
 
    @Override
    public InviteOrderSubsidy getByOrderNoAndTypeForUpdate(Long uid, String orderNo, Integer type) {
        return inviteOrderSubsidyMapper.getByOrderNoAndTypeForUpdate(uid, orderNo, type);
    }
 
    @Transactional(rollbackFor = Exception.class)
    private void addOrderSubsidy(InviteOrderSubsidy orderSubsidy)
            throws InviteOrderSubsidyException, OrderTeamRewardException, CommonOrderException {
        if (orderSubsidy.getMoney() == null || StringUtil.isNullOrEmpty(orderSubsidy.getOrderNo())
                || orderSubsidy.getSourceType() == null || orderSubsidy.getUid() == null)
            throw new InviteOrderSubsidyException(1, "数据不完整");
        InviteOrderSubsidy old = getByOrderNoAndType(orderSubsidy.getUid(), orderSubsidy.getOrderNo(),
                orderSubsidy.getSourceType());
        if (old != null) {// 修改
            if (old.getState() == InviteOrderSubsidy.STATE_INVALID
                    || old.getState() == InviteOrderSubsidy.STATE_SUBSIDIZED)
                return;
 
            // 修改状态
            InviteOrderSubsidy update = new InviteOrderSubsidy(old.getId());
            update.setMoney(orderSubsidy.getMoney());
            if (old.getState() == InviteOrderSubsidy.STATE_UNKNOWN) {// 状态未确定之前才可以更改原始补贴资金
                update.setOriginalMoney(orderSubsidy.getOriginalMoney());
            }
            update.setState(orderSubsidy.getState());
            update.setUpdateTime(new Date());
            inviteOrderSubsidyMapper.updateByPrimaryKeySelective(update);
            //TODO 删除添加奖励
        } else {// 添加
            if (orderSubsidy.getCreateTime() == null)
                orderSubsidy.setCreateTime(new Date());
            inviteOrderSubsidyMapper.insertSelective(orderSubsidy);
            //TODO 删除添加奖励
        }
    }
 
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addOrUpdateByOrder(String orderId, int sourceType) throws InviteOrderSubsidyException {
        List<HongBaoOrder> list = hongBaoOrderService.listByOrderIdAndSourceType(orderId, sourceType);
        if (list != null && list.size() > 0) {
            // 必须是自购订单才返利
            HongBaoV2 parent = hongBaoV2Service.selectByPrimaryKey(list.get(0).getHongBaoV2().getId());
            if (parent != null && parent.getUrank() != UserLevelEnum.superVIP.getOrderRank()
                    && (parent.getType() == HongBaoV2.TYPE_SHARE_GOODS || parent.getType() == HongBaoV2.TYPE_ZIGOU)) {// 不是超级会员的自购/分享才补贴
                boolean isShare = (parent.getType() == HongBaoV2.TYPE_SHARE_GOODS);
 
                List<CommonOrder> orderList = commonOrderService.listBySourceTypeAndOrderId(sourceType, orderId);
                if (orderList == null || orderList.size() == 0)
                    throw new InviteOrderSubsidyException(10, "订单为空");
                CommonOrder firstOrder = orderList.get(0);
                Date placeOrderTime = firstOrder.getThirdCreateTime();
                int urank = firstOrder.getUrank();
                UserLevelEnum buyerUserLevel = null;
                for (UserLevelEnum level : UserLevelEnum.values())
                    if (level.getOrderRank() == urank)
                        buyerUserLevel = level;
 
                if (buyerUserLevel == null)
                    throw new InviteOrderSubsidyException(11, "用户等级为空");
 
                List<Long> idList = new ArrayList<>();
                for (HongBaoOrder ho : list)
                    if (ho.getHongBaoV2() != null)
                        idList.add(ho.getHongBaoV2().getId());
                // 查询该订单号下的所有子红包
                List<HongBaoV2> children = hongBaoV2Service.listChildrenByIds(idList);
                if (children != null && children.size() > 0) {
                    Map<Long, Integer> uidHongBaoMap = new ConcurrentHashMap<>();
                    for (HongBaoV2 v2 : children) {// 按用户ID统计红包
                        Long uid = v2.getUserInfo().getId();
                        if (v2.getState() == HongBaoV2.STATE_BUKELINGQU || v2.getState() == HongBaoV2.STATE_KELINGQU
                                || v2.getState() == HongBaoV2.STATE_YILINGQU) {
                            uidHongBaoMap.put(uid, v2.getType());
                        }
                    }
 
                    List<HongBaoV2> hbList = hongBaoV2Service.listByIds(idList);
                    int state = InviteOrderSubsidy.STATE_UNKNOWN;
                    // 确定是否使用了奖励券
                    if (orderHongBaoMapService.selectByOrderIdAndSourceType(orderId, sourceType) != null) {
                        state = InviteOrderSubsidy.STATE_INVALID;
                    } else {
                        // 确定是否返利到账5天后
                        if (recieveMoneyMoreThan(hbList, 5)) {
                            state = InviteOrderSubsidy.STATE_VALID;
                        } else {
                            state = InviteOrderSubsidy.STATE_UNKNOWN;
                        }
                    }
 
                    // 产生改订单的返利总金额
                    BigDecimal totalBuyFanLiMoney = new BigDecimal(0);
                    // 计算总返利
                    for (HongBaoV2 v2 : hbList) {
                        if (v2.getState() == HongBaoV2.STATE_BUKELINGQU || v2.getState() == HongBaoV2.STATE_KELINGQU
                                || v2.getState() == HongBaoV2.STATE_YILINGQU)
                            totalBuyFanLiMoney = totalBuyFanLiMoney.add(v2.getMoney());
                    }
 
                    // 计算奖励金
                    for (Iterator<Long> its = uidHongBaoMap.keySet().iterator(); its.hasNext();) {
                        Long uid = its.next();
                        UserLevelEnum userLevel = userLevelManager.getUserLevel(uid, placeOrderTime);
 
                        int type = uidHongBaoMap.get(uid);
                        if (type == HongBaoV2.TYPE_YIJI || type == HongBaoV2.TYPE_ERJI) {
                            BigDecimal money = null;
                            if (type == HongBaoV2.TYPE_YIJI)
                                money = orderHongBaoMoneyComputeService.computeFirstTeamSubsidy(totalBuyFanLiMoney,
                                        placeOrderTime, buyerUserLevel, userLevel);
                            else
                                money = orderHongBaoMoneyComputeService.computeSecondTeamSubsidy(totalBuyFanLiMoney,
                                        placeOrderTime, buyerUserLevel, userLevel);
 
                            InviteOrderSubsidy orderSubsidy = new InviteOrderSubsidy();
                            orderSubsidy.setMoney(money);
                            orderSubsidy.setOriginalMoney(money);
                            orderSubsidy.setUid(uid);
                            orderSubsidy.setOrderNo(orderId);
                            orderSubsidy.setSourceType(sourceType);
                            orderSubsidy.setState(state);
                            if (type == HongBaoV2.TYPE_YIJI)
                                orderSubsidy.setLevel(InviteOrderSubsidy.LEVEL_ONE);
                            else
                                orderSubsidy.setLevel(InviteOrderSubsidy.LEVEL_TWO);
                            // 会员才能补贴
                            if (userLevel != UserLevelEnum.daRen) {
                                try {
                                    addOrderSubsidy(orderSubsidy);
                                } catch (OrderTeamRewardException e) {
                                    throw new InviteOrderSubsidyException(e.getCode(), e.getMsg());
                                } catch (CommonOrderException e) {
                                    throw new InviteOrderSubsidyException(e.getCode(), e.getMsg());
                                }
                                // 分享赚不能使用返利奖励券,不用等待5天
                                if (isShare) {
                                    validByOrderIdAndSourceType(orderId, sourceType);
                                }
                            }
                        }
                    }
                }
            }
        }
 
    }
 
    private boolean recieveMoneyMoreThan(List<HongBaoV2> hbList, int day) {
        // 是否全部是到账状态或失效状态
        int invalidCount = 0;// 失效个数
        int recieveCount = 0;// 到账的个数
        long maxGetTime = 0;
        for (HongBaoV2 v2 : hbList) {
            if (v2.getState() == HongBaoV2.STATE_SHIXIAO)
                invalidCount++;
            else if (v2.getState() == HongBaoV2.STATE_YILINGQU) {
                recieveCount++;
                if (v2.getGetTime() != null && v2.getGetTime().getTime() > maxGetTime)
                    maxGetTime = v2.getGetTime().getTime();
 
            }
        }
        if (invalidCount + recieveCount == hbList.size() && recieveCount > 0 && maxGetTime > 0) {// 全部已到账
            // 查询到账时间距离当前时间是否超过指定天
            if (System.currentTimeMillis() - maxGetTime > 1000 * 60 * 60 * 24L * day)
                return true;
        }
        return false;
    }
 
    @Override
    public long countByOrderIdAndSourceType(String orderId, int sourceType) {
        return inviteOrderSubsidyMapper.countByOrderNoAndType(orderId, sourceType);
    }
 
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void invalidByOrderIdAndSourceType(String orderId, int sourceType) {
        List<InviteOrderSubsidy> list = inviteOrderSubsidyMapper.listByOrderNoAndType(orderId, sourceType);
        if (list != null && list.size() > 0)
            for (InviteOrderSubsidy subsidy : list) {
                if (subsidy.getState() == InviteOrderSubsidy.STATE_UNKNOWN
                        || subsidy.getState() == InviteOrderSubsidy.STATE_VALID) {
                    InviteOrderSubsidy update = new InviteOrderSubsidy(subsidy.getId());
                    update.setState(InviteOrderSubsidy.STATE_INVALID);
                    update.setUpdateTime(new Date());
                    update.setInValidTime(new Date());
                    inviteOrderSubsidyMapper.updateByPrimaryKeySelective(update);
                }
            }
    }
 
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void validByOrderIdAndSourceType(String orderId, int sourceType) throws InviteOrderSubsidyException {
        // 查询预计到账时间
        List<CommonOrder> orderList = commonOrderService.listBySourceTypeAndOrderId(sourceType, orderId);
        if (orderList == null || orderList.size() == 0)
            throw new InviteOrderSubsidyException(31, "订单不存在");
 
        if (orderList.get(0).getSettleTime() == null)
            throw new InviteOrderSubsidyException(32, "订单尚未确认收货");
 
        // 确认收货时间的下月25号到账
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(orderList.get(0).getSettleTime());
        calendar.add(Calendar.MONTH, 1);
        Date preGetTime = new Date(TimeUtil.convertToTimeTemp(
                calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH) + 1) + "-25", "yyyy-M-dd"));
 
        List<InviteOrderSubsidy> list = inviteOrderSubsidyMapper.listByOrderNoAndType(orderId, sourceType);
        if (list != null && list.size() > 0)
            for (InviteOrderSubsidy subsidy : list) {
                if (subsidy.getState() == InviteOrderSubsidy.STATE_UNKNOWN) {
                    InviteOrderSubsidy update = new InviteOrderSubsidy(subsidy.getId());
                    update.setState(InviteOrderSubsidy.STATE_VALID);
                    update.setUpdateTime(new Date());
                    update.setValidTime(new Date());
                    update.setPreGetTime(preGetTime);
                    inviteOrderSubsidyMapper.updateByPrimaryKeySelective(update);
                }
            }
    }
 
    @Override
    public void settleById(Long id, BigDecimal money) {
        InviteOrderSubsidy orderSubsidy = new InviteOrderSubsidy(id);
        orderSubsidy.setMoney(money);
        orderSubsidy.setState(InviteOrderSubsidy.STATE_SUBSIDIZED);
        orderSubsidy.setUpdateTime(new Date());
        inviteOrderSubsidyMapper.updateByPrimaryKeySelective(orderSubsidy);
    }
 
    
    @Override
    public BigDecimal sumRecievedMoneyByUid(long uid,  Integer level) {
        return inviteOrderSubsidyMapper.sumRecievedMoneyByUid(uid, level);
    }
    
    @Override
    public BigDecimal sumValidMoneyByUidAndDate(long uid, Integer day, Integer level) {
        return inviteOrderSubsidyMapper.sumValidMoneyByUidAndDate(uid, day, level);
    }
    
    
    
    
}