Vacity 7 years ago
parent
commit
d814532676
53 changed files with 1622 additions and 338 deletions
  1. 18 0
      src/main/java/com/example/cinema/bl/ActivityService.java
  2. 6 0
      src/main/java/com/example/cinema/bl/MovieService.java
  3. 7 0
      src/main/java/com/example/cinema/bl/ScheduleService.java
  4. 5 3
      src/main/java/com/example/cinema/bl/TicketService.java
  5. 58 0
      src/main/java/com/example/cinema/blImpl/ActivityServiceImpl.java
  6. 10 0
      src/main/java/com/example/cinema/blImpl/MovieServiceImpl.java
  7. 52 17
      src/main/java/com/example/cinema/blImpl/ScheduleServiceImpl.java
  8. 3 19
      src/main/java/com/example/cinema/blImpl/StatisticsServiceImpl.java
  9. 90 43
      src/main/java/com/example/cinema/blImpl/TicketServiceImpl.java
  10. 2 2
      src/main/java/com/example/cinema/blImpl/VIPServiceImpl.java
  11. 30 0
      src/main/java/com/example/cinema/controller/ActivityController.java
  12. 6 2
      src/main/java/com/example/cinema/controller/CouponController.java
  13. 8 0
      src/main/java/com/example/cinema/controller/MovieController.java
  14. 6 1
      src/main/java/com/example/cinema/controller/ScheduleController.java
  15. 5 3
      src/main/java/com/example/cinema/controller/TicketController.java
  16. 33 0
      src/main/java/com/example/cinema/data/ActivityMapper.java
  17. 106 0
      src/main/java/com/example/cinema/data/ActivityMapper.xml
  18. 2 0
      src/main/java/com/example/cinema/data/CouponMapper.java
  19. 7 2
      src/main/java/com/example/cinema/data/CouponMapper.xml
  20. 6 0
      src/main/java/com/example/cinema/data/MovieMapper.java
  21. 14 1
      src/main/java/com/example/cinema/data/MovieMapper.xml
  22. 8 0
      src/main/java/com/example/cinema/data/ScheduleMapper.java
  23. 9 0
      src/main/java/com/example/cinema/data/ScheduleMapper.xml
  24. 2 2
      src/main/java/com/example/cinema/data/StatisticsMapper.java
  25. 9 0
      src/main/java/com/example/cinema/data/StatisticsMapper.xml
  26. 2 0
      src/main/java/com/example/cinema/data/TicketMapper.java
  27. 11 1
      src/main/java/com/example/cinema/data/TicketMapper.xml
  28. 88 0
      src/main/java/com/example/cinema/po/Activity.java
  29. 26 0
      src/main/java/com/example/cinema/po/Ticket.java
  30. 1 1
      src/main/java/com/example/cinema/po/VIPCard.java
  31. 87 0
      src/main/java/com/example/cinema/vo/ActivityForm.java
  32. 99 0
      src/main/java/com/example/cinema/vo/ActivityVO.java
  33. 2 2
      src/main/java/com/example/cinema/vo/MovieScheduleTimeVO.java
  34. 0 35
      src/main/java/com/example/cinema/vo/ScheduleRateVO.java
  35. 31 0
      src/main/java/com/example/cinema/vo/ScheduleWithSeatVO.java
  36. 3 21
      src/main/java/com/example/cinema/vo/SeatForm.java
  37. 10 22
      src/main/java/com/example/cinema/vo/TicketForm.java
  38. 41 0
      src/main/java/com/example/cinema/vo/TicketWithCouponVO.java
  39. 84 0
      src/main/java/com/example/cinema/vo/TicketWithScheduleVO.java
  40. 9 0
      src/main/resources/static/css/cinemaHall.css
  41. 10 3
      src/main/resources/static/css/userMember.css
  42. 71 9
      src/main/resources/static/css/userMovieBuy.css
  43. BIN
      src/main/resources/static/images/success.png
  44. 1 0
      src/main/resources/static/js/movieDetail.js
  45. 161 0
      src/main/resources/static/js/userMember.js
  46. 100 30
      src/main/resources/static/js/userMovieBuy.js
  47. 61 0
      src/main/resources/static/js/userMovieDetail.js
  48. 25 68
      src/main/resources/templates/userMember.html
  49. 136 16
      src/main/resources/templates/userMovieBuy.html
  50. 23 30
      src/main/resources/templates/userMovieDetail.html
  51. 7 0
      src/test/java/com/example/cinema/bl/ScheduleServiceImplTest.java
  52. 26 0
      src/test/java/com/example/cinema/blImpl/ScheduleServiceImplTest.java
  53. 5 5
      src/test/java/com/example/cinema/blImpl/StatisticsServiceImplTest.java

+ 18 - 0
src/main/java/com/example/cinema/bl/ActivityService.java

@@ -0,0 +1,18 @@
+package com.example.cinema.bl;
+
+import com.example.cinema.vo.ActivityForm;
+import com.example.cinema.vo.ResponseVO;
+
+/**
+ * Created by liying on 2019/4/20.
+ */
+public interface ActivityService {
+    
+    ResponseVO publishActivity(ActivityForm activityForm);
+
+    ResponseVO getActivities();
+
+
+
+
+}

+ 6 - 0
src/main/java/com/example/cinema/bl/MovieService.java

@@ -30,6 +30,12 @@ public interface MovieService {
      */
     ResponseVO searchAllMovie();
 
+    /**
+     * 搜索全部电影(不包括已经下架的)
+     * @return
+     */
+    ResponseVO searchOtherMoviesExcludeOff();
+
     /**
      * 想看电影
      * @param userId

+ 7 - 0
src/main/java/com/example/cinema/bl/ScheduleService.java

@@ -61,4 +61,11 @@ public interface ScheduleService {
      * @return
      */
     ResponseVO getScheduleView();
+
+    /**
+     * 观众看到的排片信息
+     * @param movieId
+     * @return
+     */
+    ResponseVO searchAudienceSchedule(int movieId);
 }

+ 5 - 3
src/main/java/com/example/cinema/bl/TicketService.java

@@ -4,6 +4,8 @@ import com.example.cinema.po.Ticket;
 import com.example.cinema.vo.ResponseVO;
 import com.example.cinema.vo.TicketForm;
 
+import java.util.List;
+
 
 /**
  * Created by liying on 2019/4/16.
@@ -11,15 +13,15 @@ import com.example.cinema.vo.TicketForm;
 public interface TicketService {
     ResponseVO addTicket(TicketForm ticketForm);
 
-    ResponseVO completeTicket(int id,int couponId);
+    ResponseVO completeTicket(List<Integer> id, int couponId);
 
     ResponseVO getBySchedule(int scheduleId);
 
     ResponseVO getTicketByUser(int userId);
 
-    ResponseVO completeByVIPCard(int ticketId,int couponId);
+    ResponseVO completeByVIPCard(List<Integer> id,int couponId);
 
-    ResponseVO cancelTicket(int ticketId);
+    ResponseVO cancelTicket(List<Integer> id);
 
 
 }

+ 58 - 0
src/main/java/com/example/cinema/blImpl/ActivityServiceImpl.java

@@ -0,0 +1,58 @@
+package com.example.cinema.blImpl;
+
+import com.example.cinema.bl.ActivityService;
+import com.example.cinema.bl.CouponService;
+import com.example.cinema.data.ActivityMapper;
+import com.example.cinema.po.Activity;
+import com.example.cinema.po.Coupon;
+import com.example.cinema.vo.ActivityForm;
+import com.example.cinema.vo.ResponseVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * Created by liying on 2019/4/20.
+ */
+@Service
+public class ActivityServiceImpl implements ActivityService {
+
+    @Autowired
+    ActivityMapper activityMapper;
+    @Autowired
+    CouponService couponService;
+
+    @Override
+    @Transactional
+    public ResponseVO publishActivity(ActivityForm activityForm) {
+        try {
+            ResponseVO vo = couponService.addCoupon(activityForm.getCouponForm());
+            Coupon coupon = (Coupon) vo.getContent();
+            Activity activity = new Activity();
+            activity.setName(activityForm.getName());
+            activity.setDescription(activityForm.getName());
+            activity.setStartTime(activityForm.getStartTime());
+            activity.setEndTime(activityForm.getEndTime());
+            activity.setCouponId(coupon.getId());
+            activityMapper.insertActivity(activity);
+            if(activityForm.getMovieList()!=null){
+                activityMapper.insertActivityAndMovie(activity.getId(), activityForm.getMovieList());
+            }
+            return ResponseVO.buildSuccess(activityMapper.selectById(activity.getId()));
+        } catch (Exception e) {
+            e.printStackTrace();
+            return ResponseVO.buildFailure("失败");
+        }
+    }
+
+    @Override
+    public ResponseVO getActivities() {
+        try {
+            return ResponseVO.buildSuccess(activityMapper.selectActivities());
+        } catch (Exception e) {
+            e.printStackTrace();
+            return ResponseVO.buildFailure("失败");
+        }
+    }
+
+}

+ 10 - 0
src/main/java/com/example/cinema/blImpl/MovieServiceImpl.java

@@ -74,6 +74,16 @@ public class MovieServiceImpl implements MovieService {
         }
     }
 
+    @Override
+    public ResponseVO searchOtherMoviesExcludeOff() {
+        try {
+            return ResponseVO.buildSuccess(movieMapper.selectOtherMoviesExcludeOff());
+        } catch (Exception e) {
+            e.printStackTrace();
+            return ResponseVO.buildFailure("失败");
+        }
+    }
+
     @Override
     public ResponseVO likeMovie(int userId, int movieId) {
 

+ 52 - 17
src/main/java/com/example/cinema/blImpl/ScheduleServiceImpl.java

@@ -91,6 +91,36 @@ public class ScheduleServiceImpl implements ScheduleService {
         }
     }
 
