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
package com.matrix.system.shopXcx.api.service.impl;
 
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.matrix.system.hive.bean.SysVipInfo;
import com.matrix.component.redis.RedisUserLoginUtils;
import com.matrix.component.tools.WxUtils;
import com.matrix.component.wechat.externalInterface.protocol.paramProtocol.BrandWCPayRequestData;
import com.matrix.core.exception.GlobleException;
import com.matrix.core.pojo.AjaxResult;
import com.matrix.core.tools.StringUtils;
import com.matrix.system.common.constance.AppConstance;
import com.matrix.system.constance.Dictionary;
import com.matrix.system.hive.bean.ShoppingGoods;
import com.matrix.system.hive.dao.ShoppingGoodsDao;
import com.matrix.system.shopXcx.api.service.WXShopOrderService;
import com.matrix.system.shopXcx.api.service.WxShopActivitiesSecKillService;
import com.matrix.system.shopXcx.api.tools.WxShopOrderUtil;
import com.matrix.system.shopXcx.bean.*;
import com.matrix.system.shopXcx.dao.*;
import com.matrix.system.shopXcx.dto.CreateSecKillDTO;
import com.matrix.system.shopXcx.dto.DiscountExplain;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
/**
 * @author wzy
 * @date 2020-04-09 16:18
 **/
@Service
public class WxShopActivitiesSecKillServiceImpl implements WxShopActivitiesSecKillService {
 
    @Autowired
    private ShopActivitiesDao shopActivitiesDao;
    @Autowired
    private ShopActivitiesSeckillInfoDao shopActivitiesSeckillInfoDao;
    @Autowired
    private ShopOrderDao shopOrderDao;
    @Autowired
    private ShopReceiveAddressDao shopReceiveAddressDao;
    @Autowired
    private ShopSkuDao shopSkuDao;
    @Autowired
    private WxShopOrderUtil wxShopOrderUtil;
    @Autowired
    private ShoppingGoodsDao shoppingGoodsDao;
    @Autowired
    private WXShopOrderService wxShopOrderService;
    @Autowired
    private ShopOrderDetailsDao shopOrderDetailsDao;
    @Autowired
    private RedisUserLoginUtils redisUserLoginUtils;
    @Autowired
    private ShopActivitiesSeckillRecordDao shopActivitiesSeckillRecordDao;
 
