Пример #1
0
    def get(self):
        """
        Available tickets query API

        **return**: A JSON dictionary with values:
        - `code`: `int`, always equals to 0
        - `result`: `list` of dictionaries of ticket information:
            - `seat_type_id`: `int`
            - `seat_type_name`: `str`
            - `left_cnt`: `int`
            - `price`: `float`
        """
        session = DBSession()
        try:
            train_name = urllib.parse.unquote(request.args.get('train_name'))
            first_interval = int(
                urllib.parse.unquote(request.args.get('first_interval')))
            last_interval = int(
                urllib.parse.unquote(request.args.get('last_interval')))
            interval_list = get_interval_list(train_name, session)
            first_index = session.query(interval_list.c.interval_no) \
                .filter(interval_list.c.interval_id == first_interval) \
                .first() \
                .interval_no
            last_index = session.query(interval_list.c.interval_no) \
                .filter(interval_list.c.interval_id == last_interval) \
                .first() \
                .interval_no
            price_list = session.query(Price.seat_type_id, func.sum(Price.price).label('price')) \
                .join(interval_list, Price.interval_id == interval_list.c.interval_id) \
                .filter(interval_list.c.interval_no <= last_index, interval_list.c.interval_no >= first_index) \
                .group_by(Price.seat_type_id) \
                .subquery()
            seats_left = session.query(Seat.seat_type_id, SeatType.name, func.count().label('left_cnt')) \
                .join(SeatType, SeatType.seat_type_id == Seat.seat_type_id) \
                .join(Train, Train.train_id == Seat.train_id) \
                .filter(Train.train_name == train_name,
                        func.cast(func.substring(Seat.occupied, first_index, last_index - first_index + 1),
                                  BIGINT) == 0) \
                .group_by(Seat.seat_type_id, SeatType.name) \
                .subquery()
            resp = session.query(seats_left.c.seat_type_id, seats_left.c.name.label('seat_type_name'),
                                 seats_left.c.left_cnt, price_list.c.price) \
                .join(price_list, price_list.c.seat_type_id == seats_left.c.seat_type_id) \
                .all()
            resp = list(
                sorted(map(lambda x: dict(zip(x.keys(), x)), resp),
                       key=lambda x: x['seat_type_id']))
            return jsonify(result=resp, code=0)
        except:
            return jsonify(code=10, error='Query error')
        finally:
            session.close()
Пример #2
0
    def get(self):
        """
        Train information query API

        **argument**:
        - `train_name`: `str`

        **return**: A JSON dictionary with values:
        - `code`: `int`, always equals to 0
        - `result`: `list` of dictionaries of passing station information:
            - `id`: `int`
            - `district`: `str`
            - `station`: `str`
            - `time`: `str`
        """
        session = DBSession()
        try:
            train_name = request.args.get('train_name')
            successive_train_rec = get_interval_list(train_name, session)
            interval_list = session.query(successive_train_rec.c.interval_no.label('id'),
                                          City.city_name.concat(',').concat(District.district_name).label('district'),
                                          Station.station_name.label('station'),
                                          func.cast(successive_train_rec.c.dep_datetime, String).label('time')) \
                .join(Station, Station.station_id == successive_train_rec.c.dep_station) \
                .join(District, Station.district_id == District.district_id) \
                .join(City, District.city_id == City.city_id) \
                .order_by(successive_train_rec.c.interval_id, Station.available == True) \
                .all()

            last_no = interval_list[-1].id
            resp = list(map(lambda x: dict(zip(x.keys(), x)), interval_list))
            last_station = session.query(func.cast(successive_train_rec.c.arv_datetime, String).label('time'),
                                         City.city_name.concat(',').concat(District.district_name).label('district'),
                                         Station.station_name.label('station'),
                                         literal(last_no + 1).label('id')) \
                .join(Station, Station.station_id == successive_train_rec.c.arv_station) \
                .join(District, Station.district_id == District.district_id) \
                .join(City, District.city_id == City.city_id) \
                .filter(successive_train_rec.c.interval_no == last_no, Station.available == True) \
                .first()
            if last_station:
                resp.append(dict(zip(last_station.keys(), last_station)))
            return jsonify(result=resp, code=0)
        except:
            return jsonify(code=10, error='未找到线路')
        finally:
            session.close()