+    @Override
+    public ResponseVO searchAudienceSchedule(int movieId) {
+        try{
+            //根据view中设置的排片可见限制
+            int days = scheduleMapper.selectView();
+            List<ScheduleItem> scheduleItems = scheduleMapper.selectScheduleByMovieId(movieId);
+
+            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+            Date today = simpleDateFormat.parse(simpleDateFormat.format(new Date()));
+            Date endDate = getNumDayAfterDate(today, days);
+
+            List<ScheduleItem> result = new ArrayList<>();
+            for(ScheduleItem s : scheduleItems){
+                if(s.getStartTime().before(endDate) && s.getStartTime().after(new Date())){
+                    result.add(s);
+                }
+            }
+            int interval = 1;
+            if(result.size() > 0){
+                interval = (int)((result.get(result.size() - 1).getStartTime().getTime() - today.getTime()) / (1000 * 3600 * 24)) + 1;
+            }
+
+            return ResponseVO.buildSuccess(getScheduleVOList(interval, today, result));
+
+        }catch (Exception e){
+            e.printStackTrace();
+            return ResponseVO.buildFailure("失败");
+        }
+    }
+
     @Override
     public ResponseVO searchScheduleSevenDays(int hallId, Date startDate) {
         try {
@@ -101,23 +131,8 @@ public class ScheduleServiceImpl implements ScheduleService {
 
             // 按照日期整理ScheduleItem
             List<ScheduleItem> scheduleItemList = scheduleMapper.selectSchedule(hallId, startDate, endDate);
-            List<ScheduleVO> scheduleVOList = new ArrayList<>();
-
-            for(int i = 0; i < 7; i++){
-                Date date = getNumDayAfterDate(startDate, i);
-                ScheduleVO scheduleVO = new ScheduleVO();
-                scheduleVO.setDate(date);
-                List<ScheduleItem> scheduleItems = new ArrayList<>();
-                for(ScheduleItem scheduleItem : scheduleItemList){
-                    Date startTime = simpleDateFormat.parse(simpleDateFormat.format(scheduleItem.getStartTime()));
-                    if(date.equals(startTime)){
-                        scheduleItems.add(scheduleItem);
-                    }
-                }
-                scheduleVO.setScheduleItemList(scheduleItems);
-                scheduleVOList.add(scheduleVO);
-            }
-            return ResponseVO.buildSuccess(scheduleVOList);
+
+            return ResponseVO.buildSuccess(getScheduleVOList(7, startDate, scheduleItemList));
         } catch (ParseException e) {
             e.printStackTrace();
             return ResponseVO.buildFailure("失败");
@@ -250,4 +265,24 @@ public class ScheduleServiceImpl implements ScheduleService {
 
         return false;
     }
+
+    List<ScheduleVO> getScheduleVOList(int interval,Date startDate, List<ScheduleItem> scheduleItemList ) throws ParseException {
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        List<ScheduleVO> scheduleVOList = new ArrayList<>();
+        for(int i = 0; i < interval; i++){
+            Date date = getNumDayAfterDate(startDate, i);
+            ScheduleVO scheduleVO = new ScheduleVO();
+            scheduleVO.setDate(date);
+            List<ScheduleItem> scheduleItems = new ArrayList<>();
+            for(ScheduleItem scheduleItem : scheduleItemList){
+                Date startTime = simpleDateFormat.parse(simpleDateFormat.format(scheduleItem.getStartTime()));
+                if(date.equals(startTime)){
+                    scheduleItems.add(scheduleItem);
+                }
+            }
+            scheduleVO.setScheduleItemList(scheduleItems);
+            scheduleVOList.add(scheduleVO);
+        }
+        return scheduleVOList;
+    }
 }

+ 3 - 19
src/main/java/com/example/cinema/blImpl/StatisticsServiceImpl.java

@@ -2,21 +2,16 @@ package com.example.cinema.blImpl;
 
 import com.example.cinema.bl.StatisticsService;
 import com.example.cinema.data.StatisticsMapper;
-import com.example.cinema.po.MovieScheduleTime;
+import com.example.cinema.vo.MovieScheduleTimeVO;
 import com.example.cinema.vo.ResponseVO;
-import com.example.cinema.vo.ScheduleRateVO;
-import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.text.DecimalFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
-import java.util.stream.Collectors;
 
 /**
  * @author fjj
@@ -37,19 +32,8 @@ public class StatisticsServiceImpl implements StatisticsService {
             requireDate = simpleDateFormat.parse(simpleDateFormat.format(requireDate));
 
             Date nextDate = getNumDayAfterDate(requireDate, 1);
-            List<MovieScheduleTime> movieScheduleTimes = statisticsMapper.selectMovieScheduleTimes(requireDate, nextDate);
-
-            //统计该天总排片数
-//            int totalTimes = movieScheduleTimes.stream().mapToInt(mst -> mst.getTime()).sum();
-//            List<ScheduleRateVO> scheduleRateVOList = new ArrayList<>();
-//            for(MovieScheduleTime movieScheduleTime: movieScheduleTimes){
-//                ScheduleRateVO scheduleRateVO = new ScheduleRateVO();
-//                scheduleRateVO.setMovieId(movieScheduleTime.getMovieId());
-//                scheduleRateVO.setRate(Double.parseDouble(String.format("%.2f",(double)movieScheduleTime.getTime() / totalTimes)));
-//                scheduleRateVO.setName(movieScheduleTime.getName());
-//                scheduleRateVOList.add(scheduleRateVO);
-//            }
-            return ResponseVO.buildSuccess(movieScheduleTimes);
+            List<MovieScheduleTimeVO> movieScheduleTimeVOList = statisticsMapper.selectMovieScheduleTimes(requireDate, nextDate);
+            return ResponseVO.buildSuccess(movieScheduleTimeVOList);
 
         }catch (Exception e){
             e.printStackTrace();

+ 90 - 43
src/main/java/com/example/cinema/blImpl/TicketServiceImpl.java

@@ -1,11 +1,9 @@
 package com.example.cinema.blImpl;
 
-import com.example.cinema.bl.CouponService;
+import com.example.cinema.bl.HallService;
 import com.example.cinema.bl.TicketService;
-import com.example.cinema.data.CouponMapper;
-import com.example.cinema.data.ScheduleMapper;
-import com.example.cinema.data.TicketMapper;
-import com.example.cinema.data.VIPCardMapper;
+import com.example.cinema.data.*;
+import com.example.cinema.po.Activity;
 import com.example.cinema.po.Coupon;
 import com.example.cinema.po.Ticket;
 import com.example.cinema.po.VIPCard;
@@ -14,6 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -31,38 +30,70 @@ public class TicketServiceImpl implements TicketService {
     ScheduleMapper scheduleMapper;
     @Autowired
     CouponMapper couponMapper;
+    @Autowired
+    HallMapper hallmapper;
+    @Autowired
+    ActivityMapper activityMapper;
 
     @Override
+    @Transactional
     public ResponseVO addTicket(TicketForm ticketForm) {
-
-        Ticket ticket = new Ticket();
-        ticket.setUserId(ticketForm.getUserId());
-        ticket.setScheduleId(ticketForm.getScheduleId());
-        ticket.setColumnIndex(ticketForm.getColumnIndex());
-        ticket.setRowIndex(ticketForm.getRowIndex());
-        ticket.setState(0);
-        try {
-            if(ticketMapper.selectTicketByScheduleIdAndSeat(ticketForm.getScheduleId(),ticketForm.getColumnIndex(),ticketForm.getRowIndex())!=null){
+        List<SeatForm> seats = ticketForm.getSeats();
+        List<Ticket> tickets=new ArrayList<>();
+        for (SeatForm seat : seats) {
+            Ticket ticket = new Ticket();
+            ticket.setUserId(ticketForm.getUserId());
+            ticket.setScheduleId(ticketForm.getScheduleId());
+            ticket.setColumnIndex(seat.getColumnIndex());
+            ticket.setRowIndex(seat.getRowIndex());
+            ticket.setState(0);
+            if (ticketMapper.selectTicketByScheduleIdAndSeat(ticketForm.getScheduleId(), seat.getColumnIndex(), seat.getRowIndex()) != null) {
                 return ResponseVO.buildFailure("该位置已被占");
             }
-            ticketMapper.insertTicket(ticket);
-            return ResponseVO.buildSuccess(ticket.getVO());
+            tickets.add(ticket);
+        }
+        try {
+            ticketMapper.insertTickets(tickets);
+            TicketWithCouponVO vo=new TicketWithCouponVO();
+            vo.setTicketVOList(tickets.stream().map(ticket -> ticket.getVO()).collect(Collectors.toList()));
+            ScheduleItem scheduleItem = scheduleMapper.selectScheduleById(tickets.get(0).getScheduleId());
+            double total=scheduleItem.getFare()*tickets.size();
+            vo.setTotal(total);
+            vo.setCoupons(couponMapper.selectCouponByUserAndAmount(tickets.get(0).getUserId(),total));
+            return ResponseVO.buildSuccess(vo);
         } catch (Exception e) {
             e.printStackTrace();
             return ResponseVO.buildFailure("失败");
         }
+
     }
 
     @Override
     @Transactional
-    public ResponseVO completeTicket(int id,int couponId) {
+    public ResponseVO completeTicket(List<Integer> id, int couponId) {
         try {
-            ticketMapper.updateTicketState(id, 1);
-            Ticket ticket=ticketMapper.selectTicketById(id);
-            if(couponId!=0) {
-                couponMapper.deleteCouponUser(couponId, ticket.getUserId());
+            List<Ticket> tickets=updateState(id,1);
+            int userId=tickets.get(0).getUserId();
+            if (couponId != 0) {
+                couponMapper.deleteCouponUser(couponId, userId);
+            }
+            ScheduleItem schedule=scheduleMapper.selectScheduleById(tickets.get(0).getScheduleId());
+            //  按电影优惠
+            List<ActivityVO> activityVOS=activityMapper.selectActivities();
+            List<Integer> coupons=new ArrayList<>();
+            for (ActivityVO vo:activityVOS ) {
+                coupons.add(vo.getCoupon().getId());
+            }
+            //  按时间优惠
+            List<ActivityVO> timeActivityVOS=activityMapper.selectActivitiesWithoutMovie();
+            for (ActivityVO vo:timeActivityVOS ) {
+                coupons.add(vo.getCoupon().getId());
             }
-            return ResponseVO.buildSuccess(ticket.getVO());
+            coupons=coupons.stream().distinct().collect(Collectors.toList());
+            for (Integer coupon : coupons) {
+                couponMapper.insertCouponUser(coupon,userId);
+            }
+            return ResponseVO.buildSuccess(tickets.stream().map(ticket -> ticket.getVO()).collect(Collectors.toList()));
         } catch (Exception e) {
             e.printStackTrace();
             return ResponseVO.buildFailure("失败");
@@ -73,14 +104,16 @@ public class TicketServiceImpl implements TicketService {
     public ResponseVO getBySchedule(int scheduleId) {
         try {
             List<Ticket> tickets = ticketMapper.selectTicketsBySchedule(scheduleId);
-            List<TicketSeatVO> ticketSeatVOS = tickets.stream().map(ticket -> {
-                TicketSeatVO vo = new TicketSeatVO();
-                vo.setScheduleId(ticket.getScheduleId());
-                vo.setColumnIndex(ticket.getColumnIndex());
-                vo.setRowIndex(ticket.getRowIndex());
-                return vo;
-            }).collect(Collectors.toList());
-            return ResponseVO.buildSuccess(ticketSeatVOS);
+            ScheduleItem schedule=scheduleMapper.selectScheduleById(scheduleId);
+            HallVO hall=hallmapper.selectHallById(schedule.getHallId());
+            int[][] seats=new int[hall.getRow()][hall.getColumn()];
+            tickets.stream().forEach(ticket -> {
+                seats[ticket.getRowIndex()][ticket.getColumnIndex()]=1;
+            });
+            ScheduleWithSeatVO scheduleWithSeatVO=new ScheduleWithSeatVO();
+            scheduleWithSeatVO.setScheduleItem(schedule);
+            scheduleWithSeatVO.setSeats(seats);
+            return ResponseVO.buildSuccess(scheduleWithSeatVO);
         } catch (Exception e) {
             e.printStackTrace();
             return ResponseVO.buildFailure("失败");
@@ -90,7 +123,11 @@ public class TicketServiceImpl implements TicketService {
     @Override
     public ResponseVO getTicketByUser(int userId) {
         try {
-            List<TicketVO> vos = ticketMapper.selectTicketByUser(userId).stream().map(ticket -> ticket.getVO()).collect(Collectors.toList());
+            List<TicketWithScheduleVO> vos = ticketMapper.selectTicketByUser(userId).stream().map(ticket -> {
+                TicketWithScheduleVO vo=ticket.getWithScheduleVO();
+                vo.setSchedule(scheduleMapper.selectScheduleById(ticket.getScheduleId()));
+                return vo;
+            }).collect(Collectors.toList());
             return ResponseVO.buildSuccess(vos);
         } catch (Exception e) {
             e.printStackTrace();
@@ -100,24 +137,22 @@ public class TicketServiceImpl implements TicketService {
 
     @Override
     @Transactional
-    public ResponseVO completeByVIPCard(int ticketId,int couponId) {
+    public ResponseVO completeByVIPCard(List<Integer> id, int couponId) {
         try {
-            Ticket ticket=ticketMapper.selectTicketById(ticketId);
+            Ticket ticket = ticketMapper.selectTicketById(id.get(0));
             VIPCard vipCard = vipCardMapper.selectCardByUserId(ticket.getUserId());
             ScheduleItem scheduleItem = scheduleMapper.selectScheduleById(ticket.getScheduleId());
             //todo 优惠券门槛校验
-            double balance = vipCard.getBalance() - scheduleItem.getFare();
-            if(couponId!=0) {
-                Coupon coupon=couponMapper.selectById(couponId);
-                balance+=coupon.getDiscountAmount();
+            double balance = vipCard.getBalance() - scheduleItem.getFare()*id.size();
+            if (couponId != 0) {
+                Coupon coupon = couponMapper.selectById(couponId);
+                balance += coupon.getDiscountAmount();
             }
             if (balance < 0) {
                 return ResponseVO.buildFailure("会员卡余额不足");
             }
             vipCardMapper.updateCardBalance(vipCard.getId(), balance);
-            completeTicket(ticketId,couponId);
-            ticket.setState(1);
-            return ResponseVO.buildSuccess(ticket.getVO());
+            return completeTicket(id, couponId);
         } catch (Exception e) {
             e.printStackTrace();
             return ResponseVO.buildFailure("失败");
@@ -125,15 +160,27 @@ public class TicketServiceImpl implements TicketService {
     }
 
     @Override
-    public ResponseVO cancelTicket(int ticketId) {
+    public ResponseVO cancelTicket(List<Integer> id) {
         try {
-            ticketMapper.updateTicketState(ticketId, 2);
-            return ResponseVO.buildSuccess(ticketMapper.selectTicketById(ticketId).getVO());
+            List<Ticket> tickets=updateState(id,2);
+
+            return ResponseVO.buildSuccess(tickets.stream().map(ticket -> ticket.getVO()).collect(Collectors.toList()));
         } catch (Exception e) {
             e.printStackTrace();
             return ResponseVO.buildFailure("失败");
         }
     }
 
+    private  List<Ticket>  updateState(List<Integer> id,int state){
+        List<Ticket> tickets=new ArrayList<>();
+        for (Integer i:id) {
+            ticketMapper.updateTicketState(i, state);
+            Ticket ticket = ticketMapper.selectTicketById(id.get(0));
+            tickets.add(ticket);
+        }
+        return tickets;
+
+    }
+
 
 }

+ 2 - 2
src/main/java/com/example/cinema/blImpl/VIPServiceImpl.java

@@ -60,7 +60,7 @@ public class VIPServiceImpl implements VIPService {
         double balance = vipCard.calculate(vipCardForm.getAmount());
         vipCard.setBalance(vipCard.getBalance() + balance);
         try {
-            vipCardMapper.updateCardBalance(vipCardForm.getVipId(), balance);
+            vipCardMapper.updateCardBalance(vipCardForm.getVipId(), vipCard.getBalance());
             return ResponseVO.buildSuccess(vipCard);
         } catch (Exception e) {
             e.printStackTrace();
@@ -75,7 +75,7 @@ public class VIPServiceImpl implements VIPService {
             if(vipCard==null){
                 return ResponseVO.buildFailure("用户卡不存在");
             }
-            return ResponseVO.buildSuccess(ResponseVO.buildSuccess(vipCard));
+            return ResponseVO.buildSuccess(vipCard);
         } catch (Exception e) {
             e.printStackTrace();
             return ResponseVO.buildFailure("失败");

+ 30 - 0
src/main/java/com/example/cinema/controller/ActivityController.java

@@ -0,0 +1,30 @@
+package com.example.cinema.controller;
+
+import com.example.cinema.bl.ActivityService;
+import com.example.cinema.vo.ActivityForm;
+import com.example.cinema.vo.ResponseVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * Created by liying on 2019/4/20.
+ */
+@RestController
+@RequestMapping("/activity")
+public class ActivityController {
+
+    @Autowired
+    ActivityService activityService;
+
+    @PostMapping("/publish")
+    public ResponseVO publishActivity(@RequestBody ActivityForm activityForm){
+        return activityService.publishActivity(activityForm);
+    }
+    @GetMapping("/get")
+    public ResponseVO getActivities(){
+        return activityService.getActivities();
+    }
+
+
+}

+ 6 - 2
src/main/java/com/example/cinema/controller/CouponController.java

@@ -1,6 +1,8 @@
 package com.example.cinema.controller;
 
+import com.example.cinema.bl.CouponService;
 import com.example.cinema.vo.ResponseVO;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -13,12 +15,14 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping("/coupon")
 public class CouponController {
 
+    @Autowired
+    CouponService couponService;
+
     @GetMapping("{userId}/get")
     public ResponseVO getCoupons(@PathVariable int userId){
-        return null;
+        return couponService.getCouponsByUser(userId);
     }
 
 
 
-
 }

+ 8 - 0
src/main/java/com/example/cinema/controller/MovieController.java

@@ -29,9 +29,17 @@ public class MovieController {
 
     @RequestMapping(value = "/movie/all", method = RequestMethod.GET)
     public ResponseVO searchAllMovie(){
+        //返回结果中包括已经下架的电影
         return movieService.searchAllMovie();
     }
 
+    @RequestMapping(value = "/movie/all/exclude/off", method = RequestMethod.GET)
+    public ResponseVO searchOtherMoviesExcludeOff(){
+        //返回结果中不包括已经下架的电影
+        return movieService.searchOtherMoviesExcludeOff();
+    }
+
+
     @RequestMapping(value = "/movie/{movieId}/like", method = RequestMethod.POST)
     public ResponseVO likeMovie(@PathVariable int movieId,@RequestParam int userId){
         return movieService.likeMovie(userId,movieId);

+ 6 - 1
src/main/java/com/example/cinema/controller/ScheduleController.java

@@ -35,13 +35,18 @@ public class ScheduleController {
         return scheduleService.searchScheduleSevenDays(hallId, startDate);
     }
 
+    @RequestMapping(value = "/schedule/search/audience", method = RequestMethod.GET)
+    public ResponseVO searchAudienceSchedule(@RequestParam int movieId){
+        return scheduleService.searchAudienceSchedule(movieId);
+    }
+
     @RequestMapping(value = "/schedule/view/set", method = RequestMethod.POST)
     public ResponseVO setScheduleView(@RequestBody  ScheduleViewForm scheduleViewForm){
         return scheduleService.setScheduleView(scheduleViewForm);
     }
 
     @RequestMapping(value = "/schedule/view", method = RequestMethod.GET)
-    public ResponseVO setScheduleView(){
+    public ResponseVO getScheduleView(){
         return scheduleService.getScheduleView();
     }
 

+ 5 - 3
src/main/java/com/example/cinema/controller/TicketController.java

@@ -7,6 +7,8 @@ import com.example.cinema.vo.TicketForm;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 /**
  * Created by liying on 2019/4/16.
  */
@@ -17,7 +19,7 @@ public class TicketController {
     TicketService ticketService;
 
     @PostMapping("/vip/buy")
-    public ResponseVO buyTicketByVIPCard(@RequestParam int ticketId,@RequestParam int couponId){
+    public ResponseVO buyTicketByVIPCard(@RequestParam List<Integer> ticketId, @RequestParam int couponId){
         return ticketService.completeByVIPCard(ticketId,couponId);
     }
 
@@ -26,7 +28,7 @@ public class TicketController {
         return ticketService.addTicket(ticketForm);
     }
     @PostMapping("/buy")
-    public ResponseVO buyTicket(@RequestParam int ticketId,@RequestParam int couponId){
+    public ResponseVO buyTicket(@RequestParam List<Integer> ticketId,@RequestParam int couponId){
         return ticketService.completeTicket(ticketId,couponId);
     }
     @GetMapping("/get/{userId}")
@@ -39,7 +41,7 @@ public class TicketController {
         return ticketService.getBySchedule(scheduleId);
     }
     @PostMapping("/cancel")
-    public ResponseVO cancelTicket(@RequestParam int ticketId){
+    public ResponseVO cancelTicket(@RequestParam List<Integer> ticketId){
         return ticketService.cancelTicket(ticketId);
     }
 

+ 33 - 0
src/main/java/com/example/cinema/data/ActivityMapper.java

@@ -0,0 +1,33 @@
+package com.example.cinema.data;
+
+import com.example.cinema.po.Activity;
+import com.example.cinema.vo.ActivityVO;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * Created by liying on 2019/4/20.
+ */
+@Mapper
+public interface ActivityMapper {
+
+    int insertActivity(Activity activity);
+
+    int insertActivityAndMovie(@Param("activityId") int activityId,@Param("movieId") List<Integer> movieId);
+
+    List<ActivityVO> selectActivities();
+
+    List<ActivityVO> selectActivitiesByMovie(int movieId);
+
+    ActivityVO selectById(int id);
+
+    List<ActivityVO> selectActivitiesWithoutMovie();
+
+
+
+
+
+
+}

+ 106 - 0
src/main/java/com/example/cinema/data/ActivityMapper.xml

@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.example.cinema.data.ActivityMapper">
+    <insert id="insertActivity" parameterType="com.example.cinema.po.Activity"
+            useGeneratedKeys="true" keyProperty="id">
+        insert into activity(a_description,activity_name,coupon_id,start_time,end_time)
+        values(#{description},#{name},#{couponId},#{startTime},#{endTime})
+    </insert>
+    <insert id="insertActivityAndMovie">
+        insert into activity_movie(activity_id,movie_id) values
+        <foreach collection="movieId" item="item" index="index"
+                 separator=",">
+            (#{activityId},#{item})
+        </foreach>
+    </insert>
+    <select id="selectById" resultMap="Activity">
+        select
+            *
+        from
+            activity a
+        left join
+            activity_movie am
+        on
+            a.id=am.activity_id
+        left join
+            movie m
+        on
+            am.movie_id=m.id
+        WHERE a.id=#{id}
+    </select>
+
+    <select id="selectActivities" resultMap="Activity">
+        select
+            *
+        from
+            activity a
+        left join
+            activity_movie am
+        on
+            a.id=am.activity_id
+        left join
+            movie m
+        on
+            am.movie_id=m.id
+
+    </select>
+
+    <select id="selectActivitiesByMovie" resultMap="Activity">
+        select
+        *
+        from
+        activity a
+        left join
+        activity_movie am
+        on
+        a.id=am.activity_id
+        left join
+        movie m
+        on
+        am.movie_id=m.id
+
+        where a.start_time &lt; Now() and a.end_time &gt; Now() and am.movie_id=#{movieId}
+
+    </select>
+    <select id="selectActivitiesWithoutMovie" resultMap="Activity">
+        select
+        *
+        from
+        activity a
+        left join
+        activity_movie am
+        on
+        a.id=am.activity_id
+        where a.start_time &lt; Now() and a.end_time &gt; Now() and movie_id is null
+
+    </select>
+
+
+
+    <resultMap id="Activity" type="com.example.cinema.vo.ActivityVO">
+        <result column="a_description" property="description"></result>
+        <result column="id" property="id"></result>
+        <result column="activity_name" property="name"></result>
+        <result column="start_time" property="startTime"></result>
+        <result column="end_time" property="endTime"></result>
+        <association property="coupon" column="coupon_id" select="com.example.cinema.data.CouponMapper.selectById">
+        </association>
+        <collection property="movieList" ofType="com.example.cinema.vo.MovieVO">
+            <id column="movie_id" property="id"></id>
+            <result column="poster_url" property="posterUrl"></result>
+            <result column="screen_writer" property="screenWriter"></result>
+            <result column="start_date" property="startDate"></result>
+            <result column="end_date" property="endDate"></result>
+            <result column="name" property="name"></result>
+            <result column="director" property="director"></result>
+            <result column="type" property="type"></result>
+            <result column="country" property="country"></result>
+            <result column="language" property="language"></result>
+            <result column="length" property="length"></result>
+            <result column="description" property="description"></result>
+            <result column="status" property="status"></result>
+            <result column="starring" property="starring"></result>
+        </collection>
+    </resultMap>
+
+</mapper>

+ 2 - 0
src/main/java/com/example/cinema/data/CouponMapper.java

@@ -21,4 +21,6 @@ public interface CouponMapper {
     void insertCouponUser(@Param("couponId") int couponId,@Param("userId")int userId);
 
     void deleteCouponUser(@Param("couponId") int couponId,@Param("userId")int userId);
+
+    List<Coupon> selectCouponByUserAndAmount(@Param("userId") int userId,@Param("amount") double amount);
 }

+ 7 - 2
src/main/java/com/example/cinema/data/CoupnMapper.xml → src/main/java/com/example/cinema/data/CouponMapper.xml

@@ -10,7 +10,7 @@
         insert into coupon_user(coupon_id,user_id)
         values(#{couponId},#{userId})
     </insert>
-    <delete id="insertCouponUser">
+    <delete id="deleteCouponUser">
         delete from coupon_user where coupon_id=#{couponId} and user_id =#{userId}
     </delete>
 
@@ -19,7 +19,12 @@
     </select>
 
     <select id="selectCouponByUser" resultMap="Coupon">
-        select * from coupon c left join coupon_user  cu on c.id=cu.coupon_id where cu.user_id=#{userId}
+        select * from coupon c left join coupon_user  cu on c.id=cu.coupon_id where cu.user_id=#{userId} and c.start_time &lt; Now() and c.end_time &gt; Now()
+
+    </select>
+
+    <select id="selectCouponByUserAndAmount" resultMap="Coupon">
+        select * from coupon c left join coupon_user  cu on c.id=cu.coupon_id where cu.user_id=#{userId} and c.start_time &lt; Now() and c.end_time &gt; Now() and #{amount}>c.target_amount
 
     </select>
 

+ 6 - 0
src/main/java/com/example/cinema/data/MovieMapper.java

@@ -41,6 +41,12 @@ public interface MovieMapper {
      */
     List<MovieVO> selectAllMovie();
 
+    /**
+     * 展示所有电影(不包括已经下架的)
+     * @return
+     */
+    List<MovieVO> selectOtherMoviesExcludeOff();
+
     /**
      * 根据关键字搜索电影
      * @param keyword

+ 14 - 1
src/main/java/com/example/cinema/data/MovieMapper.xml

@@ -17,7 +17,20 @@
     </select>
 
     <select id="selectAllMovie" resultMap="Movie">
-        select * from movie m left join (select l.movie_id, count(*) as likeCount from movie_like l group by l.movie_id) l on m.id = l.movie_id
+        select * from movie m
+        left join
+        (select l.movie_id, count(*) as likeCount from movie_like l group by l.movie_id) l
+        on m.id = l.movie_id
+        order by m.start_date asc
+    </select>
+
+    <select id="selectOtherMoviesExcludeOff" resultMap="Movie">
+        select * from
+        (select * from movie where movie.status = 0) m
+        left join
+        (select l.movie_id, count(*) as likeCount from movie_like l group by l.movie_id) l
+        on m.id = l.movie_id
+        order by m.start_date asc
     </select>
 
     <select id="selectMovieByKeyword" resultMap="Movie">

+ 8 - 0
src/main/java/com/example/cinema/data/ScheduleMapper.java

@@ -103,4 +103,12 @@ public interface ScheduleMapper {
      * @return
      */
     List<ScheduleItem> selectScheduleByMovieIdList(List<Integer> movieIdList);
+
+    /**
+     * 查询movieId的所有排片信息
+     * @param movieId
+     * @return
+     */
+    List<ScheduleItem> selectScheduleByMovieId(@Param("movieId") int movieId);
+
 }

+ 9 - 0
src/main/java/com/example/cinema/data/ScheduleMapper.xml

@@ -79,6 +79,15 @@
             where s.movie_id = m.movie_id and s.hall_id = h.hall_id
     </select>
 
+    <select id="selectScheduleByMovieId" resultMap="ScheduleItem">
+        select * from
+          (select * from schedule where movie_id = #{movieId}) s,
+          (select name as movie_name, id as movie_id from movie) m,
+          (select name as hall_name, id as hall_id from hall) h
+            where s.movie_id = m.movie_id and s.hall_id = h.hall_id
+            order by end_time asc
+    </select>
+
     <resultMap id="ScheduleItem" type="com.example.cinema.vo.ScheduleItem">
         <id column="id" property="id"></id>
         <result column="hall_id" property="hallId"></result>

+ 2 - 2
src/main/java/com/example/cinema/data/StatisticsMapper.java

@@ -1,6 +1,6 @@
 package com.example.cinema.data;
 
-import com.example.cinema.po.MovieScheduleTime;
+import com.example.cinema.vo.MovieScheduleTimeVO;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
@@ -18,5 +18,5 @@ public interface StatisticsMapper {
      * @param date
      * @return
      */
-    List<MovieScheduleTime> selectMovieScheduleTimes(@Param("date") Date date, @Param("nextDate") Date nextDate);
+    List<MovieScheduleTimeVO> selectMovieScheduleTimes(@Param("date") Date date, @Param("nextDate") Date nextDate);
 }

+ 9 - 0
src/main/java/com/example/cinema/data/StatisticsMapper.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.example.cinema.data.StatisticsMapper">
+    <select id="selectMovieScheduleTimes" resultType="com.example.cinema.vo.MovieScheduleTimeVO">
+        select movie_id as movieId, count(*) as time,name from
+              (select * from schedule where start_time between #{date} and #{nextDate}) s,
+              movie where s.movie_id = movie.id group by movieId
+    </select>
+</mapper>

+ 2 - 0
src/main/java/com/example/cinema/data/TicketMapper.java

@@ -14,6 +14,8 @@ public interface TicketMapper {
 
     int insertTicket(Ticket ticket);
 
+    int insertTickets(List<Ticket> tickets);
+
     void deleteTicket(int ticketId);
 
     void updateTicketState(@Param("ticketId") int ticketId, @Param("state") int state);

+ 11 - 1
src/main/java/com/example/cinema/data/TicketMapper.xml

@@ -6,6 +6,16 @@
         insert into ticket(user_id,schedule_id,column_index,row_index,state)
         values(#{userId}, #{scheduleId},#{columnIndex},#{rowIndex},#{state})
     </insert>
+    <insert id="insertTickets" parameterType="java.util.List"
+            useGeneratedKeys="true" keyProperty="id">
+        insert into ticket(user_id,schedule_id,column_index,row_index,state)
+        values
+        <foreach collection="list" item="item" index="index"
+                 separator=",">
+            (#{item.userId}, #{item.scheduleId},#{item.columnIndex},#{item.rowIndex},#{item.state})
+        </foreach>
+
+    </insert>
 
     <select id="selectTicketById" resultMap="Ticket">
         select * from ticket where id=#{id}
@@ -24,7 +34,7 @@
     </select>
 
 
-    <update id="updateTicketState" >
+    <update id="updateTicketState">
         update ticket set state = #{state} where id=#{ticketId}
     </update>
 

+ 88 - 0
src/main/java/com/example/cinema/po/Activity.java

@@ -0,0 +1,88 @@
+package com.example.cinema.po;
+
+import com.example.cinema.vo.CouponForm;
+import com.example.cinema.vo.MovieForm;
+
+import java.sql.Timestamp;
+import java.util.List;
+
+/**
+ * Created by liying on 2019/4/20.
+ */
+public class Activity {
+
+    private int id;
+    /**
+     * 优惠活动名称
+     */
+    private String name;
+    /**
+     * 优惠活动描述
+     */
+    private String description;
+    /**
+     * 优惠活动开始时间
+     */
+    private Timestamp startTime;
+    /**
+     * 优惠活动截止时间
+     */
+    private Timestamp endTime;
+    /**
+     * 优惠券id
+     */
+    private int couponId;
+
+    public Activity() {
+
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public int getCouponId() {
+        return couponId;
+    }
+
+    public void setCouponId(int couponId) {
+        this.couponId = couponId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Timestamp getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Timestamp startTime) {
+        this.startTime = startTime;
+    }
+
+    public Timestamp getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Timestamp endTime) {
+        this.endTime = endTime;
+    }
+
+}

+ 26 - 0
src/main/java/com/example/cinema/po/Ticket.java

@@ -1,6 +1,7 @@
 package com.example.cinema.po;
 
 import com.example.cinema.vo.TicketVO;
+import com.example.cinema.vo.TicketWithScheduleVO;
 
 /**
  * Created by liying on 2019/4/16.
@@ -63,6 +64,31 @@ public class Ticket {
         return vo;
 
     }
+    public TicketWithScheduleVO getWithScheduleVO() {
+        TicketWithScheduleVO vo = new TicketWithScheduleVO();
+        vo.setRowIndex(this.getRowIndex());
+        vo.setColumnIndex(this.getColumnIndex());
+        vo.setId(this.getId());
+        vo.setUserId(this.getUserId());
+        String stateString;
+        switch (state) {
+            case 0:
+                stateString = "未完成";
+                break;
+            case 1:
+                stateString = "已完成";
+                break;
+            case 2:
+                stateString = "已失效";
+                break;
+            default:
+                stateString = "未完成";
+        }
+        vo.setState(stateString);
+        return vo;
+
+    }
+
 
     public int getId() {
         return id;

+ 1 - 1
src/main/java/com/example/cinema/po/VIPCard.java

@@ -11,7 +11,7 @@ public class VIPCard {
 
     public static final double price = 25;
 
-    public static final String description="充值优惠:满200送30";
+    public static final String description="满200送30";
 
     /**
      * 用户id

+ 87 - 0
src/main/java/com/example/cinema/vo/ActivityForm.java

@@ -0,0 +1,87 @@
+package com.example.cinema.vo;
+
+import java.sql.Timestamp;
+import java.util.List;
+
+/**
+ * Created by liying on 2019/4/20.
+ */
+public class ActivityForm {
+    /**
+     * 优惠活动名称
+     */
+    private String name;
+    /**
+     * 优惠活动描述
+     */
+    private String description;
+    /**
+     * 优惠活动开始时间
+     */
+    private Timestamp startTime;
+    /**
+     * 优惠活动截止时间
+     */
+    private Timestamp endTime;
+    /**
+     * 优惠电影列表
+     */
+    private List<Integer> movieList;
+    /**
+     * 优惠券规格
+     */
+    private CouponForm couponForm;
+
+
+    public ActivityForm() {
+
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Timestamp getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Timestamp startTime) {
+        this.startTime = startTime;
+    }
+
+    public Timestamp getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Timestamp endTime) {
+        this.endTime = endTime;
+    }
+
+    public List<Integer> getMovieList() {
+        return movieList;
+    }
+
+    public void setMovieList(List<Integer> movieList) {
+        this.movieList = movieList;
+    }
+
+    public CouponForm getCouponForm() {
+        return couponForm;
+    }
+
+    public void setCouponForm(CouponForm couponForm) {
+        this.couponForm = couponForm;
+    }
+}

+ 99 - 0
src/main/java/com/example/cinema/vo/ActivityVO.java

@@ -0,0 +1,99 @@
+package com.example.cinema.vo;
+
+import com.example.cinema.po.Coupon;
+
+import java.sql.Timestamp;
+import java.util.List;
+
+/**
+ * Created by liying on 2019/4/20.
+ */
+public class ActivityVO {
+
+    private int id;
+    /**
+     * 优惠活动名称
+     */
+    private String name;
+    /**
+     * 优惠活动描述
+     */
+    private String description;
+    /**
+     * 优惠活动开始时间
+     */
+    private Timestamp startTime;
+    /**
+     * 优惠活动截止时间
+     */
+    private Timestamp endTime;
+    /**
+     * 优惠电影列表
+     */
+    private List<MovieVO> movieList;
+    /**
+     * 优惠券规格
+     */
+    private Coupon coupon;
+
+
+    public ActivityVO() {
+
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Timestamp getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Timestamp startTime) {
+        this.startTime = startTime;
+    }
+
+    public Timestamp getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Timestamp endTime) {
+        this.endTime = endTime;
+    }
+
+    public List<MovieVO> getMovieList() {
+        return movieList;
+    }
+
+    public void setMovieList(List<MovieVO> movieList) {
+        this.movieList = movieList;
+    }
+
+    public Coupon getCoupon() {
+        return coupon;
+    }
+
+    public void setCoupon(Coupon coupon) {
+        this.coupon = coupon;
+    }
+}

+ 2 - 2
src/main/java/com/example/cinema/po/MovieScheduleTime.java → src/main/java/com/example/cinema/vo/MovieScheduleTimeVO.java

@@ -1,10 +1,10 @@
-package com.example.cinema.po;
+package com.example.cinema.vo;
 
 /**
  * @author fjj
  * @date 2019/4/16 2:48 PM
  */
-public class MovieScheduleTime {
+public class MovieScheduleTimeVO {
     private Integer movieId;
     /**
      * 排片次数

+ 0 - 35
src/main/java/com/example/cinema/vo/ScheduleRateVO.java

@@ -1,35 +0,0 @@
-package com.example.cinema.vo;
-
-/**
- * @author fjj
- * @date 2019/4/16 3:48 PM
- */
-public class ScheduleRateVO {
-    private Integer movieId;
-    private Double rate;
-    private String name;
-
-    public Integer getMovieId() {
-        return movieId;
-    }
-
-    public void setMovieId(Integer movieId) {
-        this.movieId = movieId;
-    }
-
-    public Double getRate() {
-        return rate;
-    }
-
-    public void setRate(Double rate) {
-        this.rate = rate;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}

+ 31 - 0
src/main/java/com/example/cinema/vo/ScheduleWithSeatVO.java

@@ -0,0 +1,31 @@
+package com.example.cinema.vo;
+
+/**
+ * Created by liying on 2019/4/21.
+ */
+public class ScheduleWithSeatVO {
+    /**
+     * 排片
+     */
+    private ScheduleItem  scheduleItem;
+    /**
+     * 座位
+     */
+    private int[][] seats;
+
+    public ScheduleItem getScheduleItem() {
+        return scheduleItem;
+    }
+
+    public void setScheduleItem(ScheduleItem scheduleItem) {
+        this.scheduleItem = scheduleItem;
+    }
+
+    public int[][] getSeats() {
+        return seats;
+    }
+
+    public void setSeats(int[][] seats) {
+        this.seats = seats;
+    }
+}

+ 3 - 21
src/main/java/com/example/cinema/vo/TicketSeatVO.java → src/main/java/com/example/cinema/vo/SeatForm.java

@@ -1,13 +1,9 @@
 package com.example.cinema.vo;
 
 /**
- * Created by liying on 2019/4/16.
+ * Created by liying on 2019/4/18.
  */
-public class TicketSeatVO {
-    /**
-     * 排片id
-     */
-    private int scheduleId;
+public class SeatForm {
     /**
      * 列号
      */
@@ -17,19 +13,6 @@ public class TicketSeatVO {
      */
     private int rowIndex;
 
-
-    public TicketSeatVO() {
-    }
-
-
-    public int getScheduleId() {
-        return scheduleId;
-    }
-
-    public void setScheduleId(int scheduleId) {
-        this.scheduleId = scheduleId;
-    }
-
     public int getColumnIndex() {
         return columnIndex;
     }
@@ -45,5 +28,4 @@ public class TicketSeatVO {
     public void setRowIndex(int rowIndex) {
         this.rowIndex = rowIndex;
     }
-
-}
+}

+ 10 - 22
src/main/java/com/example/cinema/vo/TicketForm.java

@@ -1,5 +1,7 @@
 package com.example.cinema.vo;
 
+import java.util.List;
+
 /**
  * Created by liying on 2019/4/16.
  */
@@ -13,16 +15,16 @@ public class TicketForm {
      * 排片id
      */
     private int scheduleId;
-    /**
-     * 列号
-     */
-    private int columnIndex;
-    /**
-     * 排号
-     */
-    private int rowIndex;
 
+    private List<SeatForm> seats;
+
+    public List<SeatForm> getSeats() {
+        return seats;
+    }
 
+    public void setSeats(List<SeatForm> seats) {
+        this.seats = seats;
+    }
 
     public TicketForm() {
     }
@@ -43,20 +45,6 @@ public class TicketForm {
         this.scheduleId = scheduleId;
     }
 
-    public int getColumnIndex() {
-        return columnIndex;
-    }
-
-    public void setColumnIndex(int columnIndex) {
-        this.columnIndex = columnIndex;
-    }
 
-    public int getRowIndex() {
-        return rowIndex;
-    }
-
-    public void setRowIndex(int rowIndex) {
-        this.rowIndex = rowIndex;
-    }
 
 }

+ 41 - 0
src/main/java/com/example/cinema/vo/TicketWithCouponVO.java

@@ -0,0 +1,41 @@
+package com.example.cinema.vo;
+
+import com.example.cinema.po.Coupon;
+
+import java.util.List;
+
+/**
+ * Created by liying on 2019/4/21.
+ */
+public class TicketWithCouponVO {
+
+    private List<TicketVO> ticketVOList;
+
+    private double total;
+
+    private List<Coupon> coupons;
+
+    public List<TicketVO> getTicketVOList() {
+        return ticketVOList;
+    }
+
+    public void setTicketVOList(List<TicketVO> ticketVOList) {
+        this.ticketVOList = ticketVOList;
+    }
+
+    public double getTotal() {
+        return total;
+    }
+
+    public void setTotal(double total) {
+        this.total = total;
+    }
+
+    public List<Coupon> getCoupons() {
+        return coupons;
+    }
+
+    public void setCoupons(List<Coupon> coupons) {
+        this.coupons = coupons;
+    }
+}

+ 84 - 0
src/main/java/com/example/cinema/vo/TicketWithScheduleVO.java

@@ -0,0 +1,84 @@
+package com.example.cinema.vo;
+
+/**
+ * Created by liying on 2019/4/16.
+ */
+public class TicketWithScheduleVO {
+
+    /**
+     * 电影票id
+     */
+    private int id;
+    /**
+     * 用户id
+     */
+    private int userId;
+    /**
+     * 排片id
+     */
+    private ScheduleItem schedule;
+    /**
+     * 列号
+     */
+    private int columnIndex;
+    /**
+     * 排号
+     */
+    private int rowIndex;
+
+    /**
+     * 订单状态
+     */
+    private String state;
+
+    public TicketWithScheduleVO() {
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public int getUserId() {
+        return userId;
+    }
+
+    public void setUserId(int userId) {
+        this.userId = userId;
+    }
+
+    public ScheduleItem getSchedule() {
+        return schedule;
+    }
+
+    public void setSchedule(ScheduleItem scheduleId) {
+        this.schedule = schedule;
+    }
+
+    public int getColumnIndex() {
+        return columnIndex;
+    }
+
+    public void setColumnIndex(int columnIndex) {
+        this.columnIndex = columnIndex;
+    }
+
+    public int getRowIndex() {
+        return rowIndex;
+    }
+
+    public void setRowIndex(int rowIndex) {
+        this.rowIndex = rowIndex;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+}

+ 9 - 0
src/main/resources/static/css/cinemaHall.css

@@ -18,9 +18,18 @@
     width: 32px;
     height: 32px;
     margin: 3px;
+
+    border: none;
+    outline: none;
 }
 
 .cinema-hall-seat-choose {
     background: url("../images/seatChoose.png");
+    display: inline-block;
+    width: 32px;
+    height: 32px;
+    margin: 3px;
 
+    border: none;
+    outline: none;
 }

+ 10 - 3
src/main/resources/static/css/userMember.css

@@ -90,7 +90,7 @@
     position: relative;
     overflow: hidden;
     background: #1caf9a;
-    height: 100px;
+    height: 120px;
     margin: 5px;
 }
 
@@ -127,6 +127,8 @@
 
 .coupon .content .left {
     display: flex;
+    flex-shrink: 0;
+    min-width: 50%;
     flex-direction: column;
     border-right: 2px dashed rgba(255,255,255,.3);
 }
@@ -136,14 +138,19 @@
 }
 
 .coupon .content .left .description{
+    font-size: 10px;
+    color: #f9d3a1;
+}
+
+.coupon .content .left .price{
     font-size: 24px;
 }
 
 .coupon .content .right {
-    text-align: right;
+    text-align: left;
     color: #d2d2d2;
 }
 
 .notice {
-     margin-left: 10px;
+     margin-left: 12px;
 }

+ 71 - 9
src/main/resources/static/css/userMovieBuy.css

@@ -1,35 +1,97 @@
+/*第一阶段*/
 .seat-content {
     display: flex;
 }
 
-.seat-content .hall {
-    flex-grow: 1;
-    flex-shrink: 0;
-}
-
 .seat-content .movie-detail {
     padding: 20px;
     min-width: 30%;
 }
 
-.seat-content .movie-detail .head {
+.seat-content .movie-detail .line {
     display: flex;
     flex-direction: row;
 }
 
-.seat-content .movie-detail .head .img-wrapper {
+.seat-content .movie-detail .line .name {
+    flex-shrink: 0;
+}
+
+.img-wrapper {
     margin-right: 20px;
     margin-bottom: 20px;
     width: 100px;
 }
 
-.seat-content .movie-detail .head .img-wrapper img {
+.img-wrapper img {
     width: 100%;
     height: auto;
 }
 
-.seat-content .movie-detail .info #movie-name {
+.info #movie-name {
     font-size: 20px;
     font-weight: bold;
     margin-bottom: 5px;
+}
+
+#seat-detail {
+    display: flex;
+    flex-wrap: wrap;
+}
+
+#seat-detail span {
+    flex-shrink: 0;
+    margin-right: 5px;
+}
+
+/*第二阶段*/
+#order-state table thead tr {
+    background-color: #1caf9ab8;
+}
+
+#order-state table th, td {
+    text-align: center;
+    vertical-align: middle !important;
+}
+
+.order-info {
+    margin: 20px 0;
+    display: flex;
+    justify-content: space-between;
+    padding: 20px;
+}
+
+.item {
+    margin: 5px 0;
+}
+
+.order-footer {
+    display: flex;
+    flex-direction: column;
+    justify-content: flex-end;
+    align-items: flex-end;
+    padding: 10px;
+    margin-bottom: 20px;
+}
+
+.order-footer b {
+    font-size: 20px;
+    color: #1caf9a;
+}
+
+hr.dashed-line {
+    border: 1px dashed #eeeeee
+}
+
+.success-notice {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    padding: 50px;
+}
+
+.success-notice .hint {
+    margin-top: 25px;
+    font-size: 20px;
 }

BIN
src/main/resources/static/images/success.png


+ 1 - 0
src/main/resources/static/js/movieDetail.js

@@ -76,6 +76,7 @@ $(document).ready(function(){
         $('#movie-director').text(movie.director);
         $('#movie-starring').text(movie.starring);
         $('#movie-writer').text(movie.screenWriter);
+        $('#movie-length').text(movie.length);
     }
 
     // user界面才有

+ 161 - 0
src/main/resources/static/js/userMember.js

@@ -0,0 +1,161 @@
+$(document).ready(function () {
+    getVIP();
+    getCoupon();
+});
+
+var isBuyState = true;
+var vipCardId;
+
+function getVIP() {
+    getRequest(
+        '/vip/' + sessionStorage.getItem('id') + '/get',
+        function (res) {
+            if (res.success) {
+                // 是会员
+                $("#member-card").css("visibility", "visible");
+                $("#member-card").css("display", "");
+                $("#nonmember-card").css("display", "none");
+
+                vipCardId = res.content.id;
+                $("#member-id").text(res.content.id);
+                $("#member-balance").text("¥" + res.content.balance);
+                $("#member-joinDate").text(res.content.joinDate.substring(0, 10));
+            } else {
+                // 非会员
+                $("#member-card").css("display", "none");
+                $("#nonmember-card").css("display", "");
+            }
+        },
+        function (error) {
+            alert(error);
+        });
+
+    getRequest(
+        '/vip/getVIPInfo',
+        function (res) {
+            if (res.success) {
+                $("#member-buy-price").text(res.content.price);
+                $("#member-buy-description").text("充值优惠:" + res.content.description + "。永久有效");
+                $("#member-description").text(res.content.description);
+            } else {
+                alert(res.content);
+            }
+
+        },
+        function (error) {
+            alert(error);
+        });
+}
+
+function buyClick() {
+    clearForm();
+    $('#buyModal').modal('show')
+    $("#userMember-amount-group").css("display", "none");
+    isBuyState = true;
+}
+
+function chargeClick() {
+    clearForm();
+    $('#buyModal').modal('show')
+    $("#userMember-amount-group").css("display", "");
+    isBuyState = false;
+}
+
+function clearForm() {
+    $('#userMember-form input').val("");
+    $('#userMember-form .form-group').removeClass("has-error");
+    $('#userMember-form p').css("visibility", "hidden");
+}
+
+function confirmCommit() {
+    if (validateForm()) {
+        if ($('#userMember-cardNum').val() === "123123123" && $('#userMember-cardPwd').val() === "123123") {
+            if (isBuyState) {
+                postRequest(
+                    '/vip/add?userId=' + sessionStorage.getItem('id'),
+                    null,
+                    function (res) {
+                        $('#buyModal').modal('hide');
+                        alert("购买会员卡成功");
+                        getVIP();
+                    },
+                    function (error) {
+                        alert(error);
+                    });
+            } else {
+                postRequest(
+                    '/vip/charge',
+                    {vipId: vipCardId, amount: parseInt($('#userMember-amount').val())},
+                    function (res) {
+                        $('#buyModal').modal('hide');
+                        alert("充值成功");
+                        getVIP();
+                    },
+                    function (error) {
+                        alert(error);
+                    });
+            }
+        } else {
+            alert("银行卡号或密码错误");
+        }
+    }
+}
+
+function validateForm() {
+    var isValidate = true;
+    if (!$('#userMember-cardNum').val()) {
+        isValidate = false;
+        $('#userMember-cardNum').parent('.form-group').addClass('has-error');
+        $('#userMember-cardNum-error').css("visibility", "visible");
+    }
+    if (!$('#userMember-cardPwd').val()) {
+        isValidate = false;
+        $('#userMember-cardPwd').parent('.form-group').addClass('has-error');
+        $('#userMember-cardPwd-error').css("visibility", "visible");
+    }
+    if (!isBuyState && (!$('#userMember-amount').val() || parseInt($('#userMember-amount').val()) <= 0)) {
+        isValidate = false;
+        $('#userMember-amount').parent('.form-group').addClass('has-error');
+        $('#userMember-amount-error').css("visibility", "visible");
+    }
+    return isValidate;
+}
+
+function getCoupon() {
+    getRequest(
+        '/coupon/' + sessionStorage.getItem('id') + '/get',
+        function (res) {
+            if (res.success) {
+                var couponList = res.content;
+                var couponListContent = '';
+                for (let coupon of couponList) {
+                    couponListContent += '<div class="content">' +
+                        '<div class="col-md-8 left">' +
+                        '<div class="name">' +
+                        coupon.name +
+                        '</div>' +
+                        '<div class="description">' +
+                        coupon.description +
+                        '</div>' +
+                        '<div class="price">' +
+                        '满' + coupon.targetAmount + '减' + coupon.discountAmount +
+                        '</div>' +
+                        '</div>' +
+                        '<div class="col-md-4 right">' +
+                        '<div>有效日期:</div>' +
+                        '<div>' + formatDate(coupon.startTime) + ' ~ ' + formatDate(coupon.endTime) + '</div>' +
+                        '</div>' +
+                        '</div>'
+                }
+                $('#coupon-list').html(couponListContent);
+
+            }
+        },
+        function (error) {
+            alert(error);
+        });
+}
+
+function formatDate(date) {
+    return date.substring(5, 10).replace("-", ".");
+}

+ 100 - 30
src/main/resources/static/js/userMovieBuy.js

@@ -1,47 +1,117 @@
+var selectedSeats = []
+var scheduleId;
+
 $(document).ready(function () {
+    scheduleId = parseInt(window.location.href.split('?')[1].split('&')[1].split('=')[1]);
 
-    getCinemaHalls();
+    getInfo();
 
-    function getCinemaHalls() {
-        // TODO:修改
-        var halls = [];
+    function getInfo() {
         getRequest(
-            '/hall/all',
+            '/ticket/get/occupiedSeats?scheduleId=' + scheduleId,
             function (res) {
-                halls = res.content;
-                renderHall(halls);
+                if (res.success) {
+                    renderSchedule(res.content.scheduleItem, res.content.seats);
+                }
             },
             function (error) {
                 alert(JSON.stringify(error));
             }
         );
     }
+});
 
-    function renderHall(halls) {
-        $('#hall-card').empty();
-        var hallDomStr = "";
+function renderSchedule(schedule, seats) {
+    $('#schedule-hall-name').text(schedule.hallName);
+    $('#schedule-time').text(schedule.startTime.substring(5, 7) + "月" + schedule.startTime.substring(8, 10) + "日 " + schedule.startTime.substring(11, 16) + "场");
 
-        var hall = halls[0]
+    var hallDomStr = "";
+    var seat = "";
+    for (var i = 0; i < seats.length; i++) {
+        var temp = ""
+        for (var j = 0; j < seats[i].length; j++) {
+            var id = "seat" + i + j
 
-        var seat = "";
-        for (var i = 0; i < hall.row; i++) {
-            var temp = ""
-            for (var j = 0; j < hall.column; j++) {
-                temp += "<div class='cinema-hall-seat'></div>";
+            if (seats[i][j] == 0) {
+                // 未选
+                temp += "<button class='cinema-hall-seat-choose' id='" + id + "' onclick='seatClick(\"" + id + "\"," + i + "," + j + ")'></button>";
+            } else {
+                // 已选中
+                selectedSeats[selectedSeats.length] = [i, j]
+                temp += "<button class='cinema-hall-seat' id='" + id + "' onclick='seatClick(\"" + id + "\"," + i + "," + j + ")'></button>";
             }
-            seat += "<div>" + temp + "</div>";
         }
-        var hallDom =
-            "<div class='cinema-hall'>" +
-            "<div>" +
-            "<span class='cinema-hall-name'>" + hall.name + "</span>" +
-            "<span class='cinema-hall-size'>" + hall.column + '*' + hall.row + "</span>" +
-            "</div>" +
-            "<div class='cinema-seat'>" + seat +
-            "</div>" +
-            "</div>";
-        hallDomStr += hallDom;
-
-        $('#hall-card').append(hallDomStr);
+        seat += "<div>" + temp + "</div>";
+    }
+    var hallDom =
+        "<div class='cinema-hall'>" +
+        "<div>" +
+        "<span class='cinema-hall-name'>" + schedule.hallName + "</span>" +
+        "<span class='cinema-hall-size'>" + seats.length + '*' + seats[0].length + "</span>" +
+        "</div>" +
+        "<div class='cinema-seat'>" + seat +
+        "</div>" +
+        "</div>";
+    hallDomStr += hallDom;
+
+    $('#hall-card').html(hallDomStr);
+}
+
+function seatClick(id, i, j) {
+    let seat = $('#' + id);
+    if (seat.hasClass("cinema-hall-seat-choose")) {
+        seat.removeClass("cinema-hall-seat-choose");
+        seat.addClass("cinema-hall-seat");
+
+        selectedSeats[selectedSeats.length] = [i, j]
+    } else {
+        seat.removeClass("cinema-hall-seat");
+        seat.addClass("cinema-hall-seat-choose");
+
+        selectedSeats = selectedSeats.filter(function (value) {
+            return value[0] != i || value[1] != j;
+        })
+    }
+
+    selectedSeats.sort(function (x, y) {
+        var res = x[0] - y[0];
+        return res === 0 ? x[1] - y[1] : res;
+    });
+
+    let seatDetailStr = "";
+    if (selectedSeats.length == 0) {
+        seatDetailStr += "还未选择座位"
+        $('#order-confirm-btn').attr("disabled", "disabled")
+    } else {
+        for (let seatLoc of selectedSeats) {
+            seatDetailStr += "<span>" + (seatLoc[0] + 1) + "排" + (seatLoc[1] + 1) + "座</span>";
+        }
+        $('#order-confirm-btn').removeAttr("disabled");
     }
-});
+    $('#seat-detail').html(seatDetailStr);
+}
+
+function orderConfirmClick() {
+    var seats = [];
+    for (let seat of selectedSeats) {
+        seats.push({rowIndex: seat[0], columnIndex: seat[1]});
+    }
+
+    // 锁座位
+    postRequest(
+        '/ticket/lockSeat',
+        {userId: sessionStorage.getItem('id'), scheduleId: scheduleId, seats: seats},
+        function (res) {
+            $('#seat-state').css("display", "none");
+            $('#order-state').css("display", "");
+        },
+        function (error) {
+            alert(error);
+        });
+}
+
+function payConfirmClick() {
+    $('#order-state').css("display", "none");
+    $('#success-state').css("display", "");
+    $('#buyModal').modal('hide')
+}

+ 61 - 0
src/main/resources/static/js/userMovieDetail.js

@@ -0,0 +1,61 @@
+var dates;
+var movieId;
+
+$(document).ready(function () {
+    movieId = parseInt(window.location.href.split('?')[1].split('&')[0].split('=')[1]);
+
+    getSchedule();
+
+    function getSchedule() {
+        getRequest(
+            '/schedule/search/audience?movieId=' + movieId,
+            function (res) {
+                if (res.success) {
+                    $('#schedule').css("display", "");
+                    dates = res.content;
+                    repaintScheduleDate(0);
+                } else {
+                    $('#none-hint').css("display", "");
+                }
+            },
+            function (error) {
+                alert(error);
+            }
+        );
+    }
+
+});
+
+function repaintScheduleDate(curDateLoc) {
+    var dateContent = ""
+    for (var i = 0; i < dates.length; i++) {
+        var date = dates[i].date.substring(5, 7) + "月" + dates[i].date.substring(8, 10) + "日";
+        if (i == 0) date += "(今天)";
+        else if (i == 1) date += "(明天)";
+        dateContent += '<li role="presentation" id="schedule-date' + i + '"><a href="#"  onclick="repaintScheduleDate(\'' + i + '\')">' + date + '</a></li>';
+    }
+    $('#schedule-date').html(dateContent);
+
+    $('#schedule-date' + curDateLoc).addClass("active");
+    repaintScheduleBody(curDateLoc);
+}
+
+function repaintScheduleBody(curDateLoc) {
+    var scheduleItems = dates[curDateLoc].scheduleItemList;
+
+    if (scheduleItems.length == 0) {
+        $('#date-none-hint').css("display", "");
+    } else {
+        $('#date-none-hint').css("display", "none");
+    }
+    var bodyContent = "";
+    for (var i = 0; i < scheduleItems.length; i++) {
+        bodyContent += "<tr><td>" + scheduleItems[i].startTime.substring(11, 16) + "</td>" +
+            "<td>预计" + scheduleItems[i].endTime.substring(11, 16) + "散场</td>" +
+            "<td>" + scheduleItems[i].hallName + "</td>" +
+            "<td><b>" + scheduleItems[i].fare.toFixed(2) + "</b></td>" +
+            "<td><a class='btn btn-primary' href='/user/movieDetail/buy?id="+movieId+"&scheduleId="+scheduleItems[i].id+"' role='button'>选座购票</a></td></tr>";
+    }
+
+    $('#schedule-body').html(bodyContent);
+}

+ 25 - 68
src/main/resources/templates/userMember.html

@@ -42,7 +42,7 @@
 </div>
 <div class="content-container">
     <!--非会员-->
-    <div class="card col-md-8 col-md-offset-2">
+    <div class="card col-md-8 col-md-offset-2" id="nonmember-card" style="display: none;">
         <div class="header">
             <div class="title">会员卡</div>
             <div class="state">非会员</div>
@@ -52,14 +52,14 @@
             <hr/>
         </div>
         <div class="info">
-            <div class="price"><b>18</b>元/张</div>
-            <div class="description">充值优惠:满300送20。永久有效</div>
-            <button id="buy" data-toggle="modal" data-target="#buyModal">立即购买</button>
+            <div class="price"><b id="member-buy-price"></b>元/张</div>
+            <div id="member-buy-description" class="description"></div>
+            <button onclick="buyClick()">立即购买</button>
         </div>
     </div>
 
     <!--会员-->
-    <div class="card col-md-8 col-md-offset-2">
+    <div class="card col-md-8 col-md-offset-2" id="member-card" style="visibility: hidden;">
         <div class="header">
             <div class="title">会员卡</div>
             <div class="state">VIP</div>
@@ -72,22 +72,25 @@
             <div class="content">
                 <div class="line">
                     <div><b>会员卡号:</b></div>
-                    <div>100001</div>
-                </div>
-                <div class="line">
-                    <div><b>余额:</b></div>
-                    <div>¥0</div>
+                    <div id="member-id"></div>
                 </div>
                 <div class="line">
                     <div><b>入会日期:</b></div>
-                    <div>2019/04/13</div>
+                    <div id="member-joinDate"></div>
                 </div>
                 <div class="line">
                     <div><b>充值优惠:</b></div>
-                    <div>满200减30</div>
+                    <div id="member-description"></div>
+                </div>
+
+                <hr/>
+
+                <div class="line">
+                    <div><b>余额:</b></div>
+                    <div id="member-balance"></div>
                 </div>
             </div>
-            <button>立即充值</button>
+            <button onclick="chargeClick()">立即充值</button>
         </div>
     </div>
 
@@ -97,54 +100,7 @@
             <div class="title">优惠券</div>
         </div>
         <div class="col-md-6 coupon-wrapper">
-            <div class="coupon">
-                <div class="content">
-                    <div class="col-md-9 left">
-                        <div class="name">
-                            春季优惠券
-                        </div>
-                        <div class="description">
-                            满20减5
-                        </div>
-                    </div>
-                    <div class="col-md-3 right">
-                        永久有效
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="col-md-6 coupon-wrapper">
-            <div class="coupon">
-                <div class="content">
-                    <div class="col-md-9 left">
-                        <div class="name">
-                            春季优惠券
-                        </div>
-                        <div class="description">
-                            满20减5
-                        </div>
-                    </div>
-                    <div class="col-md-3 right">
-                        永久有效
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="col-md-6 coupon-wrapper">
-            <div class="coupon">
-                <div class="content">
-                    <div class="col-md-9 left">
-                        <div class="name">
-                            春季优惠券
-                        </div>
-                        <div class="description">
-                            满20减5
-                        </div>
-                    </div>
-                    <div class="col-md-3 right">
-                        永久有效
-                    </div>
-                </div>
+            <div class="coupon" id="coupon-list">
             </div>
         </div>
     </div>
@@ -154,29 +110,30 @@
     <div class="modal-dialog" role="document">
         <div class="modal-content">
             <div class="modal-header">
-                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
+                </button>
                 <h4 class="modal-title" id="myModalLabel">购买会员卡</h4>
             </div>
-            <div class="modal-body">
+            <div class="modal-body" id="userMember-form">
                 <div class="form-group">
-                    <label for="userMember-cardNum">银行卡号</label>
+                    <label for="userMember-cardNum"><span class="error-text">*</span>银行卡号</label>
                     <input class="form-control" id="userMember-cardNum" placeholder="请输入银行卡号">
                     <p id="userMember-cardNum-error" class="notice">银行卡号不能为空</p>
                 </div>
                 <div class="form-group">
-                    <label for="userMember-cardPwd">密码</label>
+                    <label for="userMember-cardPwd"><span class="error-text">*</span>密码</label>
                     <input type="password" class="form-control" id="userMember-cardPwd" placeholder="请输入密码">
                     <p id="userMember-cardPwd-error" class="notice">密码不能为空</p>
                 </div>
-                <div class="form-group">
-                    <label for="userMember-amount">金额</label>
+                <div class="form-group" id="userMember-amount-group">
+                    <label for="userMember-amount"><span class="error-text">*</span>金额</label>
                     <input type="number" class="form-control" id="userMember-amount" placeholder="请输入充值金额">
                     <p id="userMember-amount-error" class="notice">充值金额需要大于0元</p>
                 </div>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
-                <button type="button" class="btn btn-primary">确定</button>
+                <button type="button" class="btn btn-primary" onclick="confirmCommit()">确定</button>
             </div>
         </div>
     </div>

+ 136 - 16
src/main/resources/templates/userMovieBuy.html

@@ -41,40 +41,160 @@
         </ul>
     </div>
 </div>
+
 <div class="content-container">
     <div class="card col-md-12">
-        <div class="col-md-10 col-md-offset-1">
-            <ol class="breadcrumb">
-                <li><a href="#" class="active">选座</a></li>
-                <li>确认订单,支付</li>
-                <li>支付成功</li>
+        <div class="col-md-10 col-md-offset-1" id="seat-state">
+            <ol class="breadcrumb col-md-12">
+                <li class="col-md-4"><a href="#" class="active">1. 选座</a></li>
+                <li class="col-md-4">2. 确认订单,支付</li>
+                <li class="col-md-4">3. 支付成功</li>
             </ol>
 
-            <div class="seat-content">
-                <div class="hall content-card card" id="hall-card">
+            <div class="seat-content col-md-12">
+                <div class="col-md-8 content-card card" id="hall-card">
                 </div>
 
-                <div class="movie-detail">
-                    <div class="head">
-                        <div class="img-wrapper">
+                <div class="col-md-4 movie-detail">
+                    <div class="line">
+                        <div class="name img-wrapper">
                             <img id="movie-img">
                         </div>
                         <div class="info">
                             <div id="movie-name"></div>
-                            <div>版本:国语版3D</div>
-                            <div>片长:137分钟</div>
+                            <div>语言:<span id="movie-language"></span></div>
+                            <div>类型:<span id="movie-type"></span></div>
+                            <div>片长:<span id="movie-length"></span>分钟</div>
                         </div>
                     </div>
                     <hr/>
-                    <div>影厅:1号厅</div>
-                    <div>场次:4月17日 14:00场</div>
-                    <div>座位:还未选择座位</div>
+                    <div class="line">
+                        <div class="name">影厅:</div>
+                        <div id="schedule-hall-name"></div>
+                    </div>
+                    <div class="line">
+                        <div class="name">场次:</div>
+                        <div id="schedule-time"></div>
+                    </div>
+                    <div class="line">
+                        <div class="name">座位:</div>
+                        <div id="seat-detail">还未选择座位</div>
+                    </div>
                     <hr/>
-                    <button class="btn btn-primary" disabled="disabled">确认下单</button>
+                    <button id="order-confirm-btn" class="btn btn-primary" onclick="orderConfirmClick()"
+                            disabled="disabled">
+                        确认下单
+                    </button>
+                </div>
+            </div>
+        </div>
+
+        <div class="col-md-10 col-md-offset-1" id="order-state" style="display: none;">
+            <ol class="breadcrumb col-md-12">
+                <li class="col-md-4">1. 选座</li>
+                <li class="col-md-4"><a href="#" class="active">2. 确认订单,支付</a></li>
+                <li class="col-md-4">3. 支付成功</li>
+            </ol>
+
+            <table class="table table-striped table-bordered">
+                <thead>
+                <tr>
+                    <th>电影</th>
+                    <th>场次</th>
+                    <th>票数/座位</th>
+                    <th>单价(元)</th>
+                    <th>总价(元)</th>
+                </tr>
+                </thead>
+
+                <tbody>
+                <tr>
+                    <td>
+                        <div>夏目友人帐</div>
+                        <div>版本:国语3D</div>
+                    </td>
+                    <td>
+                        <div>1号厅</div>
+                        <div>4月18日 19:00</div>
+                    </td>
+                    <td>
+                        <div>3张</div>
+                        <div>1排1座</div>
+                        <div>1排2座</div>
+                        <div>1排3座</div>
+                    </td>
+                    <td>30.00</td>
+                    <td><b>90.00</b></td>
+                </tr>
+                </tbody>
+            </table>
+
+            <div class="order-info">
+                <div>
+                    优惠券:
+                    <select style="height: 30px;">
+                        <option>满50减5</option>
+                        <option>满100减15</option>
+                    </select>
+                </div>
+
+                <div class="">
+                    <div class="item">总金额: ¥90.00</div>
+                    <div class="item">优惠金额: ¥5.00</div>
+                </div>
+            </div>
+
+            <hr class="dashed-line"/>
+
+            <div class="order-footer">
+                <div class="item">实付款:<b> ¥85.00</b></div>
+                <button class="item btn btn-primary" data-toggle="modal" data-target="#buyModal">确认订单,立即支付</button>
+            </div>
+        </div>
+
+        <div class="col-md-10 col-md-offset-1" id="success-state" style="display: none;">
+            <ol class="breadcrumb col-md-12">
+                <li class="col-md-4">1. 选座</li>
+                <li class="col-md-4">2. 确认订单,支付</li>
+                <li class="col-md-4"><a href="#" class="active">3. 支付成功</a></li>
+            </ol>
+
+            <div class="success-notice" style="text-align: center">
+                <img src="/images/success.png"/>
+                <div class="hint">支付成功,至<a class="hint">“我的电影票”</a>页面查看</div>
             </div>
         </div>
     </div>
 </div>
+
+<div class="modal fade" id="buyModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
+                </button>
+                <h4 class="modal-title" id="myModalLabel">付款</h4>
+            </div>
+            <div class="modal-body">
+                <div class="form-group">
+                    <label for="userMember-cardNum">银行卡号</label>
+                    <input class="form-control" id="userMember-cardNum" placeholder="请输入银行卡号">
+                    <p id="userMember-cardNum-error" class="notice">银行卡号不能为空</p>
+                </div>
+                <div class="form-group">
+                    <label for="userMember-cardPwd">密码</label>
+                    <input type="password" class="form-control" id="userMember-cardPwd" placeholder="请输入密码">
+                    <p id="userMember-cardPwd-error" class="notice">密码不能为空</p>
+                </div>
+
+                <div><b>金额:</b>&nbsp;&nbsp;90元</div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
+                <button type="button" class="btn btn-primary" onclick="payConfirmClick()">确认支付</button>
+            </div>
+        </div>
+    </div>
 </div>
 </body>
 </html>

+ 23 - 30
src/main/resources/templates/userMovieDetail.html

@@ -20,6 +20,7 @@
     <script src="/js/bootstrap.js"></script>
     <script src="/js/request.js"></script>
     <script src="/js/movieDetail.js"></script>
+    <script src="/js/userMovieDetail.js"></script>
 </head>
 <body>
 <div class="nav-top-container">
@@ -61,38 +62,30 @@
         </div>
     </div>
     <div class="seesion-container">
-        <!--<h1>暂无排片</h1>-->
-        <ul class="nav nav-tabs">
-            <li role="presentation" class="active"><a href="#">4月17日(今天)</a></li>
-            <li role="presentation"><a href="#">4月18日</a></li>
-            <li role="presentation"><a href="#">4月19日</a></li>
-            <li role="presentation"><a href="#">4月20日</a></li>
-        </ul>
+        <h1 id="none-hint" style="display: none;">暂无排片</h1>
+        <div id="schedule" style="display: none;">
+            <ul class="nav nav-tabs" id="schedule-date">
+            </ul>
 
-        <div class="table-wrapper">
-            <table class="table table-striped">
-                <thead>
-                <tr>
-                    <th>放映开始时间</th>
-                    <th>放映结束时间</th>
-                    <th>版本</th>
-                    <th>放映厅</th>
-                    <th>票价(元)</th>
-                    <th>选座购票</th>
-                </tr>
-                </thead>
+            <div class="table-wrapper">
+                <table class="table table-striped">
+                    <thead>
+                    <tr>
+                        <th>放映开始时间</th>
+                        <th>放映结束时间</th>
+                        <th>放映厅</th>
+                        <th>票价(元)</th>
+                        <th>选座购票</th>
+                    </tr>
+                    </thead>
 
-                <tbody>
-                <tr>
-                    <td>14:00</td>
-                    <td>预计15:35散场</td>
-                    <td>国语3D</td>
-                    <td>1号厅</td>
-                    <td><b>31.00</b></td>
-                    <td><a class="btn btn-primary" href="/user/movieDetail/buy?id=10" role="button">选座购票</a></td>
-                </tr>
-                </tbody>
-            </table>
+                    <tbody id="schedule-body">
+                    <tr>
+                    </tr>
+                    </tbody>
+                </table>
+                <h4 id="date-none-hint" style="display: none;">所选日期暂无排片</h4>
+            </div>
         </div>
     </div>
 </div>

+ 7 - 0
src/test/java/com/example/cinema/bl/ScheduleServiceImplTest.java

@@ -8,6 +8,7 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 
 import java.util.Arrays;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -35,4 +36,10 @@ public class ScheduleServiceImplTest {
 //        scheduleBatchDeleteForm.setScheduleIdList(Arrays.asList(20,21,31,26,27,28,29,30));
 //        scheduleService.deleteBatchOfSchedule(scheduleBatchDeleteForm);
 //    }
+
+//    @Test
+//    public void searchAudienceSchedule(){
+//        Date date = new Date();
+//        scheduleService.searchAudienceSchedule(10,date);
+//    }
 }

+ 26 - 0
src/test/java/com/example/cinema/blImpl/ScheduleServiceImplTest.java

@@ -0,0 +1,26 @@
+package com.example.cinema.blImpl;
+
+import com.example.cinema.bl.ScheduleService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.junit.Assert.*;
+
+/**
+ * @author fjj
+ * @date 2019/4/21 12:08 AM
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ScheduleServiceImplTest {
+
+    @Autowired
+    private ScheduleService scheduleService;
+    @Test
+    public void searchAudienceSchedule() {
+        scheduleService.searchAudienceSchedule(16);
+    }
+}

+ 5 - 5
src/test/java/com/example/cinema/blImpl/StatisticsServiceImplTest.java

@@ -22,11 +22,11 @@ import static org.junit.Assert.*;
 public class StatisticsServiceImplTest {
     @Autowired
     private StatisticsService statisticsService;
-//    @Test
-//    public void getScheduleRateByDate() throws ParseException {
-//        System.out.println(getNumDayBeforeDate(new Date(),-5));
-//        statisticsService.getScheduleRateByDate(getNumDayBeforeDate(new Date(),-5));
-//    }
+    @Test
+    public void getScheduleRateByDate() throws ParseException {
+        System.out.println(getNumDayBeforeDate(new Date(),-5));
+        statisticsService.getScheduleRateByDate(getNumDayBeforeDate(new Date(),-5));
+    }
 
     /**
      * 获得num天后的日期