Explorar o código

预约赛事手动退款, 赛事定时核销订单

Memory_LG hai 1 mes
pai
achega
f687405939

+ 8 - 0
pom.xml

@@ -58,6 +58,14 @@
                 <scope>import</scope>
             </dependency>
 
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-data-redis</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
             <!-- 覆盖logback的依赖配置-->
             <dependency>
                 <groupId>ch.qos.logback</groupId>

+ 2 - 0
qmjszx-admin/src/main/java/beilv/Application.java

@@ -3,6 +3,7 @@ package beilv;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
 /**
  * 启动程序
@@ -10,6 +11,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
  * @author ruoyi
  */
 @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
+@EnableScheduling
 public class Application
 {
     public static void main(String[] args)

+ 14 - 0
qmjszx-admin/src/main/java/beilv/web/controller/competition/CompetitionController.java

@@ -92,6 +92,8 @@ public class CompetitionController extends BaseController {
     @PostMapping("/add")
     @ResponseBody
     public AjaxResult addSave(Competition competition) {
+
+
         return toAjax(competitionService.insertCompetition(competition));
     }
 
@@ -182,4 +184,16 @@ public class CompetitionController extends BaseController {
         return prefix + "/details";
     }
 
+    /**
+     * 针对某个购票记录进行退票处理
+     *
+     * @param orderId 购票记录id
+     * @return
+     */
+    @GetMapping("/close/{orderId}")
+    @ResponseBody
+    public AjaxResult closeStadiumById(@PathVariable("orderId") String orderId) {
+        return toAjax(stadiumService.closeStadiumById(orderId));
+    }
+
 }

+ 1 - 11
qmjszx-admin/src/main/java/beilv/web/controller/stadium/StadiumController.java

@@ -117,15 +117,5 @@ public class StadiumController extends BaseController {
     }
 
 
-    /**
-     * 针对某个购票记录进行退票处理
-     *
-     * @param orderId 购票记录id
-     * @return
-     */
-    @GetMapping("/close/{orderId}")
-    @ResponseBody
-    public AjaxResult closeStadiumById(@PathVariable("orderId") String orderId) {
-        return toAjax(stadiumService.closeStadiumById(orderId));
-    }
+
 }

+ 5 - 1
qmjszx-admin/src/main/resources/application-druid.yml

@@ -58,4 +58,8 @@ spring:
                     merge-sql: true
                 wall:
                     config:
-                        multi-statement-allow: true
+                        multi-statement-allow: true
+    redis:
+        host: 127.0.0.1
+        port: 16379
+        password: sooka123456

+ 1 - 9
qmjszx-admin/src/main/resources/templates/competition/competition.html

@@ -177,17 +177,9 @@
                 }else if(allowPublishTime <= currentTime){
                     $.modal.alertError("取消报名时间早于当前时间, 请先修改取消报名时间!")
                 }else if(allowPublishTime > currentTime){
-                    var data = { "id": id , "applyStartTime": formatApplyStartTime(allowPublishTime)};
+                    var data = { "id": id , "applyStartTime": formatApplyStartTime(allowPublishTime), "allowPublishTime": (startTime.getTime() - beforeTimeMs)/1000};
                     $.operate.submit(url, "post", "json", data);
                 }
-                /*if(allowPublishTime > currentTime){
-                    var data = { "id": id , "applyStartTime": formatApplyStartTime(allowPublishTime)};
-                    $.operate.submit(url, "post", "json", data);
-                }else if(startTime <= currentTime){
-                    $.modal.alertError("赛事开始时间早于当前时间, 请先修改赛事开始时间!")
-                }else{
-
-                }*/
             }
         });
     }

+ 2 - 5
qmjszx-admin/src/main/resources/templates/competition/details.html

@@ -83,7 +83,7 @@
                     var actions = [];
                     // if (row.competitionState === 'competiton_state_1')
                     if(row.paymentStatus === 'payment_status_have_paid'){
-                        actions.push('<a class="btn btn-success btn-xs" href="javascript:void(0)" onclick="closeStadium(\'' + row.id + '\')"><i class="fa fa-close"></i>退款</a> ')
+                        actions.push('<a class="btn btn-success btn-xs" href="javascript:void(0)" onclick="closeStadium(\'' + row.orderId + '\')"><i class="fa fa-close"></i>退款</a> ')
                     }
 
                     return actions.join('');