    @Override
    public AjaxResult createSecKillOrder(CreateSecKillDTO secKillDTO) throws Exception {
        SysVipInfo sysVipInfo = redisUserLoginUtils.getLoginUser(SysVipInfo.class);
        ShopActivitiesSeckillInfo seckillInfo = shopActivitiesSeckillInfoDao.selectById(secKillDTO.getId());
        if (seckillInfo == null) {
            return AjaxResult.buildFailInstance("秒杀不存在");
        }
        ShopActivities shopActivities = shopActivitiesDao.selectById(seckillInfo.getActId());
        if (shopActivities.getActBeginTime().getTime() > System.currentTimeMillis()) {
            return AjaxResult.buildFailInstance("秒杀未开始,请耐心等待");
        }
 
        if (shopActivities.getActEndTime().getTime() < System.currentTimeMillis()) {
            return AjaxResult.buildFailInstance("秒杀已结束");
        }
 
        if (seckillInfo.getSiRemainCnt() != null && seckillInfo.getSiRemainCnt() != 0) {
            if (secKillDTO.getCount() > seckillInfo.getSiRemainCnt()) {
                return AjaxResult.buildFailInstance("商品不足");
            }
        }
 
        if (seckillInfo.getSiLimitCnt() != null && seckillInfo.getSiLimitCnt() != 0) {
            if (secKillDTO.getCount() > seckillInfo.getSiLimitCnt()) {
                return AjaxResult.buildFailInstance("购买数量超过最大限购数量");
            }
 
            int count = shopActivitiesSeckillRecordDao.selectCountSecKill(seckillInfo.getId(), sysVipInfo.getOpenId());
            if (secKillDTO.getCount() + count > seckillInfo.getSiLimitCnt()) {
                return AjaxResult.buildFailInstance("购买数量超过最大限购数量");
            }
        }
 
        secKillDTO.setPrice(seckillInfo.getSiPrice());
        secKillDTO.setGoodsId(seckillInfo.getGoodsId().intValue());
        secKillDTO.setOpenId(sysVipInfo.getOpenId());
        ShopOrder shopOrder = createOrder(secKillDTO);
 
        ShopActivitiesSeckillRecord seckillRecord = new ShopActivitiesSeckillRecord();
        seckillRecord.setOrderId(shopOrder.getId().longValue());
        seckillRecord.setSiId(seckillInfo.getId());
        seckillRecord.setUserId(sysVipInfo.getId());
        seckillRecord.setCreateBy(sysVipInfo.getNickName() == null ? "游客" : sysVipInfo.getNickName());
        seckillRecord.setUpdateBy(sysVipInfo.getNickName() == null ? "游客" : sysVipInfo.getNickName());
        seckillRecord.setCompanyId(seckillInfo.getCompanyId());
 
        // 同步锁
        synchronized (this) {
            ShopActivitiesSeckillInfo remain = shopActivitiesSeckillInfoDao.selectById(secKillDTO.getId());
            if (secKillDTO.getCount() > remain.getSiRemainCnt()) {
                return AjaxResult.buildFailInstance("商品不足");
            }
 
            shopActivitiesSeckillRecordDao.insert(seckillRecord);
            // 更新数据剩余数量
            seckillInfo.setSiRemainCnt(seckillInfo.getSiRemainCnt() - secKillDTO.getCount());
            shopActivitiesSeckillInfoDao.updateByModel(seckillInfo);
        }
 
        BrandWCPayRequestData payData = wxShopOrderService.startPayment(shopOrder);
        AjaxResult result = new AjaxResult(AjaxResult.STATUS_SUCCESS, Arrays.asList(payData));
//        AjaxResult result = AjaxResult.buildSuccessInstance("sucess");
        result.putInMap("orderId", shopOrder.getId());
        return result;
    }
 
