Drew 6 роки тому
батько
коміт
25df121802
21 змінених файлів з 155 додано та 29 видалено
  1. 5 0
      src/main/java/com/izouma/ticketExchange/Application.java
  2. 2 1
      src/main/java/com/izouma/ticketExchange/domain/AuditedEntity.java
  3. 2 1
      src/main/java/com/izouma/ticketExchange/domain/BaseEntity.java
  4. 2 2
      src/main/java/com/izouma/ticketExchange/domain/Order.java
  5. 6 0
      src/main/java/com/izouma/ticketExchange/domain/OrderDetail.java
  6. 1 0
      src/main/java/com/izouma/ticketExchange/domain/Schedule.java
  7. 4 2
      src/main/java/com/izouma/ticketExchange/dto/LockSeatRequest.java
  8. 5 1
      src/main/java/com/izouma/ticketExchange/enums/OrderStatus.java
  9. 7 0
      src/main/java/com/izouma/ticketExchange/repo/OrderDetailRepo.java
  10. 7 0
      src/main/java/com/izouma/ticketExchange/repo/OrderRepo.java
  11. 2 1
      src/main/java/com/izouma/ticketExchange/repo/ScheduleRepo.java
  12. 1 3
      src/main/java/com/izouma/ticketExchange/repo/ShowRepo.java
  13. 5 1
      src/main/java/com/izouma/ticketExchange/service/CinemaService.java
  14. 57 0
      src/main/java/com/izouma/ticketExchange/service/OrderService.java
  15. 19 13
      src/main/java/com/izouma/ticketExchange/service/ScheduleService.java
  16. 8 2
      src/main/java/com/izouma/ticketExchange/service/SeatService.java
  17. 5 1
      src/main/java/com/izouma/ticketExchange/service/TppService.java
  18. 9 0
      src/main/java/com/izouma/ticketExchange/web/OrderController.java
  19. 1 1
      src/main/java/com/izouma/ticketExchange/web/SeatController.java
  20. 2 0
      src/main/resources/application.yaml
  21. 5 0
      src/test/java/com/izouma/ticketExchange/service/TppServiceTest.java

+ 5 - 0
src/main/java/com/izouma/ticketExchange/Application.java

@@ -4,12 +4,17 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
 import springfox.documentation.swagger2.annotations.EnableSwagger2;
 
 @SpringBootApplication
 @EnableJpaAuditing
 @EnableSwagger2
 @EnableCaching