@@ -95,11 +95,8 @@
 
     function closeStadium(id){
         $.ajax({
-            url: prefix + "/close",
+            url: prefix + "/close/"+id,
             type: "GET",
-            data: {
-                id: id,
-            },
             success: function(res){
                 if(res.code === 0){
                     $.modal.msgSuccess("操作成功");

+ 7 - 0
qmjszx-business/pom.xml

@@ -87,6 +87,13 @@
             <version>1.1.3</version>
         </dependency>
 
+
+        <!-- 放在 pom.xml 的 <dependencies> 节点下 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+
     </dependencies>
 
 </project>

+ 1 - 0
qmjszx-business/src/main/java/beilv/competition/domain/Competition.java

@@ -141,6 +141,7 @@ public class Competition extends BaseEntity {
      */
     private String competitionImg;
 
+    private Long allowPublishTime;
     @Override
     public String toString() {
         return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)

+ 10 - 0
qmjszx-business/src/main/java/beilv/competition/domain/Constant.java

@@ -0,0 +1,10 @@
+package beilv.competition.domain;
+
+public class Constant {
+    public static final String REDIS_CHANNEL = "message_sending";
+    public static final String TASK_QUEUE = "competition:";
+    public static final String TASK_QUEUE_QUERY = "competition:*";
+
+    public Constant() {
+    }
+}

+ 29 - 0
qmjszx-business/src/main/java/beilv/competition/domain/RedisTask.java

@@ -0,0 +1,29 @@
+package beilv.competition.domain;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.Date;
+
+@Setter
+@Getter
+@AllArgsConstructor
+@NoArgsConstructor
+public class RedisTask {
+    private Integer competitionId;
+    private String competitionState;
+    private String paymentStatus;
+
+    public String toString() {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            return objectMapper.writeValueAsString(this);
+        } catch (Exception var2) {
+            var2.printStackTrace();
+            return super.toString();
+        }
+    }
+}

+ 15 - 3
qmjszx-business/src/main/java/beilv/competition/service/impl/CompetitionServiceImpl.java

@@ -3,18 +3,23 @@ package beilv.competition.service.impl;
 import beilv.common.core.text.Convert;
 import beilv.common.utils.ShiroUtils;
 import beilv.competition.domain.Competition;
+import beilv.competition.domain.RedisTask;
 import beilv.competition.mapper.CompetitionMapper;
 import beilv.competition.service.ICompetitionService;
 import beilv.competition.task.CloseReg;
 import beilv.stadium.domain.Stadium;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
 import java.util.Date;
 import java.util.List;
 import java.util.Timer;
 
+import static beilv.competition.domain.Constant.TASK_QUEUE;
+
 /**
  * 赛事发布Service业务层处理
  *
@@ -24,9 +29,12 @@ import java.util.Timer;
 @Service
 public class CompetitionServiceImpl implements ICompetitionService {
 
-    @Autowired
+    @Resource
     private CompetitionMapper competitionMapper;
 
+    @Autowired
+    private StringRedisTemplate redisTemplate;
+
     private final static String DAI_FA_BU = "competiton_state_1";
     private final static String BAO_MING_ZHONG = "competiton_state_2";
     private final static String BAO_MING_JIE_SHU = "competiton_state_3";
@@ -136,9 +144,13 @@ public class CompetitionServiceImpl implements ICompetitionService {
         competition.setPublishBy(ShiroUtils.getSysUser().getUserId().toString());
         competition.setPublishName(ShiroUtils.getSysUser().getUserName());
         competition.setCompetitionState(BAO_MING_ZHONG);
-        Timer timer = new Timer();
+//        Timer timer = new Timer();
         //new Date(competition.getApplyStartTime().getTime() - (long) (competition.getApplyBeforeTime() * 60 * 1000))
-        timer.schedule(new CloseReg(competitionMapper, competition.getId()), competition.getApplyStartTime());
+//        timer.schedule(new CloseReg(competitionMapper, competition.getId()), competition.getApplyStartTime());
+        //修改使用redis的zset存储定时任务.
+        RedisTask redisTask = new RedisTask(competition.getId(),"competiton_state_3","payment_status_verification");
+        redisTemplate.opsForZSet().add(TASK_QUEUE + redisTask.getCompetitionId(), redisTask.toString(), competition.getAllowPublishTime());
+
         return competitionMapper.publishCompetition(competition);
     }
 

+ 2 - 2
qmjszx-business/src/main/java/beilv/competition/task/CloseReg.java

@@ -20,7 +20,7 @@ public class CloseReg extends TimerTask {
 
     @Override
     public void run() {
-        Competition competition = new Competition();
+        /*Competition competition = new Competition();
         competition.setId(id);
         competition.setCompetitionState("competiton_state_3");
         this.competitionMapper.updateCompetition(competition);
@@ -30,6 +30,6 @@ public class CloseReg extends TimerTask {
         stadium.setCompetitionId(String.valueOf(id));
         stadium.setPaymentStatus("payment_status_verification");
         stadium.setVerificationTime(new Date());
-        this.competitionMapper.updateBookARace(stadium);
+        this.competitionMapper.updateBookARace(stadium);*/
     }
 }

+ 83 - 0
qmjszx-business/src/main/java/beilv/competition/task/RedisTaskChecker.java

@@ -0,0 +1,83 @@
+package beilv.competition.task;
+
+import beilv.competition.domain.Competition;
+import beilv.competition.domain.RedisTask;
+import beilv.competition.mapper.CompetitionMapper;
+import beilv.stadium.domain.Stadium;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.Set;
+
+import static beilv.competition.domain.Constant.REDIS_CHANNEL;
+import static beilv.competition.domain.Constant.TASK_QUEUE_QUERY;
+
+/**
+ * 轮询Redis有序集合, 处理到期的任务.
+ * 将到期的任务发布, 由监听者接收
+ * 同时移除其他相同eventId的任务
+ */
+
+@Component
+public class RedisTaskChecker {
+
+    @Autowired
+    private StringRedisTemplate stringRedisTemplate;
+
+    @Resource
+    private CompetitionMapper competitionMapper;
+
+    /**
+     * 检测到期任务, 并将消息发布
+     */
+    @Scheduled(fixedRate = 1000)
+    public void checkTasks() {
+        long currentTime = System.currentTimeMillis() / 1000;
+
+        // 获取所有有序集合的键
+        Set<String> keys = stringRedisTemplate.keys(TASK_QUEUE_QUERY);
+        if (keys != null && !keys.isEmpty()) {
+            for (String key : keys) {
+                // 获取当前时间之前的所有任务
+                Set<String> tasks = stringRedisTemplate.opsForZSet().rangeByScore(key, 0, currentTime);
+                if (tasks != null && !tasks.isEmpty()) {
+                    for (String taskJson : tasks) {
+                        try {
+//                            System.out.println("taskJson => " + taskJson);
+
+                            //获取任务信息
+                            ObjectMapper objectMapper = new ObjectMapper();
+                            RedisTask task = objectMapper.readValue(taskJson, RedisTask.class);
+
+                            Competition competition = new Competition();
+                            competition.setId(task.getCompetitionId());
+                            competition.setCompetitionState(task.getCompetitionState());
+                            competitionMapper.updateCompetition(competition);
+
+                            //核验当前赛事下已支付的订单
+                            Stadium stadium = new Stadium();
+                            stadium.setCompetitionId(String.valueOf(task.getCompetitionId()));
+                            stadium.setPaymentStatus(task.getPaymentStatus());
+                            stadium.setVerificationTime(new Date());
+                            competitionMapper.updateBookARace(stadium);
+
+
+                            // 移除当前已发布的任务
+                            stringRedisTemplate.opsForZSet().remove(key, taskJson);
+                            System.out.println("Removed task: " + taskJson);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+