瀏覽代碼

Merge branch 'dev'

xiongzhu 4 年之前
父節點
當前提交
c5d11c5f6c

+ 6 - 0
src/main/java/com/izouma/nineth/config/ErrorCode.java

@@ -0,0 +1,6 @@
+package com.izouma.nineth.config;
+
+public class ErrorCode {
+    public static final int SOLD_OUT = 1001;
+    public static final int OFF_SHELF = 1002;
+}

+ 4 - 0
src/main/java/com/izouma/nineth/config/RedisKeys.java

@@ -20,4 +20,8 @@ public class RedisKeys {
     public static final String MINT_ORDER_LOCK = "mintOrderLock::";
 
     public static final String ACTIVITY_PAY_RECORD = "activityPayRecord::";
+
+    public static final String UPDATE_SALE = "updateSale";
+
+    public static final String UPDATE_STOCK = "updateSale";
 }

+ 25 - 0
src/main/java/com/izouma/nineth/domain/BlackList.java

@@ -0,0 +1,25 @@
+package com.izouma.nineth.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+
+@Data
+@Entity
+@AllArgsConstructor
+@NoArgsConstructor
+public class BlackList extends BaseEntity {
+    private Long userId;
+
+    private String name;
+
+    private String phone;
+
+    private String ip;
+
+    private String reason;
+
+    private String ua;
+}

+ 22 - 2
src/main/java/com/izouma/nineth/listener/UpdateSaleListener.java

@@ -1,5 +1,6 @@
 package com.izouma.nineth.listener;
 
+import com.izouma.nineth.config.RedisKeys;
 import com.izouma.nineth.service.CollectionService;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -7,6 +8,9 @@ import org.apache.rocketmq.spring.annotation.ConsumeMode;
 import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
 import org.apache.rocketmq.spring.core.RocketMQListener;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.data.redis.core.BoundHashOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
 @Service
@@ -19,10 +23,26 @@ import org.springframework.stereotype.Service;
 @ConditionalOnProperty(value = "general.notify-server", havingValue = "false", matchIfMissing = true)
 public class UpdateSaleListener implements RocketMQListener<Long> {
 
-    private CollectionService collectionService;
+    private CollectionService             collectionService;
+    private RedisTemplate<String, Object> redisTemplate;
 
     @Override
     public void onMessage(Long id) {
-        collectionService.syncSale(id);
+        BoundHashOperations<String, String, Integer> ops = redisTemplate.boundHashOps(RedisKeys.UPDATE_SALE);
+        ops.increment(id.toString(), 1);
+    }
+
+    @Scheduled(fixedRate = 10000)
+    public void updateSale() {
+        BoundHashOperations<String, String, Integer> ops = redisTemplate.boundHashOps(RedisKeys.UPDATE_SALE);
+        for (String id : ops.keys()) {
+            Long val = ops.increment(id, -1);
+            if (val <= 0) {
+                ops.delete(id);
+            } else if (val > 1) {
+                ops.put(id, 1);
+            }
+            collectionService.syncSale(Long.parseLong(id));
+        }
     }
 }

+ 6 - 2
src/main/java/com/izouma/nineth/repo/UserRepo.java

@@ -181,9 +181,13 @@ public interface UserRepo extends JpaRepository<User, Long>, JpaSpecificationExe
 
     List<User> findBySettleAccountIdIsNotNull();
 
+//    @Transactional
+//    @Modifying
+//    @Query("update User set vipPoint = vipPoint + ?2 where id = ?1")
+//    void updateVipPoint(Long id, int num);
+
     @Transactional
     @Modifying
-    @Query("update User set vipPoint = vipPoint + ?2 where id = ?1")
+    @Query("update User set vipPoint = ?2 where id = ?1")
     void updateVipPoint(Long id, int num);
-
 }

+ 1 - 0
src/main/java/com/izouma/nineth/security/WebSecurityConfig.java

@@ -109,6 +109,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                 .antMatchers("/druid/**").permitAll()
                 .antMatchers("/testmq/**").permitAll()
                 .antMatchers("/teststock/**").permitAll()
+                .antMatchers("/debounce/**").permitAll()
                 // all other requests need to be authenticated
                 .anyRequest().authenticated().and()
                 // make sure we use stateless session; session won't be used to

+ 16 - 2
src/main/java/com/izouma/nineth/service/CollectionService.java

@@ -380,6 +380,19 @@ public class CollectionService {
         return stock;
     }
 
+    public synchronized Integer getStock(Long id) {
+        BoundValueOperations<String, Object> ops = redisTemplate.boundValueOps(RedisKeys.COLLECTION_STOCK + id);
+        Integer stock = (Integer) ops.get();
+        if (stock == null) {
+            Boolean success = ops.setIfAbsent(Optional.ofNullable(collectionRepo.getStock(id))
+                    .orElse(0), 7, TimeUnit.DAYS);
+            log.info("创建redis库存:{}", success);
+            return (Integer) ops.get();
+        } else {
+            return stock;
+        }
+    }
+
     public synchronized Long decreaseStock(Long id, int number) {
         return increaseStock(id, -number);
     }
@@ -392,7 +405,8 @@ public class CollectionService {
             log.info("创建redis销量:{}", success);
         }
         Long sale = ops.increment(number);
-        rocketMQTemplate.convertAndSend(generalProperties.getUpdateSaleTopic(), id);
+        redisTemplate.opsForHash().increment(RedisKeys.UPDATE_SALE, id, 1);
+//        rocketMQTemplate.convertAndSend(generalProperties.getUpdateSaleTopic(), id);
         return sale;
     }
 