    private ShopOrder createOrder(CreateSecKillDTO secKillDTO) {
        SysVipInfo sysVipInfo = redisUserLoginUtils.getLoginUser(SysVipInfo.class);
        ShopReceiveAddress shopReceiveAddress = shopReceiveAddressDao.selectById(secKillDTO.getAddressId());
        if (shopReceiveAddress == null) {
            throw new GlobleException("请选择正确的收获地址");
        }
 
        ShopOrder shopOrder = new ShopOrder();
        shopOrder.setStoreId(Integer.parseInt(secKillDTO.getShopId().toString()));
        shopOrder.setOrderType(ShopOrder.ORDER_TYPE_SERVICE);
 
        List<ShopSku> shopSkus = shopSkuDao.selectByPid(secKillDTO.getGoodsId());
 
        List<ShopOrderDetails> details = new ArrayList<>();
        ShopOrderDetails shopOrderDetails = new ShopOrderDetails();
        shopOrderDetails.setCreateBy(AppConstance.SYSTEM_USER);
        shopOrderDetails.setUpdateBy(AppConstance.SYSTEM_USER);
        shopOrderDetails.setpId(secKillDTO.getGoodsId());
        shopOrderDetails.setsId(shopSkus.get(0).getId());
        shopOrderDetails.setPrice(secKillDTO.getPrice());
        shopOrderDetails.setCount(secKillDTO.getCount());
        shopOrderDetails.setsTitle(shopSkus.get(0).getName());
        shopOrderDetails.setDiscountAmount(BigDecimal.ZERO);
        shopOrderDetails.setTotalPrice(shopOrderDetails.getPrice().multiply(BigDecimal.valueOf(shopOrderDetails.getCount())));
        details.add(shopOrderDetails);
 
        //查询绑定的产品是否为家居产品,如果已经含家具产品则不再比较
        if (ShopOrder.ORDER_TYPE_GOODS != shopOrder.getOrderType()) {
            ShopSku shopSku = shopSkuDao.selectById(shopSkus.get(0).getId().intValue());
            String stokCode = shopSku.getStockCode();
            if (StringUtils.isNotBlank(stokCode)) {
                ShoppingGoods shoppingGoods = shoppingGoodsDao.selectById(Long.parseLong(stokCode));
                if (shoppingGoods != null) {
                    //根据购买的产品设置订单类型
                    if (Dictionary.SHOPPING_GOODS_TYPE_JJCP.equals(shoppingGoods.getGoodType())) {
                        shopOrder.setOrderType(ShopOrder.ORDER_TYPE_GOODS);
                    } else {
 
                    }
                } else {
                    shopOrder.setOrderType(ShopOrder.ORDER_TYPE_GOODS);
                }
            }
        }
 
        //TODO 更新库存和销量 更新库存和销量[考虑和erp库存联动]
        wxShopOrderUtil.updateProductAndSkuInfo(details);
 
        shopOrder.setUserId(secKillDTO.getId());
        shopOrder.setCreateBy("微信小程序生成");
        shopOrder.setUpdateBy("微信小程序生成");
        shopOrder.setCommodityPrice(secKillDTO.getPrice());
        shopOrder.setPurchaseQuantity(1);
        shopOrder.setCompanyId(sysVipInfo.getCompanyId());
        //购买方式
        shopOrder.setShippingMethod(secKillDTO.getShippingMethod());
        //生成订单号
        shopOrder.setOrderNo(WxUtils.getOrderNum());
        //设置支付状态
        shopOrder.setPayStatus(ShopOrder.ORDER_STATUS_WAIT_PAY);
        //设置订单状态
        shopOrder.setOrderStatus(ShopOrder.ORDER_PAY_STATUS_WAIT);
 
        //设置退款费用(注:下次优化从数据字典表获取)
        shopOrder.setRefundCharge(BigDecimal.ZERO);
        //客户电话
        shopOrder.setUserTel(shopReceiveAddress.getAddrTelephone());
        //客户姓名
        shopOrder.setUserName(shopReceiveAddress.getAddrLiaisonman());
        //删除标识
        shopOrder.setDelFlag(AppConstance.DATA_USEABLE);
        shopOrder.setActivityType(ShopOrder.ACTIVITY_TYPE_SECKILL);
        //微信订单号
        shopOrder.setWxOrderNo("");
        //微信支付结果
        shopOrder.setPayResult(ShopOrder.ORDER_WX_STATUS_WAIT_PAY);
        //如果没有提交购买方式或配送方式不是物流
        //获取邮费
        BigDecimal postPrice = wxShopOrderService.calculationPostage(secKillDTO.getPrice(),sysVipInfo.getCompanyId());
        shopOrder.setPostage(postPrice);
        BigDecimal payPrice = secKillDTO.getPrice().multiply(BigDecimal.valueOf(secKillDTO.getCount())).add(shopOrder.getPostage());
        shopOrder.setOrderMoney(payPrice);
        DiscountExplain discountExplain = new DiscountExplain();
        discountExplain.setPayPrice(payPrice);
        discountExplain.setPostage(postPrice);
        discountExplain.setActivityPrice(BigDecimal.ZERO);
        discountExplain.setCouponPrice(BigDecimal.ZERO);
        discountExplain.setBillPrice(payPrice);
        Gson g = new GsonBuilder().create();
        shopOrder.setDiscountExplain(g.toJson(discountExplain));
        shopOrderDao.insert(shopOrder);
 
        wxShopOrderUtil.insertSendPackageInfo(shopOrder, secKillDTO.getShippingMethod(), shopReceiveAddress);
        //给订单详情表添加订单ID
        for (ShopOrderDetails detail : details) {
            detail.setOrderId(shopOrder.getId());
        }
        if (CollectionUtils.isNotEmpty(details)) {
            shopOrderDetailsDao.batchInsert(details);
        }
        return shopOrder;
    }
}