+@EnableRedisRepositories
+@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
 public class Application {
 
     public static void main(String[] args) {

+ 2 - 1
src/main/java/com/izouma/ticketExchange/domain/AuditedEntity.java

@@ -11,6 +11,7 @@ import org.springframework.data.annotation.LastModifiedDate;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 
 import javax.persistence.*;
+import java.io.Serializable;
 import java.time.LocalDateTime;
 
 @MappedSuperclass
@@ -18,7 +19,7 @@ import java.time.LocalDateTime;
 @EntityListeners(AuditingEntityListener.class)
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @JsonIgnoreProperties(ignoreUnknown = true)
-public abstract class AuditedEntity {
+public abstract class AuditedEntity implements Serializable {
 
     @JsonIgnore
     @CreatedBy

+ 2 - 1
src/main/java/com/izouma/ticketExchange/domain/BaseEntity.java

@@ -11,6 +11,7 @@ import org.springframework.data.annotation.LastModifiedDate;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 
 import javax.persistence.*;
+import java.io.Serializable;
 import java.time.LocalDateTime;
 
 @MappedSuperclass
@@ -18,7 +19,7 @@ import java.time.LocalDateTime;
 @EntityListeners(AuditingEntityListener.class)
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @JsonIgnoreProperties(ignoreUnknown = true)
-public abstract class BaseEntity {
+public abstract class BaseEntity implements Serializable {
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     private Long id;

+ 2 - 2
src/main/java/com/izouma/ticketExchange/domain/Order.java

@@ -49,8 +49,8 @@ public class Order extends BaseEntity {
     @ApiModelProperty(value = "取票码", name = "ticketContents")
     private String ticketContents;
 
-    @ApiModelProperty(value = "淘票票订单ID", name = "tbOrderId")
-    private String tbOrderId;
+    @ApiModelProperty(value = "第三方订单ID", name = "thirdOrderId")
+    private String thirdOrderId;
 
     private String phone;
 

+ 6 - 0
src/main/java/com/izouma/ticketExchange/domain/OrderDetail.java

@@ -2,7 +2,10 @@ package com.izouma.ticketExchange.domain;
 
 import com.izouma.ticketExchange.enums.OrderStatus;
 import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
@@ -12,6 +15,9 @@ import java.math.BigDecimal;
 
 @Data
 @Entity
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
 @ApiModel(value = "订单详情", description = "订单详情")
 public class OrderDetail extends BaseEntity {
 

+ 1 - 0
src/main/java/com/izouma/ticketExchange/domain/Schedule.java

@@ -8,6 +8,7 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 import org.hibernate.annotations.NotFound;
 import org.hibernate.annotations.NotFoundAction;
+import org.springframework.data.redis.core.RedisHash;
 
 import javax.persistence.*;
 import java.math.BigDecimal;

+ 4 - 2
src/main/java/com/izouma/ticketExchange/dto/LockSeatRequest.java

@@ -1,16 +1,18 @@
 package com.izouma.ticketExchange.dto;
 
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 import lombok.NonNull;
 
 import java.util.List;
 
 @Data
+@NoArgsConstructor
+@AllArgsConstructor
 public class LockSeatRequest {
     private Long         couponId;
     private Long         scheduleId;
-    @NonNull
     private List<String> seatIds;
-    @NonNull
     private List<String> seatNames;
 }

+ 5 - 1
src/main/java/com/izouma/ticketExchange/enums/OrderStatus.java

@@ -1,7 +1,11 @@
 package com.izouma.ticketExchange.enums;
 
 public enum OrderStatus {
-    ;
+    NOT_PAID("待支付"),
+    ISSUING("出票中"),
+    ISSUE_SUCCESS("出票成功"),
+    ISSUE_FAIL("出票失败"),
+    CANCELLED("已取消");
 
     private final String description;
 

+ 7 - 0
src/main/java/com/izouma/ticketExchange/repo/OrderDetailRepo.java

@@ -0,0 +1,7 @@
+package com.izouma.ticketExchange.repo;
+
+import com.izouma.ticketExchange.domain.OrderDetail;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface OrderDetailRepo extends JpaRepository<OrderDetail, Long> {
+}

+ 7 - 0
src/main/java/com/izouma/ticketExchange/repo/OrderRepo.java

@@ -0,0 +1,7 @@
+package com.izouma.ticketExchange.repo;
+
+import com.izouma.ticketExchange.domain.Order;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface OrderRepo extends JpaRepository<Order, Long> {
+}

+ 2 - 1
src/main/java/com/izouma/ticketExchange/repo/ScheduleRepo.java

@@ -4,11 +4,12 @@ import com.izouma.ticketExchange.domain.Schedule;
 import com.izouma.ticketExchange.domain.Show;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.CrudRepository;
 
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.List;
 
-public interface ScheduleRepo extends JpaRepository<Schedule, Long> {
+public interface ScheduleRepo extends CrudRepository<Schedule, Long> {
     List<Schedule> findByCinemaIdAndShowIdAndShowTimeAfter(Long cinemaId, Long showId, LocalDateTime date);
 }

+ 1 - 3
src/main/java/com/izouma/ticketExchange/repo/ShowRepo.java

@@ -9,7 +9,5 @@ import java.time.LocalDate;
 import java.util.List;
 
 public interface ShowRepo extends JpaRepository<Show, Long> {
-    @Query("select show from Schedule schedule join com.izouma.ticketExchange.domain.Show show on schedule.showId = show.id " +
-            "where schedule.cinemaId = ?1 and schedule.showDate >= ?2 group by show.id")
-    List<Show> getCinemaShows(Long cinemaId, LocalDate date);
+    List<Show> findByIdIn(List<Long> ids);
 }

+ 5 - 1
src/main/java/com/izouma/ticketExchange/service/CinemaService.java

@@ -19,10 +19,13 @@ import org.springframework.stereotype.Service;
 
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 @Service
 @AllArgsConstructor
@@ -31,6 +34,7 @@ public class CinemaService {
     private CouponInfoRepo couponInfoRepo;
     private ScheduleRepo   scheduleRepo;
     private ShowRepo       showRepo;
+    private TppService     tppService;
 
     public Page<Cinema> getByCity(Long cityId, Long couponId, String regionName, Double lat, Double lng, Pageable pageable) {
         CouponInfo couponInfo = couponInfoRepo.findById(couponId).orElseThrow(new BusinessException("无记录"));
@@ -66,7 +70,7 @@ public class CinemaService {
 
     public Map getCinemaShows(Long cinemaId, Long couponId, Long showId) {
         Cinema cinema = cinemaRepo.findById(cinemaId).orElseThrow(new BusinessException("无记录"));
-        List<Show> shows = showRepo.getCinemaShows(cinemaId, LocalDate.now());
+        List<Show> shows = showRepo.findByIdIn(new ArrayList<>(tppService.getSchedules(cinemaId).stream().collect(Collectors.groupingBy(Schedule::getShowId)).keySet()));
         Map<String, Object> map = new HashMap<>();
         map.put("cinema", cinema);
         map.put("shows", shows);

+ 57 - 0
src/main/java/com/izouma/ticketExchange/service/OrderService.java

@@ -0,0 +1,57 @@
+package com.izouma.ticketExchange.service;
+
+import com.izouma.ticketExchange.domain.*;
+import com.izouma.ticketExchange.enums.OrderStatus;
+import com.izouma.ticketExchange.exception.BusinessException;
+import com.izouma.ticketExchange.repo.*;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Service
+@AllArgsConstructor
+public class OrderService {
+    private OrderRepo         orderRepo;
+    private OrderDetailRepo   orderDetailRepo;
+    private ScheduleRepo      scheduleRepo;
+    private CouponReceiveRepo couponReceiveRepo;
+    private TppService        tppService;
+
+    public void createOrder(Long userId, String applyKey, Long couponId, Long scheduleId, List<String> seats) {
+        Schedule schedule = scheduleRepo.findById(scheduleId).orElseThrow(new BusinessException("该场次不存在"));
+        List<CouponReceive> couponReceives = couponReceiveRepo.findAllByUserIdAndCouponIdAndUsedFalse(userId, couponId);
+        if (couponReceives.size() < seats.size()) {
+            throw new BusinessException("优惠券数量不足");
+        }
+        BigDecimal totalFee = schedule.getPrice().multiply(BigDecimal.valueOf(seats.size()));
+        Order order = Order.builder()
+                           .userId(userId)
+                           .couponId(couponId)
+                           .scheduleId(scheduleId)
+                           .cinemaId(schedule.getCinemaId())
+                           .showId(schedule.getShowId())
+                           .hallName(schedule.getHallName())
+                           .totalFee(totalFee)
+                           .discount(totalFee)
+                           .actualPaid(BigDecimal.ZERO)
+                           .status(OrderStatus.NOT_PAID)
+                           .applyKey(applyKey)
+                           .build();
+        orderRepo.save(order);
+        for (int i = 0; i < seats.size(); i++) {
+            OrderDetail detail = OrderDetail.builder()
+                                            .userId(userId)
+                                            .orderId(order.getId())
+                                            .totalFee(schedule.getPrice())
+                                            .discount(schedule.getPrice())
+                                            .actualPaid(BigDecimal.ZERO)
+                                            .seatName(seats.get(i))
+                                            .couponReceiveId(couponReceives.get(i).getId())
+                                            .status(OrderStatus.NOT_PAID)
+                                            .build();
+            orderDetailRepo.save(detail);
+        }
+    }
+}

+ 19 - 13
src/main/java/com/izouma/ticketExchange/service/ScheduleService.java

@@ -3,6 +3,7 @@ package com.izouma.ticketExchange.service;
 import com.izouma.ticketExchange.domain.Schedule;
 import com.izouma.ticketExchange.repo.ScheduleRepo;
 import lombok.AllArgsConstructor;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDate;
@@ -21,14 +22,26 @@ import static java.time.temporal.ChronoUnit.DAYS;
 @AllArgsConstructor
 public class ScheduleService {
     private ScheduleRepo scheduleRepo;
+    private TppService   tppService;
 
     public List cinemaSchedule(Long cinemaId, Long showId) {
-        List<Schedule> scheduleList = scheduleRepo.findByCinemaIdAndShowIdAndShowTimeAfter(cinemaId, showId, LocalDateTime.now());
+        List<Schedule> scheduleList = tppService.getSchedules(cinemaId).stream()
+                                                .filter(schedule -> schedule.getShowId().equals(showId)
+                                                        && schedule.getShowTime().isAfter(LocalDateTime.now()))
+                                                .collect(Collectors.toList());
+//        List<Schedule> scheduleList = scheduleRepo.findByCinemaIdAndShowIdAndShowTimeAfter(cinemaId, showId, LocalDateTime.now());
         return scheduleList.stream()
                            .sorted(Comparator.comparing(Schedule::getShowDate))
-                           .collect(Collectors.groupingBy(schedule -> {
-                               String date = schedule.getShowDate().format(DateTimeFormatter.ofPattern("MM-dd"));
-                               switch ((int) DAYS.between(LocalDate.now(), schedule.getShowDate())) {
+                           .collect(Collectors.groupingBy(Schedule::getShowDate,
+                                   Collectors.mapping(location -> location, Collectors.toList())))
+                           .entrySet()
+                           .stream()
+                           .sorted(Comparator.comparing(Map.Entry::getKey))
+                           .map((Function<Map.Entry<LocalDate, List<Schedule>>, Map>) stringListEntry -> {
+                               Map<String, Object> map = new HashMap<>();
+                               stringListEntry.getValue().sort(Comparator.comparing(Schedule::getShowTime));
+                               String date = stringListEntry.getKey().format(DateTimeFormatter.ofPattern("MM-dd"));
+                               switch ((int) DAYS.between(LocalDate.now(), stringListEntry.getKey())) {
                                    case 0:
                                        date = "今天" + date;
                                        break;
@@ -40,16 +53,9 @@ public class ScheduleService {
                                        break;
                                    default:
                                        String[] weekDays = {"周一", "周二", "周三", "周四", "周五", "周六", "周日"};
-                                       date = weekDays[schedule.getShowDate().getDayOfWeek().getValue()] + date;
+                                       date = weekDays[stringListEntry.getKey().getDayOfWeek().getValue() - 1] + date;
                                }
-                               return date;
-                           }, Collectors.mapping(location -> location, Collectors.toList())))
-                           .entrySet()
-                           .stream()
-                           .map((Function<Map.Entry<String, List<Schedule>>, Map>) stringListEntry -> {
-                               Map<String, Object> map = new HashMap<>();
-                               stringListEntry.getValue().sort(Comparator.comparing(Schedule::getShowTime));
-                               map.put("showDate", stringListEntry.getKey());
+                               map.put("showDate", date);
                                map.put("schedules", stringListEntry.getValue());
                                return map;
                            })

+ 8 - 2
src/main/java/com/izouma/ticketExchange/service/SeatService.java

@@ -1,5 +1,6 @@
 package com.izouma.ticketExchange.service;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.izouma.ticketExchange.domain.*;
 import com.izouma.ticketExchange.enums.CouponStatus;
 import com.izouma.ticketExchange.exception.BusinessException;
@@ -8,6 +9,7 @@ import com.taobao.api.ApiException;
 import com.taobao.api.response.FilmDataThirdPartyLockSeatResponse;
 import com.taobao.api.response.FilmDataThirdPartySeatMapResponse;
 import lombok.AllArgsConstructor;
+import org.apache.commons.beanutils.BeanUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 
@@ -63,9 +65,13 @@ public class SeatService {
         List<CouponReceive> couponReceives = couponReceiveRepo.findAllByUserIdAndCouponIdAndUsedFalse(userId, couponId);
         int usableCount = couponReceives.size();
         if (usableCount < seatIds.size()) {
-            throw new BusinessException("最多可选" + usableCount + "个");
+            throw new BusinessException("最多只能选" + usableCount + "个座位");
         }
-
+        FilmDataThirdPartyLockSeatResponse.SeatLocked seatLocked = tppService.lockSeat(scheduleId, StringUtils.join(seatIds, "|"), StringUtils.join(seatNames, "|"), couponReceives.get(0).getPhone(), userId);
+        ObjectMapper objectMapper = new ObjectMapper();
+        Map<String, Object> map = objectMapper.convertValue(seatLocked, Map.class);
+        map.put("price", 0);
+        map.put("seatNames", seatNames);
         return tppService.lockSeat(scheduleId, StringUtils.join(seatIds, "|"), StringUtils.join(seatNames, "|"), couponReceives.get(0).getPhone(), userId);
     }
 

+ 5 - 1
src/main/java/com/izouma/ticketExchange/service/TppService.java

@@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -168,6 +169,7 @@ public class TppService {
         throw new BusinessException("获取影院失败");
     }
 
+    @Cacheable("tppGetSchedules")
     public List<Schedule> getSchedules(Long cinemaId) {
         FilmDataThirdPartySchedulesGetRequest req = new FilmDataThirdPartySchedulesGetRequest();
         req.setUserId(tbUserId);
@@ -197,7 +199,9 @@ public class TppService {
                                              .isExpired(s.getIsExpired())
                                              .build());
                 });
-                scheduleRepo.saveAll(scheduleList);
+                new Thread(() -> {
+                    scheduleRepo.saveAll(scheduleList);
+                }).start();
                 return scheduleList;
             }
             log.error("获取排片失败\n\t{}", rsp.getBody());

+ 9 - 0
src/main/java/com/izouma/ticketExchange/web/OrderController.java

@@ -0,0 +1,9 @@
+package com.izouma.ticketExchange.web;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/order")
+public class OrderController {
+}

+ 1 - 1
src/main/java/com/izouma/ticketExchange/web/SeatController.java

@@ -26,7 +26,7 @@ public class SeatController {
         return seatService.seatMap(scheduleId, couponId, SecurityUtils.getAuthenticatedUser().getId());
     }
 
-    @GetMapping("/lock")
+    @PostMapping("/lock")
     public FilmDataThirdPartyLockSeatResponse.SeatLocked lockSeat(@RequestBody LockSeatRequest request) {
         return seatService.lockSeat(request.getCouponId(), request.getScheduleId(), request.getSeatIds(), request.getSeatNames(), SecurityUtils.getAuthenticatedUser().getId());
     }

+ 2 - 0
src/main/resources/application.yaml

@@ -6,6 +6,8 @@ server:
         enabled: true
         mime-types: application/json,application/xml,text/html,text/xml,text/plain
 spring:
+    main:
+        allow-bean-definition-overriding: true
     profiles:
         active: dev
     datasource:

+ 5 - 0
src/test/java/com/izouma/ticketExchange/service/TppServiceTest.java

@@ -38,4 +38,9 @@ public class TppServiceTest extends ApplicationTests {
     public void getSeats() throws ApiException {
         tppService.getSeatMap(729164896L);
     }
+
+    @Test
+    public void unlock() {
+        tppService.unlockSeat("85_44_729543745_[0300000200801209, 0300000200901210]", 44L);
+    }
 }