def delete(self): """ Train line disable API, **JWT required** The body should be a JSON dictionary including the following attribute(s): **return**: A JSON dictionary with values: - `code`: `int`, equals to 0 if deletion is successful - `error`: `str`, shown if `code != 0` - `result`: `str`, shown if `code == 0` """ session = DBSession() try: body = request.get_json() train_name = body.get('train_name') train = session.query(Train).filter( Train.train_name == train_name, Train.available == True).first() if not train: return jsonify(code=12, error='停用失败,线路不存在或已停用') interval_list = session.query(Interval).filter( Interval.train_id == train.train_id, Interval.available == True).all() for interval in interval_list: interval.available = False train.available = False session.commit() return jsonify(code=0, result='线路停用成功') except: traceback.print_exc() session.rollback() return jsonify(code=12, error='停用失败,请联系运维人员') finally: session.close()
def post(self): """ Sign-up API The body should be a JSON dictionary including the following attribute(s): - `username`: `str` - `real_name`: `str` - `password`: `str` - `id_card`: `str` - `phone_number`: `str` - `email`: `str` **return**: A JSON dictionary with values: - `code`: `int`, equals to 0 if sign-up is successful - `error`: `str`, shown if `code != 0` """ session = DBSession() try: body = request.get_json() if session.query(User).filter( User.username == body.get('username')).first() is not None: return jsonify(error='Username already exists', code=406) new_user = User(**body) new_user.hash_password() session.add(new_user) session.commit() return jsonify(code=0) except: session.rollback() return jsonify(code=10, error='Unexpected error when creating user') finally: session.close()
def get(self): """ Payment API **argument**: - `order_id`: `int` **return**: `Purchase succeeded` or `Purchase failed` or `Already paid` """ session = DBSession() try: order_id = request.args.get('order_id') current_order: Order = session.query(Order).filter( Order.order_id == order_id).first() if current_order.order_status == "paid": return "Already paid" current_order.order_status = "paid" session.commit() session.flush() current_ticket: Ticket = session.query(Ticket).filter( Ticket.ticket_id == current_order.ticket_id).first() current_ticket.available = True session.commit() session.flush() return "Purchase succeeded" except: session.rollback() return "Purchase failed" finally: session.close()
def patch(self): """ Station modification API, **JWT required** The body should be a JSON dictionary including the following attribute(s): - `city_name`: `str` - `district_name`: `str` - `station_name`: `str` - `new_station_name`: `str` **return**: A JSON dictionary with values - `code`: `int`, equals to 0 if modification is successful - `result`: `str` for success message, shown if `code == 0` - `error`: `str`, shown if `code != 0` """ session = DBSession() try: body = request.get_json() city_name = body.get('city_name') district_name = body.get('district_name') station_name = body.get('station_name') new_station_name = body.get('new_station_name') current_station: Station = session.query(Station).filter( Station.station_name == station_name, Station.available == True).first() if not current_station: return jsonify(code=1, error="站点不存在") district = session.query(District).filter( District.district_name == district_name).first() if not district: city = session.query(City).filter( City.city_name == city_name).first() new_district = District(district_name=district_name, city_id=city.city_id) session.add(new_district) session.commit() district = session.query(District).filter( District.district_name == district_name).first() current_station.district_id = district.district_id if new_station_name: current_station.station_name = new_station_name session.commit() return jsonify(code=0, result="修改成功") except: session.rollback() return jsonify(code=1, error='修改失败') finally: session.close()
def patch(self): """ User information update API, **JWT required** The body should be a JSON dictionary including the following attribute(s): - `username`: `str` - `password`: `str` - `real_name`: `str` - `email`: `str` - `phone_number`: `str` **return**: A JSON dictionary with values: - `code`: `int`, equals to 0 if update is successful - `error`: `str`, shown if `code != 0` - `result`: `str`, shown if `code == 0` """ session = DBSession() try: body = request.get_json() user_id = get_jwt_identity() user = session.query(User).filter(User.user_id == user_id).first() if user is None: return jsonify(error='User not found', code=404) if user.username != body.get('username'): new_username = body.get('username') if session.query(User).filter( User.username == new_username).first() is not None: return jsonify(error='Username already exists', code=406) user.username = new_username user.real_name = body.get('real_name') user.email = body.get('email') user.phone_number = body.get('phone_number') new_password = body.get('password') if new_password: if 8 <= len(new_password) <= 30: user.password = new_password user.hash_password() else: session.rollback() return jsonify(code=1, error='密码长度错误') session.commit() return jsonify(code=0, result='用户信息修改成功') except: session.rollback() return jsonify(code=10, error='Update failed') finally: session.close()
def patch(self): """ Train line price information update API for administrator, **JWT required** The body should be a JSON dictionary including the following attribute(s): - `interval_id`: `int` - `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` **return**: A JSON dictionary with values: - `code`: `int`, equals to 0 if update is successful - `error`: `str`, shown if `code != 0` - `result`: `str`, shown if `code == 0` """ session = DBSession() try: body = request.get_json() for raw_id, raw_price in body.get('price').items(): seat_type_id = int(raw_id[-1]) obj_price: Price = session.query(Price) \ .filter(Price.interval_id == body.get('interval_id'), Price.seat_type_id == seat_type_id) \ .first() if obj_price: price = float(raw_price) if price > 0: obj_price.price = price else: raise Exception('') session.commit() return jsonify(code=0, result='修改成功') except: session.rollback() traceback.print_exc() return jsonify(code=10, error='修改失败') finally: session.close()
def delete(self): """ Station deletion API, **JWT required** The body should be a JSON dictionary including the following attribute(s): - `station_name`: `str` **return**: A JSON dictionary with values - `code`: `int`, equals to 0 if deletion is successful - `result`: `str` for success message, shown if `code == 0` - `error`: `str`, shown if `code != 0` """ session = DBSession() try: body = request.get_json() station_name = body.get('station_name') # Find if the station exists station: Station = session.query(Station).filter( Station.station_name == station_name, Station.available == True).first() if not station: return jsonify(code=1, error="站点不存在或已删除") # Check if the station has train passing interval = session.query(Interval).filter( or_(Interval.dep_station == station.station_id, Interval.arv_station == station.station_id)).first() if interval: return jsonify(code=2, error="站点仍有火车经过") station.available = False session.commit() return jsonify(code=0, result="删除成功") except: session.rollback() return jsonify(code=10, error='操作失败,请联系运维人员') finally: session.close()
break dep_t = time(int(interval_info[2][0:2]), int(interval_info[2][3:5])) arv_t = time(int(interval_info[4][0:2]), int(interval_info[4][3:5])) info = { "train_id": train.train_id, "dep_station": dep_s.station_id, "arv_station": arv_s.station_id, "dep_datetime": dep_t, "arv_datetime": arv_t } new_interval = Interval(**info) session.add(new_interval) session.commit() session.flush() interval_id = new_interval.interval_id interval_id_list.append(interval_id) # Add Price seat_type_id = 1 for price in interval_info[6:]: if price != '-': price_obj = Price(interval_id=interval_id, seat_type_id=seat_type_id, price=float(price)) session.add(price_obj) session.commit() seat_type_id += 1 for inv_i, interval_id in enumerate(interval_id_list): interval = session.query(Interval).filter(Interval.interval_id == interval_id).first()
def post(self): """ Train line creation API, **JWT required** The body should be a JSON dictionary including the following attribute(s): - `train_name`: `str` - `line`: `list` of dictionaries containing: - `dep_station`: `str` - `arv_station`: `str` - `dep_time`: `str` - `arv_time`: `str` - `price`: `dict` containing at least one of: - `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` **return**: A JSON dictionary with values: - `code`: `int`, equals to 0 if creation is successful - `error`: `str`, shown if `code != 0` - `result`: `str`, shown if `code == 0` """ session = DBSession() try: body = request.get_json() train_name = body.get('train_name') if not train_name: return jsonify(code=11, error='火车名为空') train: Train = session.query(Train).filter( Train.train_name == train_name).first() if train: return jsonify(code=11, error='火车名已存在!') new_train = Train(train_name=train_name) session.add(new_train) session.commit() session.flush() train_id = new_train.train_id interval_id_list = [] interval_list = body.get('line') seat_type_list = [] for interval_info in interval_list: dep_station = session.query(Station.station_id) \ .filter(Station.station_name == interval_info['dep_station'], Station.available == True) \ .first() \ .station_id arv_station = session.query(Station.station_id) \ .filter(Station.station_name == interval_info['arv_station'], Station.available == True) \ .first() \ .station_id dep_datetime = None arv_datetime = None if 'dep_time' in interval_info.keys( ) and interval_info['dep_time']: dep_datetime = time( *list(map(int, interval_info['dep_time'].split(':')))) if 'arv_time' in interval_info.keys( ) and interval_info['arv_time']: arv_datetime = time( *list(map(int, interval_info['arv_time'].split(':')))) new_interval = Interval(train_id=train_id, dep_station=dep_station, arv_station=arv_station, dep_datetime=dep_datetime, arv_datetime=arv_datetime) session.add(new_interval) session.commit() session.flush() interval_id = new_interval.interval_id interval_id_list.append(interval_id) price_dict = interval_info['price'] for k, v in price_dict.items(): seat_type_id = int(k[-1]) if seat_type_id not in seat_type_list: seat_type_list.append(seat_type_id) if not v: continue seat_price = max(0.01, abs(float(v))) new_price = Price(interval_id=interval_id, seat_type_id=seat_type_id, price=seat_price) session.add(new_price) session.commit() session.execute(func.add_seats(seat_type_list, train_id)) for index, interval_id in enumerate(interval_id_list): interval = session.query(Interval).filter( Interval.interval_id == interval_id).first() interval.next_id = interval_id_list[ index + 1] if index < len(interval_id_list) - 1 else None interval.prev_id = interval_id_list[index - 1] if index > 0 else None session.commit() return jsonify(code=0, result='线路添加成功') except: traceback.print_exc() session.rollback() return jsonify(code=12, error='添加失败,请检查输入是否合法') finally: session.close()
def post(self): """ Station addition API, **JWT required** The body should be a JSON dictionary including the following attribute(s): - `province_name`: `str` - `city_name`: `str` - `district_name`: `str` - `station_name`: `str` **return**: A JSON dictionary with values - `code`: `int`, equals to 0 if addition is successful - `result`: `str` for success message, shown if `code == 0` - `error`: `str`, shown if `code != 0` """ session = DBSession() try: body = request.get_json() province_name = body.get('province_name') city_name = body.get('city_name') district_name = body.get('district_name') station_name = body.get('station_name') station = session.query(Station) \ .filter(Station.station_name == station_name) \ .first() exist_flag = False if station: if station.available: return jsonify(code=1, error="站点已存在!") else: district = session.query(District) \ .filter(District.district_id == station.district_id) \ .first() if district.district_name == district_name: station.available = True session.commit() return jsonify(code=0, result='站点{}添加成功'.format(station_name)) exist_flag = True province = session.query(Province).filter( Province.province_name == province_name).first() if province is None: new_province = Province(province_name=province_name) session.add(new_province) session.commit() province = session.query(Province).filter( Province.province_name == province_name).first() city = session.query(City).filter( City.city_name == city_name).first() if city is None: new_city = City(city_name=city_name, province_id=province.province_id) session.add(new_city) session.commit() city = session.query(City).filter( City.city_name == city_name).first() district = session.query(District).filter( District.district_name == district_name).first() if district is None: new_district = District(district_name=district_name, city_id=city.city_id) session.add(new_district) session.commit() district = session.query(District).filter( District.district_name == district_name).first() if exist_flag: station.district_id = district.district_id station.available = True else: station = Station(station_name=station_name, district_id=district.district_id) session.add(station) session.commit() return jsonify(code=0, result='站点{}添加成功'.format(station_name)) except: traceback.print_exc() session.rollback() return jsonify(code=1, error='添加失败,站点已存在或地址信息有误。') finally: session.close()
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()
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()