Пример #3
0
    def get(self):
        """
        Train line information query API for administrator, **JWT required**

        **argument**:
        - `train_name`: `str`

        **return**: A JSON dictionary with values:
        - `code`: `int`, equals to 0 if query is successful
        - `error`: `str`, shown if `code != 0`
        - `result`: `dict` containing:
            - `available`: `boolean`
            - `line`: `list` of dictionaries of interval information:
                - `interval_id`: `int`
                - `interval_no`: `int`
                - `train_name`: `str`
                - `dep_station`: `str`
                - `arv_station`: `str`
                - `dep_datetime`: `str`
                - `arv_datetime`: `str`
                - `price`: `dict` containing:
                    - `seat_type_1`, `str`
                    - `seat_type_2`, `str`
                    - `seat_type_3`, `str`
                    - `seat_type_4`, `str`
                    - `seat_type_5`, `str`
                    - `seat_type_6`, `str`
                    - `seat_type_7`, `str`
        """
        session = DBSession()
        try:
            train_name = request.args.get('train_name')
            interval_list = get_interval_list(train_name, session, True)
            available = session.query(Train.available).filter(
                Train.train_name == train_name).first().available
            dep_s = aliased(Station, name='dep_s')
            arv_s = aliased(Station, name='arv_s')
            res_list = session.query(interval_list.c.interval_id, interval_list.c.interval_no, Train.train_name,
                                     dep_s.station_name.label('dep_station'), arv_s.station_name.label('arv_station'),
                                     func.cast(interval_list.c.dep_datetime, String).label('dep_datetime'),
                                     func.cast(interval_list.c.arv_datetime, String).label('arv_datetime'), ) \
                .join(Train, Train.train_id == interval_list.c.train_id) \
                .join(dep_s, dep_s.station_id == interval_list.c.dep_station) \
                .join(arv_s, arv_s.station_id == interval_list.c.arv_station) \
                .order_by(interval_list.c.interval_no) \
                .all()
            res_list = list(map(lambda x: dict(zip(x.keys(), x)), res_list))
            for i in res_list:
                i['price'] = dict(
                    zip(map(lambda x: 'seat_type_' + str(x), range(1, 8)),
                        ['x'] * 7))
                price_list = session.query(Price).filter(
                    Price.interval_id == i['interval_id']).all()
                i['price'].update(
                    dict(
                        map(
                            lambda x: ('seat_type_{}'.format(x.seat_type_id),
                                       '{:.2f}'.format(x.price)), price_list)))
            return jsonify(code=0,
                           result={
                               'line': res_list,
                               'available': available
                           })
        except:
            traceback.print_exc()
            return jsonify(code=10, error='Query error')
        finally:
            session.close()
