Browse Source

定时上架

wangqifan 4 years ago
parent
commit
a9026e1dd9

+ 11 - 0
src/main/java/com/izouma/nineth/repo/AuctionActivityRepo.java

@@ -2,6 +2,7 @@ package com.izouma.nineth.repo;
 
 import com.izouma.nineth.domain.AuctionActivity;
 import com.izouma.nineth.enums.AuctionStatus;
+import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Modifying;
@@ -27,4 +28,14 @@ public interface AuctionActivityRepo extends JpaRepository<AuctionActivity, Long
     @Modifying
     @Transactional
     void addLike(Long id, int num);
+
+    @Transactional
+    @Modifying
+    @Query("update AuctionActivity c set  c.status = ?2 where  c.id = ?1")
+    void scheduleOnShelf(Long id, AuctionStatus status);
+
+    @Transactional
+    @Modifying
+    @Query("update AuctionActivity c set  c.status = ?2 where  c.id = ?1")
+    void scheduleOffShelf(Long id, AuctionStatus status);
 }

+ 62 - 2
src/main/java/com/izouma/nineth/service/AuctionActivityService.java

@@ -4,6 +4,7 @@ import com.izouma.nineth.annotations.Debounce;
 import com.izouma.nineth.config.RedisKeys;
 import com.izouma.nineth.domain.Asset;
 import com.izouma.nineth.domain.AuctionActivity;
+import com.izouma.nineth.domain.Collection;
 import com.izouma.nineth.domain.User;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.dto.auction.AuctionInputDTO;
@@ -22,13 +23,19 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.data.domain.Page;
 import org.springframework.data.redis.core.BoundValueOperations;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.scheduling.TaskScheduler;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.web.bind.annotation.RequestBody;
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Optional;
+import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
 @Slf4j
@@ -42,6 +49,9 @@ public class AuctionActivityService {
     private final PasswordEncoder               passwordEncoder;
     private final RedisTemplate<String, Object> redisTemplate;
     private final CacheService                  cacheService;
+    private final TaskScheduler                 taskScheduler;
+
+    private final Map<Long, ScheduledFuture<?>> tasks = new HashMap<>();
 
     public Page<AuctionActivity> all(PageQuery pageQuery) {
         return auctionActivityRepo
@@ -103,8 +113,13 @@ public class AuctionActivityService {
             asset.setStatus(AssetStatus.AUCTIONING);
             assetRepo.save(asset);
         }
-        record.setStatus(AuctionStatus.NOTSTARTED);
-        return auctionActivityRepo.save(record);
+        AuctionActivity saved = auctionActivityRepo.save(record);
+        if (saved.getStatus().equals(AuctionStatus.NOTSTARTED)) {
+            onShelfTask(saved);
+        } else if (saved.getStatus().equals(AuctionStatus.ONGOING)) {
+            offShelfTask(saved);
+        }
+        return saved;
     }
 
     public synchronized String changeStatus(Long id, AuctionStatus status) {
@@ -128,4 +143,49 @@ public class AuctionActivityService {
             cacheService.clearAuction(id);
         }
     }
+
+    private void onShelfTask(AuctionActivity record) {
+        ScheduledFuture<?> task = tasks.get(record.getId());
+        if (task != null) {
+            if (!task.cancel(true)) {
+                return;
+            }
+        }
+        if (record.getStatus().equals(AuctionStatus.NOTSTARTED)) {
+            if (record.getStartTime().minusSeconds(2).isAfter(LocalDateTime.now())) {
+                Date date = Date.from(record.getStartTime().atZone(ZoneId.systemDefault()).toInstant());
+                ScheduledFuture<?> future = taskScheduler.schedule(() -> {
+                    auctionActivityRepo.scheduleOnShelf(record.getId(), AuctionStatus.ONGOING);
+                    tasks.remove(record.getId());
+                    offShelfTask(record);
+                }, date);
+                tasks.put(record.getId(), future);
+            } else {
+                auctionActivityRepo.scheduleOnShelf(record.getId(), AuctionStatus.ONGOING);
+            }
+        }
+    }
+
+    private void offShelfTask(AuctionActivity record) {
+        ScheduledFuture<?> task = tasks.get(record.getId());
+        if (task != null) {
+            if (!task.cancel(true)) {
+                return;
+            }
+        }
+        AuctionActivity nowRecord = auctionActivityRepo.findById(record.getId())
+                .orElseThrow(new BusinessException("无数据"));
+        if (nowRecord.getStatus().equals(AuctionStatus.ONGOING)) {
+            if (nowRecord.getEndTime().minusSeconds(2).isAfter(LocalDateTime.now())) {
+                Date date = Date.from(record.getStartTime().atZone(ZoneId.systemDefault()).toInstant());
+                ScheduledFuture<?> future = taskScheduler.schedule(() -> {
+                    auctionActivityRepo.scheduleOffShelf(nowRecord.getId(), AuctionStatus.PURCHASED);
+                    tasks.remove(record.getId());
+                }, date);
+                tasks.put(record.getId(), future);
+            } else {
+                auctionActivityRepo.scheduleOffShelf(nowRecord.getId(), AuctionStatus.PURCHASED);
+            }
+        }
+    }
 }