@@ -410,7 +424,7 @@ public class CollectionService {
         }
     }
 
-    @Debounce(key = "#id", delay = 500)
+//    @Debounce(key = "#id", delay = 500)
     public void syncSale(Long id) {
         Integer sale = (Integer) redisTemplate.opsForValue().get(RedisKeys.COLLECTION_SALE + id);
         if (sale != null) {

+ 15 - 4
src/main/java/com/izouma/nineth/service/OrderService.java

@@ -40,6 +40,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.codec.EncoderException;
 import org.apache.commons.codec.net.URLCodec;
 import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.rocketmq.client.producer.SendResult;
 import org.apache.rocketmq.spring.core.RocketMQTemplate;
@@ -109,6 +110,11 @@ public class OrderService {
             throw new BusinessException("签名已过期");
         }
 
+        Integer stock = collectionService.getStock(collectionId);
+        if (stock == null || stock <= 0) {
+            throw new BusinessException("藏品已售罄", ErrorCode.SOLD_OUT);
+        }
+
         Long id = snowflakeIdWorker.nextId();
         SendResult result = rocketMQTemplate.syncSend(generalProperties.getCreateOrderTopic(),
                 new CreateOrderEvent(id, userId, collectionId, qty, addressId, userCouponId, invitor, vip), 100000);
@@ -123,15 +129,15 @@ public class OrderService {
         qty = 1;
         int stock = Optional.ofNullable(collectionService.decreaseStock(collectionId, qty))
                 .map(Math::toIntExact)
-                .orElseThrow(new BusinessException("很遗憾,藏品已售罄"));
+                .orElseThrow(new BusinessException("很遗憾,藏品已售罄", ErrorCode.SOLD_OUT));
         // 创建订单出错后需要回滚库存,所以需要try-catch
         try {
             if (stock < 0) {
-                throw new BusinessException("很遗憾,藏品已售罄");
+                throw new BusinessException("很遗憾,藏品已售罄", ErrorCode.SOLD_OUT);
             }
             Collection collection = collectionRepo.findById(collectionId).orElseThrow(new BusinessException("藏品不存在"));
             if (collection.getAssetId() != null && collection.getAssetId().equals(778359L)) {
-                throw new BusinessException("很遗憾,藏品已售罄");
+                throw new BusinessException("很遗憾,藏品已售罄", ErrorCode.SOLD_OUT);
             }
             if (collection.getAssetId() != null) {
                 Asset asset = assetRepo.findById(collection.getAssetId()).orElseThrow(new BusinessException("藏品不存在"));
@@ -196,6 +202,10 @@ public class OrderService {
                     if (user.getVipPurchase() - purchase <= 0) {
                         throw new BusinessException("vip名额已使用完毕!");
                     }
+                    // vip扣除额度
+                    if (ObjectUtils.isNotEmpty(collection.getVipQuota())) {
+                        collectionService.decreaseQuota(collectionId, 1);
+                    }
                 } else {
 //                    long count = userRepo.countAllByCollectionIdAndCollectionInvitor(collectionId, userId);
 //                    int sub = collection.getAssignment() - (int) count;
@@ -725,8 +735,9 @@ public class OrderService {
                 });
             }
             //加上积分
-            if (order.getVipPoint() > 0) {
+            if (ObjectUtils.isNotEmpty(order.getVipPoint()) && order.getVipPoint() > 0) {
                 userRepo.updateVipPoint(order.getUserId(), order.getVipPoint());
+                log.info("取消加积分用户ID:{},订单ID:{},积分:{}", order.getUserId(), order.getId(), order.getVipPoint());
             }
 
             rocketMQTemplate.syncSend(generalProperties.getUpdateStockTopic(), order.getCollectionId(), 10000);

+ 5 - 4
src/main/java/com/izouma/nineth/service/UserService.java

@@ -202,6 +202,10 @@ public class UserService {
                     if (point <= 0) {
                         long count = userRepo.countAllByCollectionIdAndCollectionInvitor(collectionId, invitor);
                         if (count >= collection.getAssignment()) {
+                            // 扣除藏品额度
+                            if (ObjectUtils.isNotEmpty(collection.getVipQuota())) {
+                                collectionService.decreaseQuota(collectionId, 1);
+                            }
                             userRepo.updateVipPoint(invitor, 1);
                             pointRecordRepo.save(PointRecord.builder()
                                     .collectionId(collectionId)
@@ -209,10 +213,7 @@ public class UserService {
                                     .type("VIP_POINT")
                                     .point(1)
                                     .build());
-                            // 扣除藏品额度
-                            if (ObjectUtils.isNotEmpty(collection.getVipQuota())) {
-                                collectionService.decreaseQuota(collectionId, 1);
-                            }
+
                         }
                     }
                 }

+ 12 - 0
src/test/java/com/izouma/nineth/service/UserServiceTest.java

@@ -185,4 +185,16 @@ public class UserServiceTest extends ApplicationTests {
                 .idNo(identityAuth.getIdNo())
                 .build());
     }
+
+    @Test
+    public void test1() {
+        List<User> users = userRepo.findAll();
+        users.forEach(user -> {
+            if (user.getVipPoint() > 1) {
+                user.setVipPoint(1);
+            } else {
+
+            }
+        });
+    }
 }