Пример #4
0
    def delete(self):
        """
        Ticket refund API, **JWT required**

        **return**: A JSON dictionary with values:
        - `code`: `int`, equals to 0 if deletion is successful
        - `result`: `str`, shown if `code == 0`
        - `error`: `str`, shown if `code != 0`
        """
        session = DBSession()
        try:
            user_id = get_jwt_identity()
            body = request.get_json()
            order_id = body.get('order_id')
            # The delete function is to set the order status "cancelled", set ticket available false,
            # and released the occupied seat.
            current_order: Order = session.query(Order).filter(
                Order.order_id == order_id).first()
            # print(current_order.user_id, user_id)
            if int(user_id) != int(current_order.user_id):
                return jsonify(code=100, error='非法退票操作!')
            current_order.order_status = "cancelled"
            session.commit()
            session.flush()
            current_ticket: Ticket = session.query(Ticket).filter(
                Ticket.ticket_id == current_order.ticket_id).first()
            current_ticket.available = False
            session.commit()
            session.flush()
            first_interval = current_ticket.first_interval
            last_interval = current_ticket.last_interval
            current_seat: Seat = session.query(Seat).filter(
                Seat.seat_id == current_ticket.seat_id).first()
            train_id = session.query(Train.train_id).join(
                Interval, Interval.train_id == Train.train_id).filter(
                    Interval.interval_id == first_interval,
                    Interval.available == True,
                    Train.available == True).first()

            # Here to release the seat
            train_name = session.query(Train.train_name).filter(
                Train.train_id == train_id,
                Train.available == True).first().train_name
            interval_list = get_interval_list(train_name, session)
            # successive_train_rec = get_interval_list(train_name, session)
            # interval_list = session.query(successive_train_rec.c.interval_id) \
            #     .order_by(successive_train_rec.c.interval_id) \
            #     .all()
            first_index = session.query(interval_list.c.interval_no) \
                .filter(interval_list.c.interval_id == first_interval) \
                .first() \
                .interval_no
            last_index = session.query(interval_list.c.interval_no) \
                .filter(interval_list.c.interval_id == last_interval) \
                .first() \
                .interval_no
            current_seat.occupied = bin(
                int(current_seat.occupied, 2)
                & int('0' * (last_index - first_index + 1), 2) <<
                (40 - last_index))[2:].zfill(40)
            session.commit()
            session.flush()
            return jsonify(code=0, result="操作成功,票已失效")
        except:
            session.rollback()
            return jsonify(code=10, error='操作失败,请联系管理员')
        finally:
            session.close()
Пример #5
0
    def post(self):
        """
        Train order API, **JWT required**

        **return**: A JSON dictionary with values:
        - `code`: `int`, equals to 0 if order is successful
        - `result`: `dict` with values, shown if `code == 0`:
            - `order_id`: `int`
        - `error`: `str`, shown if `code != 0`
        """
        session = DBSession()
        try:
            user_id = get_jwt_identity()
            body = request.get_json()
            first_interval = int(body.get('first_interval'))
            last_interval = int(body.get('last_interval'))
            seat_class = body.get('seat_class')
            train_name = body.get('train_name')
            # successive_train_rec = get_interval_list(train_name, session)
            interval_list = get_interval_list(train_name, session)
            # interval_list = session.query(successive_train_rec.c.interval_id) \
            #     .order_by(successive_train_rec.c.interval_id) \
            #     .all()
            first_index = session.query(interval_list.c.interval_no) \
                .filter(interval_list.c.interval_id == first_interval) \
                .first() \
                .interval_no
            last_index = session.query(interval_list.c.interval_no) \
                .filter(interval_list.c.interval_id == last_interval) \
                .first() \
                .interval_no
            seat = session.query(Seat) \
                .join(Train, Train.train_id == Seat.train_id) \
                .filter(Train.train_name == train_name,
                        Seat.seat_type_id == seat_class,
                        func.cast(func.substring(Seat.occupied, first_index, last_index - first_index + 1),
                                  BIGINT) == 0) \
                .first()
            if seat is None:
                return jsonify(code=404, error='当前区间无余票!')
            seat.occupied = bin(
                int(seat.occupied, 2)
                | int('1' * (last_index - first_index + 1), 2) <<
                (40 - last_index))[2:].zfill(40)
            new_ticket = Ticket(first_interval=first_interval,
                                last_interval=last_interval,
                                seat_id=seat.seat_id,
                                available=False)
            session.add(new_ticket)
            session.commit()
            session.flush()
            price = session.query(func.sum(Price.price).label('price')) \
                .join(interval_list, Price.interval_id == interval_list.c.interval_id) \
                .filter(Price.seat_type_id == seat_class, interval_list.c.interval_no <= last_index,
                        interval_list.c.interval_no >= first_index) \
                .first()
            new_order = Order(order_status='unpaid',
                              user_id=user_id,
                              ticket_id=new_ticket.ticket_id,
                              price=price)
            session.add(new_order)
            session.commit()
            session.flush()
            return jsonify(code=0, result={'order_id': new_order.order_id})
        except:
            session.rollback()
            return jsonify(code=10, error='订票失败')
        finally:
            session.close()