Compare commits
No commits in common. 'master' and 'main' have entirely different histories.
@ -1,3 +0,0 @@
|
||||
.idea
|
||||
__pycache__/
|
||||
*.log
|
||||
@ -1,7 +0,0 @@
|
||||
FROM python:3.12.4-slim
|
||||
WORKDIR /app
|
||||
COPY requirements.txt requirements.txt
|
||||
RUN pip config set global.index-url http://mirrors.aliyun.com/pypi/simple && pip config set install.trusted-host mirrors.aliyun.com
|
||||
RUN pip install -r requirements.txt
|
||||
COPY . ./
|
||||
CMD ["gunicorn", "-w", "4", "--bind", "0.0.0.0:3002", "myapp:app" ]
|
||||
@ -1 +0,0 @@
|
||||
Subproject commit 50b2c113694b3c40ed3aea797ce341532d5bebd7
|
||||
@ -1,25 +0,0 @@
|
||||
from flask import request
|
||||
from loguru import logger
|
||||
|
||||
|
||||
class LogService:
|
||||
@staticmethod
|
||||
def configure_logging():
|
||||
logger.remove() # 移除默认的日志配置
|
||||
logger.add(
|
||||
"logs/app.log", # 日志文件名
|
||||
rotation="1 week", # 每周轮换
|
||||
retention="1 month", # 保留一个月
|
||||
level="INFO", # 记录 INFO 及以上级别的日志
|
||||
format="{time} - {level} - {message}", # 日志格式
|
||||
backtrace=True, # 打印完整的异常堆栈
|
||||
diagnose=True # 打印详细的异常信息
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def log():
|
||||
logger.info(f"Request Path: {request.path}")
|
||||
logger.info(f"Request Method: {request.method}")
|
||||
logger.info(f"Request Headers: {request.headers}")
|
||||
logger.info(f"Request args: {request.args}")
|
||||
logger.info(f"Request Body: {request.get_data(as_text=True)}")
|
||||
@ -1,25 +0,0 @@
|
||||
from flask import Blueprint, request, jsonify
|
||||
from flask_jwt_extended import create_access_token
|
||||
|
||||
from app import LogService
|
||||
from app.models import Passenger
|
||||
from presenter import PassengerPresenter
|
||||
from utils import StateCode, create_response
|
||||
|
||||
login_bp = Blueprint('login', __name__)
|
||||
|
||||
|
||||
@login_bp.route('/login', methods=['POST'])
|
||||
def login():
|
||||
data = request.json
|
||||
account = data.get('account')
|
||||
password = data.get('password')
|
||||
if not account or not password:
|
||||
return jsonify(create_response(StateCode.PARAMS_ERROR)), 400
|
||||
user = Passenger.verifyPassenger(account, password)
|
||||
if user:
|
||||
access_token = create_access_token(identity=user.id)
|
||||
user_presenter = PassengerPresenter(user, {"token": access_token}).as_dict()
|
||||
LogService.log()
|
||||
return jsonify(create_response(StateCode.SUCCESS, data=user_presenter)), 200
|
||||
return jsonify(create_response(StateCode.PASSWORD_INCORRECT)), 400
|
||||
@ -1,6 +0,0 @@
|
||||
from app import db
|
||||
from .order_lib import Order
|
||||
from .passenger_lib import Passenger
|
||||
from .station_lib import Station
|
||||
from .train_lib import Train
|
||||
|
||||
@ -1,103 +0,0 @@
|
||||
import pdb
|
||||
import random
|
||||
import time
|
||||
import uuid
|
||||
from datetime import timedelta, datetime
|
||||
|
||||
from sqlalchemy import func
|
||||
|
||||
from app.models import db
|
||||
from app.models.ticket_lib import Ticket
|
||||
from app.models.train_station_lib import TrainStation
|
||||
|
||||
|
||||
class Order(db.Model):
|
||||
__tablename__ = 'order'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
order_no = db.Column(db.String(120), unique=True, nullable=False)
|
||||
price = db.Column(db.Numeric(8, 2))
|
||||
payment_time = db.Column(db.DateTime)
|
||||
state = db.Column(db.Integer, default=0)
|
||||
passenger_id = db.Column(db.Integer, db.ForeignKey('passenger.id'), nullable=False, index=True)
|
||||
created_at = db.Column(db.DateTime, default=func.now())
|
||||
updated_at = db.Column(db.DateTime, default=func.now())
|
||||
|
||||
passenger = db.relationship('Passenger', backref=db.backref('orders'))
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Order {self.id}>'
|
||||
|
||||
@classmethod
|
||||
def setOrderState(cls, order_no, passenger_id, **kwargs):
|
||||
order = cls.query.filter_by(order_no=order_no, passenger_id=passenger_id).first()
|
||||
if order:
|
||||
# 更新订单的属性
|
||||
for key, value in kwargs.items():
|
||||
setattr(order, key, value)
|
||||
if key == 'state' and value == 1:
|
||||
for ticket in order.tickets:
|
||||
Ticket.updateState(ticket) # Update state to 1
|
||||
# 提交更改到数据库
|
||||
db.session.commit()
|
||||
return order
|
||||
else:
|
||||
# 处理订单未找到的情况
|
||||
return None
|
||||
|
||||
|
||||
def generate_unique_id(length=4):
|
||||
# 获取当前的秒级时间戳
|
||||
timestamp_seconds = int(time.time())
|
||||
|
||||
# 生成 4 位随机数
|
||||
random_number = random.randint(0, 10 ** length - 1)
|
||||
|
||||
# 确保随机数是 4 位数字
|
||||
random_number_str = str(random_number).zfill(length)
|
||||
|
||||
# 生成唯一标识符
|
||||
unique_id = f"{timestamp_seconds}{random_number_str}"
|
||||
return unique_id
|
||||
|
||||
|
||||
def generateOrder(params, passenger_id):
|
||||
# Create a new Order object
|
||||
order = Order(
|
||||
order_no=generate_unique_id(5),
|
||||
passenger_id=passenger_id
|
||||
)
|
||||
|
||||
for e in params['tickets']:
|
||||
# 创建Ticket对象
|
||||
ticket = Ticket.generateTicket(e, passenger_id)
|
||||
# 计算起始站和终点站
|
||||
from_station = TrainStation.query.filter_by(train_no=ticket.train_no, station_name=ticket.from_station).one()
|
||||
to_station = TrainStation.query.filter_by(train_no=ticket.train_no, station_name=ticket.to_station).one()
|
||||
# 计算区间价格
|
||||
train_stations = TrainStation.query.filter(
|
||||
TrainStation.train_no == ticket.train_no,
|
||||
TrainStation.index.between(from_station.index, to_station.index)
|
||||
).all()
|
||||
ticket.price = sum(e.price for e in train_stations)
|
||||
# 计算座位号
|
||||
seat_count = db.session.query(func.count(Ticket.id)).filter_by(
|
||||
train_no=ticket.train_no,
|
||||
date=ticket.date
|
||||
).scalar()
|
||||
ticket.seat_no = seat_count + 1
|
||||
|
||||
# 转换时间 计算出发时间
|
||||
interval_days = (
|
||||
datetime.strptime(ticket.date, "%Y/%m/%d") - datetime.combine(from_station.departure_time.date(),
|
||||
datetime.min.time())).days
|
||||
ticket.departure_time = from_station.departure_time + timedelta(days=interval_days)
|
||||
ticket.arrival_time = to_station.arrival_time + timedelta(days=interval_days)
|
||||
|
||||
order.tickets.append(ticket)
|
||||
|
||||
order.price = sum(ticket.price for ticket in order.tickets)
|
||||
|
||||
return order
|
||||
|
||||
|
||||
@ -1,58 +0,0 @@
|
||||
from sqlalchemy import func
|
||||
|
||||
from app.models import db
|
||||
from werkzeug.security import generate_password_hash, check_password_hash
|
||||
|
||||
|
||||
def isAvailable(account):
|
||||
Passenger.query.filter_by(account=account).first()
|
||||
|
||||
|
||||
class Passenger(db.Model):
|
||||
__tablename__ = 'passenger'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(120))
|
||||
account = db.Column(db.String(120), unique=True, nullable=False, index=True)
|
||||
password_digest = db.Column(db.String(2000), nullable=False)
|
||||
id_card_no = db.Column(db.String(120))
|
||||
mobile_no = db.Column(db.String(120))
|
||||
bank_card_no = db.Column(db.String(120))
|
||||
state = db.Column(db.Integer, default=0)
|
||||
member_type = db.Column(db.Integer)
|
||||
last_login_time = db.Column(db.DateTime)
|
||||
created_at = db.Column(db.DateTime, default=func.now())
|
||||
updated_at = db.Column(db.DateTime, default=func.now())
|
||||
|
||||
def check_password(self, password):
|
||||
return check_password_hash(self.password_digest, password) # 验证密码
|
||||
|
||||
@classmethod
|
||||
def verifyPassenger(cls, account, password):
|
||||
passenger = cls.query.filter_by(account=account).first()
|
||||
if passenger and passenger.check_password(password):
|
||||
return passenger
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def create(cls, data):
|
||||
passenger = cls(
|
||||
account=data.get('account'),
|
||||
password_digest=generate_password_hash(data.get('password')),
|
||||
name=data.get('name'),
|
||||
id_card_no=data.get('idCardNo'),
|
||||
mobile_no=data.get('mobileNo'),
|
||||
bank_card_no=data.get('bankCard'),
|
||||
)
|
||||
db.session.add(passenger)
|
||||
db.session.commit()
|
||||
return passenger
|
||||
|
||||
@classmethod
|
||||
def destroy(cls, passenger_id):
|
||||
passenger = cls.query.get(passenger_id)
|
||||
if passenger:
|
||||
db.session.delete(passenger)
|
||||
db.session.commit()
|
||||
return True
|
||||
return False
|
||||
@ -1,45 +0,0 @@
|
||||
import pdb
|
||||
from datetime import datetime
|
||||
from pypinyin import pinyin, Style
|
||||
from sqlalchemy import func
|
||||
|
||||
from app.models import db
|
||||
|
||||
|
||||
class Station(db.Model):
|
||||
__tablename__: str = 'station'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(120), unique=True, nullable=False, index=True)
|
||||
pinyin = db.Column(db.String(120))
|
||||
province = db.Column(db.String(120))
|
||||
city = db.Column(db.String(120))
|
||||
district = db.Column(db.String(120))
|
||||
created_at = db.Column(db.DateTime, default=func.now())
|
||||
updated_at = db.Column(db.DateTime, default=func.now())
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Station {self.name}>'
|
||||
|
||||
@classmethod
|
||||
def create(cls, data):
|
||||
station = cls(
|
||||
name=data.get('name'),
|
||||
pinyin=''.join([item[0] for item in pinyin(data.get('name'), style=Style.NORMAL)]).upper(),
|
||||
province=data.get('province'),
|
||||
city=data.get('city'),
|
||||
created_at=datetime.now(),
|
||||
updated_at=datetime.now(),
|
||||
)
|
||||
db.session.add(station)
|
||||
db.session.commit()
|
||||
return station
|
||||
|
||||
@classmethod
|
||||
def destroy(cls, station_id):
|
||||
station = cls.query.get(station_id)
|
||||
if station:
|
||||
db.session.delete(station)
|
||||
db.session.commit()
|
||||
return True
|
||||
return False
|
||||
@ -1,45 +0,0 @@
|
||||
from sqlalchemy import func
|
||||
|
||||
from app.models import db
|
||||
|
||||
|
||||
class Ticket(db.Model):
|
||||
__tablename__: str = 'ticket'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
seat_no = db.Column(db.String(120))
|
||||
seat_class = db.Column(db.String(120))
|
||||
price = db.Column(db.Numeric(8, 2))
|
||||
state = db.Column(db.Integer, default=0)
|
||||
train_no = db.Column(db.String(120), db.ForeignKey('train.train_no'), nullable=False, index=True)
|
||||
passenger_id = db.Column(db.Integer, db.ForeignKey('passenger.id'), nullable=False, index=True)
|
||||
order_id = db.Column(db.Integer, db.ForeignKey('order.id'), nullable=False, index=True)
|
||||
from_station = db.Column(db.String(120))
|
||||
to_station = db.Column(db.String(120))
|
||||
date = db.Column(db.String(120))
|
||||
departure_time = db.Column(db.DateTime)
|
||||
arrival_time = db.Column(db.DateTime)
|
||||
created_at = db.Column(db.DateTime, default=func.now())
|
||||
updated_at = db.Column(db.DateTime, default=func.now())
|
||||
order = db.relationship('Order', backref=db.backref('tickets'))
|
||||
passenger = db.relationship('Passenger', backref=db.backref('tickets'))
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Ticket {self.id}>'
|
||||
|
||||
def updateState(self):
|
||||
self.state = 1
|
||||
return self
|
||||
|
||||
@classmethod
|
||||
def generateTicket(cls, item, passenger_id):
|
||||
# Create a new Ticket object
|
||||
ticket = Ticket(
|
||||
seat_class=item["seatClass"],
|
||||
train_no=item["trainNo"],
|
||||
from_station=item["from"],
|
||||
to_station=item["to"],
|
||||
date=item["date"],
|
||||
passenger_id=passenger_id
|
||||
)
|
||||
return ticket
|
||||
@ -1,91 +0,0 @@
|
||||
from sqlalchemy import func
|
||||
|
||||
from app.models import db
|
||||
from app.models.train_station_lib import TrainStation
|
||||
|
||||
class Train(db.Model):
|
||||
__tablename__: str = 'train'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
train_no = db.Column(db.String(120), unique=True, nullable=False, index=True)
|
||||
departure_station = db.Column(db.String(120))
|
||||
arrival_station = db.Column(db.String(120))
|
||||
departure_time = db.Column(db.DateTime)
|
||||
expiration_time = db.Column(db.DateTime)
|
||||
effective_time = db.Column(db.DateTime)
|
||||
arrival_time = db.Column(db.DateTime)
|
||||
created_at = db.Column(db.DateTime, default=func.now())
|
||||
updated_at = db.Column(db.DateTime, default=func.now())
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Train {self.id}>'
|
||||
|
||||
@classmethod
|
||||
def create(cls, new_train):
|
||||
db.session.add(new_train)
|
||||
db.session.commit()
|
||||
return new_train
|
||||
|
||||
@classmethod
|
||||
def queryTrains(cls, from_station, to_station, date):
|
||||
# Query for train stations where the station name matches `from_station`
|
||||
from_train = TrainStation.query.filter_by(station_name=from_station).all()
|
||||
|
||||
# Query for train stations where the station name matches `to_station`
|
||||
to_train = TrainStation.query.filter_by(station_name=to_station).all()
|
||||
|
||||
# Extract train_no from both query results
|
||||
from_train_nos = {ts.train_no for ts in from_train}
|
||||
to_train_nos = {ts.train_no for ts in to_train}
|
||||
|
||||
# Find the common train_no between the two stations
|
||||
common_train_nos = from_train_nos & to_train_nos
|
||||
|
||||
# Filter train numbers where the index of the from station is less than the index of the to station
|
||||
valid_train_nos = [
|
||||
train_no for train_no in common_train_nos
|
||||
if next(ts.index for ts in from_train if ts.train_no == train_no) <
|
||||
next(ts.index for ts in to_train if ts.train_no == train_no)
|
||||
]
|
||||
# Query trains by the filtered train numbers and the given date (assuming date filtering)
|
||||
trains = Train.query.filter(
|
||||
Train.effective_time >= date,
|
||||
Train.train_no.in_(valid_train_nos)
|
||||
).all()
|
||||
|
||||
# Assuming you have a presenter or serializer for the trains
|
||||
return trains
|
||||
|
||||
|
||||
def buildTrain(params):
|
||||
# Create a new Train object
|
||||
train = Train(
|
||||
train_no=params['trainNo'],
|
||||
effective_time=params['effective_time'],
|
||||
expiration_time=params['expiration_time']
|
||||
)
|
||||
|
||||
# Extract indexes for determining first and last station
|
||||
indexes = [e["index"] for e in params['stations']]
|
||||
|
||||
for e in params['stations']:
|
||||
# Create and associate TrainStation objects
|
||||
train_station = TrainStation(
|
||||
station_name=e["name"],
|
||||
price=e["price"],
|
||||
departure_time=e["depTime"],
|
||||
arrival_time=e["arrTime"],
|
||||
index=e["index"]
|
||||
)
|
||||
train.train_stations.append(train_station)
|
||||
# Determine the departure time and station for the first station
|
||||
if e["index"] == 0:
|
||||
train.departure_time = e["depTime"]
|
||||
train.departure_station = e["name"]
|
||||
|
||||
# Determine the arrival time and station for the last station
|
||||
if e["index"] == max(indexes):
|
||||
train.arrival_time = e["arrTime"]
|
||||
train.arrival_station = e["name"]
|
||||
|
||||
return train
|
||||
@ -1,21 +0,0 @@
|
||||
from sqlalchemy import func
|
||||
|
||||
from app.models import db
|
||||
|
||||
|
||||
class TrainStation(db.Model):
|
||||
__tablename__: str = 'train_station'
|
||||
|
||||
train_no = db.Column(db.String(120), db.ForeignKey('train.train_no'), primary_key=True, index=True)
|
||||
station_name = db.Column(db.String(120), db.ForeignKey('station.name'), primary_key=True)
|
||||
|
||||
price = db.Column(db.Numeric(8, 2))
|
||||
arrival_time = db.Column(db.DateTime)
|
||||
departure_time = db.Column(db.DateTime)
|
||||
index = db.Column(db.Integer, default=0)
|
||||
created_at = db.Column(db.DateTime, default=func.now())
|
||||
updated_at = db.Column(db.DateTime, default=func.now())
|
||||
|
||||
station = db.relationship('Station', backref=db.backref('train_stations'))
|
||||
train = db.relationship('Train', backref=db.backref('train_stations'))
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
from flask import Blueprint, request, jsonify
|
||||
from flask_jwt_extended import get_jwt_identity, jwt_required
|
||||
from app import db, LogService
|
||||
from app.models.order_lib import generateOrder, Order
|
||||
from presenter.order import OrderPresenter
|
||||
from utils import create_response, StateCode
|
||||
from utils.server import verifyOrderPayment
|
||||
|
||||
order_bp = Blueprint('order', __name__)
|
||||
|
||||
|
||||
@order_bp.route('/orders', methods=['POST'])
|
||||
@jwt_required()
|
||||
def createOrder():
|
||||
current_user = get_jwt_identity()
|
||||
data = request.json
|
||||
new_order = generateOrder(data, current_user)
|
||||
db.session.add(new_order)
|
||||
db.session.commit()
|
||||
order_presenter = OrderPresenter(new_order).as_dict()
|
||||
LogService.log()
|
||||
return jsonify(create_response(StateCode.SUCCESS, data=order_presenter)), 200
|
||||
|
||||
|
||||
@order_bp.route('/orders/<string:order_no>/query_payment', methods=['POST'])
|
||||
@jwt_required()
|
||||
def queryPayment(order_no):
|
||||
current_user = get_jwt_identity()
|
||||
response = verifyOrderPayment(order_no)
|
||||
if response.status_code == 200 and response.json().get("data")["state"] == "successful":
|
||||
order = Order.setOrderState(order_no, current_user,
|
||||
state=1, payment_time=response.json().get("data")["pay_time"])
|
||||
order_presenter = OrderPresenter(order).as_dict()
|
||||
LogService.log()
|
||||
return jsonify(create_response(StateCode.SUCCESS, data=order_presenter)), 200
|
||||
else:
|
||||
LogService.log()
|
||||
return jsonify(create_response(StateCode.ORDER_PAY_ERROR)), 400
|
||||
|
||||
|
||||
@order_bp.route('/orders', methods=['GET'])
|
||||
@jwt_required()
|
||||
def queryOrder():
|
||||
state = request.args.get("state")
|
||||
current_user = get_jwt_identity()
|
||||
orders = Order.query.filter(Order.passenger_id == current_user, Order.state == state).all()
|
||||
order_presenter = [OrderPresenter(order).as_dict() for order in orders]
|
||||
LogService.log()
|
||||
return jsonify(create_response(StateCode.SUCCESS, data=order_presenter)), 200
|
||||
@ -1,62 +0,0 @@
|
||||
from flask import Blueprint, request, jsonify
|
||||
from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity
|
||||
|
||||
from app import redis_client, LogService
|
||||
from app.models.passenger_lib import Passenger, isAvailable
|
||||
from presenter import PassengerPresenter
|
||||
from utils import StateCode, create_response, checkMobile, checkIdCard, checkBankCard
|
||||
|
||||
register_bp = Blueprint('register', __name__)
|
||||
|
||||
|
||||
@register_bp.route('/register', methods=['POST'])
|
||||
def register():
|
||||
data = request.json
|
||||
account = data.get('account')
|
||||
password = data.get('password')
|
||||
mobile_no = data.get('mobileNo')
|
||||
mobile_code = data.get('mobileCode')
|
||||
id_card_no = data.get('idCardNo')
|
||||
bank_card_no = data.get('bankCard')
|
||||
|
||||
if not account or not password:
|
||||
return jsonify(create_response(StateCode.PARAMS_ERROR)), 400
|
||||
|
||||
if not checkMobile(mobile_no):
|
||||
return jsonify(create_response(StateCode.MOBILE_ERROR)), 400
|
||||
|
||||
if not verifyCode(mobile_no, mobile_code):
|
||||
return jsonify(create_response(StateCode.MOBILE_CODE_ERROR)), 400
|
||||
|
||||
if not checkIdCard(id_card_no):
|
||||
return jsonify(create_response(StateCode.ID_CARD_ERROR)), 400
|
||||
|
||||
if isAvailable(account):
|
||||
return jsonify(create_response(StateCode.USER_ALREADY_EXISTS)), 400
|
||||
|
||||
if not checkBankCard(bank_card_no):
|
||||
return jsonify(create_response(StateCode.BANK_CARD_ERROR)), 400
|
||||
|
||||
new_passenger = Passenger.create(data=data)
|
||||
access_token = create_access_token(identity=new_passenger.id)
|
||||
user_presenter = PassengerPresenter(new_passenger, {"token": access_token}).as_dict()
|
||||
LogService.log()
|
||||
return jsonify(create_response(StateCode.SUCCESS, data=user_presenter)), 200
|
||||
|
||||
|
||||
@register_bp.route('/auth', methods=['GET'])
|
||||
@jwt_required()
|
||||
def auth():
|
||||
current_user = get_jwt_identity()
|
||||
user = Passenger.query.get(current_user)
|
||||
if not user:
|
||||
return jsonify(create_response(StateCode.USER_NOT_FOUND)), 400
|
||||
user_presenter = PassengerPresenter(user, {}).as_dict()
|
||||
LogService.log()
|
||||
|
||||
return jsonify(create_response(code=StateCode.SUCCESS, data=user_presenter)), 200
|
||||
|
||||
|
||||
def verifyCode(mobile_no, code):
|
||||
stored_code = redis_client.get(mobile_no)
|
||||
return stored_code == code
|
||||
@ -1,46 +0,0 @@
|
||||
import iso8601
|
||||
from flask import Blueprint, jsonify, request
|
||||
from flask_jwt_extended import get_jwt_identity, jwt_required
|
||||
|
||||
from app import LogService
|
||||
from app.models import Station
|
||||
from app.models.ticket_lib import Ticket
|
||||
from app.models.train_lib import Train
|
||||
from presenter import StationPresenter
|
||||
from presenter.ticket import TicketPresenter
|
||||
from presenter.train import TrainPresenter
|
||||
from utils import create_response, StateCode
|
||||
|
||||
query_bp = Blueprint('query', __name__)
|
||||
|
||||
|
||||
@query_bp.route('/trains/query_train', methods=['GET'])
|
||||
def queryTrains(): # 查询车次方法
|
||||
from_station = request.args.get('from')
|
||||
to_station = request.args.get('to')
|
||||
date = iso8601.parse_date(request.args.get('date'))
|
||||
if not from_station or not to_station or not date:
|
||||
return jsonify(create_response(StateCode.PARAMS_ERROR)), 400
|
||||
|
||||
trains = Train.queryTrains(from_station, to_station, date)
|
||||
trains_presenters = [TrainPresenter(train).as_dict() for train in trains]
|
||||
LogService.log()
|
||||
return jsonify(create_response(StateCode.SUCCESS, data=trains_presenters)), 200
|
||||
|
||||
|
||||
@query_bp.route('/tickets', methods=['GET'])
|
||||
@jwt_required()
|
||||
def getTickets(): # 查询车票方法
|
||||
current_user = get_jwt_identity() # 解码JWT得到用户ID
|
||||
tickets = Ticket.query.filter_by(passenger_id=current_user).all()
|
||||
tickets_presenters = [TicketPresenter(ticket).as_dict() for ticket in tickets]
|
||||
LogService.log()
|
||||
return jsonify(create_response(StateCode.SUCCESS, data=tickets_presenters)), 200
|
||||
|
||||
|
||||
@station_bp.route('/stations', methods=['GET'])
|
||||
def queryStations(): # 查询站点方法
|
||||
stations = Station.query.all()
|
||||
stations_presenters = [StationPresenter(station).as_dict() for station in stations]
|
||||
LogService.log()
|
||||
return jsonify(create_response(StateCode.SUCCESS, data=stations_presenters)), 200
|
||||
@ -1,26 +0,0 @@
|
||||
from flask import request, jsonify, Blueprint
|
||||
from app import LogService
|
||||
from app.models import Station
|
||||
from presenter import StationPresenter
|
||||
from utils import create_response, StateCode
|
||||
|
||||
station_bp = Blueprint('stations', __name__)
|
||||
|
||||
|
||||
@station_bp.route('/stations', methods=['POST'])
|
||||
def createStation(): # 创建站点方法
|
||||
data = request.json
|
||||
new_station = Station.create(data=data)
|
||||
station_presenter = StationPresenter(new_station).as_dict()
|
||||
LogService.log()
|
||||
return jsonify(create_response(StateCode.SUCCESS, data=station_presenter)), 200
|
||||
|
||||
|
||||
@station_bp.route('/stations/quantity_create', methods=['POST'])
|
||||
def quantityCreate(): # 批量创建站点方法
|
||||
stations = request.json.get("stations")
|
||||
for name in stations:
|
||||
station_hash = {"name": name}
|
||||
Station.create(station_hash)
|
||||
LogService.log()
|
||||
return jsonify(create_response(StateCode.SUCCESS)), 200
|
||||
@ -1,27 +0,0 @@
|
||||
from flask import request, jsonify, Blueprint
|
||||
from app import db, LogService
|
||||
from app.models import Train
|
||||
from app.models.train_lib import buildTrain
|
||||
from presenter.train import TrainPresenter
|
||||
from utils import create_response, StateCode
|
||||
|
||||
trains_bp = Blueprint('trains', __name__)
|
||||
|
||||
|
||||
@trains_bp.route('/trains', methods=['GET'])
|
||||
def queryAllTrains():
|
||||
trains = Train.query.all()
|
||||
trains_presenters = [TrainPresenter(train).as_dict() for train in trains]
|
||||
LogService.log()
|
||||
return jsonify(create_response(StateCode.SUCCESS, data=trains_presenters)), 200
|
||||
|
||||
|
||||
@trains_bp.route('/trains', methods=['POST'])
|
||||
def createTrain():
|
||||
data = request.json
|
||||
new_train = buildTrain(data)
|
||||
db.session.add(new_train)
|
||||
db.session.commit()
|
||||
train_presenter = TrainPresenter(new_train).as_dict()
|
||||
LogService.log()
|
||||
return jsonify(create_response(StateCode.SUCCESS, data=train_presenter)), 200
|
||||
@ -1,40 +0,0 @@
|
||||
version: '3.8'
|
||||
services:
|
||||
python:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./Dockerfile
|
||||
restart: always
|
||||
environment:
|
||||
- DATABASE_URL=postgresql://postgres:postgres@db:5432/mini12306_python
|
||||
- REDIS_URL=redis
|
||||
- SERVER_LIB_URL=http://py12306.learnerhub.net
|
||||
ports:
|
||||
- "3002:3002"
|
||||
depends_on:
|
||||
- db
|
||||
- redis
|
||||
volumes:
|
||||
- /var/log/mini12306_python:/app/logs
|
||||
|
||||
redis:
|
||||
image: redis:alpine
|
||||
container_name: 12306_redis
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
|
||||
db:
|
||||
image: postgres:15
|
||||
container_name: 12306_postgres
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: mini12306_python
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
redis_data:
|
||||
@ -1 +0,0 @@
|
||||
init folder
|
||||
@ -1 +0,0 @@
|
||||
Single-database configuration for Flask.
|
||||
@ -1,50 +0,0 @@
|
||||
# A generic, single database configuration.
|
||||
|
||||
[alembic]
|
||||
# template used to generate migration files
|
||||
# file_template = %%(rev)s_%%(slug)s
|
||||
|
||||
# set to 'true' to run the environment during
|
||||
# the 'revision' command, regardless of autogenerate
|
||||
# revision_environment = false
|
||||
|
||||
|
||||
# Logging configuration
|
||||
[loggers]
|
||||
keys = root,sqlalchemy,alembic,flask_migrate
|
||||
|
||||
[handlers]
|
||||
keys = console
|
||||
|
||||
[formatters]
|
||||
keys = generic
|
||||
|
||||
[logger_root]
|
||||
level = WARN
|
||||
handlers = console
|
||||
qualname =
|
||||
|
||||
[logger_sqlalchemy]
|
||||
level = WARN
|
||||
handlers =
|
||||
qualname = sqlalchemy.engine
|
||||
|
||||
[logger_alembic]
|
||||
level = INFO
|
||||
handlers =
|
||||
qualname = alembic
|
||||
|
||||
[logger_flask_migrate]
|
||||
level = INFO
|
||||
handlers =
|
||||
qualname = flask_migrate
|
||||
|
||||
[handler_console]
|
||||
class = StreamHandler
|
||||
args = (sys.stderr,)
|
||||
level = NOTSET
|
||||
formatter = generic
|
||||
|
||||
[formatter_generic]
|
||||
format = %(levelname)-5.5s [%(name)s] %(message)s
|
||||
datefmt = %H:%M:%S
|
||||
@ -1,113 +0,0 @@
|
||||
import logging
|
||||
from logging.config import fileConfig
|
||||
|
||||
from flask import current_app
|
||||
|
||||
from alembic import context
|
||||
|
||||
# this is the Alembic Config object, which provides
|
||||
# access to the values within the .ini file in use.
|
||||
config = context.config
|
||||
|
||||
# Interpret the config file for Python logging.
|
||||
# This line sets up loggers basically.
|
||||
fileConfig(config.config_file_name)
|
||||
logger = logging.getLogger('alembic.env')
|
||||
|
||||
|
||||
def get_engine():
|
||||
try:
|
||||
# this works with Flask-SQLAlchemy<3 and Alchemical
|
||||
return current_app.extensions['migrate'].db.get_engine()
|
||||
except (TypeError, AttributeError):
|
||||
# this works with Flask-SQLAlchemy>=3
|
||||
return current_app.extensions['migrate'].db.engine
|
||||
|
||||
|
||||
def get_engine_url():
|
||||
try:
|
||||
return get_engine().url.render_as_string(hide_password=False).replace(
|
||||
'%', '%%')
|
||||
except AttributeError:
|
||||
return str(get_engine().url).replace('%', '%%')
|
||||
|
||||
|
||||
# add your model's MetaData object here
|
||||
# for 'autogenerate' support
|
||||
# from myapp import mymodel
|
||||
# target_metadata = mymodel.Base.metadata
|
||||
config.set_main_option('sqlalchemy.url', get_engine_url())
|
||||
target_db = current_app.extensions['migrate'].db
|
||||
|
||||
# other values from the config, defined by the needs of env.py,
|
||||
# can be acquired:
|
||||
# my_important_option = config.get_main_option("my_important_option")
|
||||
# ... etc.
|
||||
|
||||
|
||||
def get_metadata():
|
||||
if hasattr(target_db, 'metadatas'):
|
||||
return target_db.metadatas[None]
|
||||
return target_db.metadata
|
||||
|
||||
|
||||
def run_migrations_offline():
|
||||
"""Run migrations in 'offline' mode.
|
||||
|
||||
This configures the context with just a URL
|
||||
and not an Engine, though an Engine is acceptable
|
||||
here as well. By skipping the Engine creation
|
||||
we don't even need a DBAPI to be available.
|
||||
|
||||
Calls to context.execute() here emit the given string to the
|
||||
script output.
|
||||
|
||||
"""
|
||||
url = config.get_main_option("sqlalchemy.url")
|
||||
context.configure(
|
||||
url=url, target_metadata=get_metadata(), literal_binds=True
|
||||
)
|
||||
|
||||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
|
||||
|
||||
def run_migrations_online():
|
||||
"""Run migrations in 'online' mode.
|
||||
|
||||
In this scenario we need to create an Engine
|
||||
and associate a connection with the context.
|
||||
|
||||
"""
|
||||
|
||||
# this callback is used to prevent an auto-migration from being generated
|
||||
# when there are no changes to the schema
|
||||
# reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html
|
||||
def process_revision_directives(context, revision, directives):
|
||||
if getattr(config.cmd_opts, 'autogenerate', False):
|
||||
script = directives[0]
|
||||
if script.upgrade_ops.is_empty():
|
||||
directives[:] = []
|
||||
logger.info('No changes in schema detected.')
|
||||
|
||||
conf_args = current_app.extensions['migrate'].configure_args
|
||||
if conf_args.get("process_revision_directives") is None:
|
||||
conf_args["process_revision_directives"] = process_revision_directives
|
||||
|
||||
connectable = get_engine()
|
||||
|
||||
with connectable.connect() as connection:
|
||||
context.configure(
|
||||
connection=connection,
|
||||
target_metadata=get_metadata(),
|
||||
**conf_args
|
||||
)
|
||||
|
||||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
|
||||
|
||||
if context.is_offline_mode():
|
||||
run_migrations_offline()
|
||||
else:
|
||||
run_migrations_online()
|
||||
@ -1,24 +0,0 @@
|
||||
"""${message}
|
||||
|
||||
Revision ID: ${up_revision}
|
||||
Revises: ${down_revision | comma,n}
|
||||
Create Date: ${create_date}
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
${imports if imports else ""}
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = ${repr(up_revision)}
|
||||
down_revision = ${repr(down_revision)}
|
||||
branch_labels = ${repr(branch_labels)}
|
||||
depends_on = ${repr(depends_on)}
|
||||
|
||||
|
||||
def upgrade():
|
||||
${upgrades if upgrades else "pass"}
|
||||
|
||||
|
||||
def downgrade():
|
||||
${downgrades if downgrades else "pass"}
|
||||
@ -1,178 +0,0 @@
|
||||
"""init databases
|
||||
|
||||
Revision ID: 1b3bc6809b30
|
||||
Revises:
|
||||
Create Date: 2024-08-15 15:09:26.124279
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '1b3bc6809b30'
|
||||
down_revision = None
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('log',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('log_user_agent', sa.String(length=120), nullable=True),
|
||||
sa.Column('log_method', sa.String(length=120), nullable=True),
|
||||
sa.Column('log_quest_path', sa.String(length=120), nullable=True),
|
||||
sa.Column('log_ip', sa.String(length=120), nullable=True),
|
||||
sa.Column('log_params', sa.String(length=120), nullable=True),
|
||||
sa.Column('log_controller', sa.String(length=120), nullable=True),
|
||||
sa.Column('log_controller_action', sa.String(length=120), nullable=True),
|
||||
sa.Column('log_controller_id', sa.String(length=120), nullable=True),
|
||||
sa.Column('account_id', sa.String(length=120), nullable=True),
|
||||
sa.Column('event_name', sa.String(length=120), nullable=True),
|
||||
sa.Column('event_content', sa.Text(), nullable=True),
|
||||
sa.Column('operator', sa.String(length=120), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_table('passenger',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('name', sa.String(length=120), nullable=True),
|
||||
sa.Column('account', sa.String(length=120), nullable=False),
|
||||
sa.Column('password_digest', sa.String(length=2000), nullable=False),
|
||||
sa.Column('id_card_no', sa.String(length=120), nullable=True),
|
||||
sa.Column('mobile_no', sa.String(length=120), nullable=True),
|
||||
sa.Column('bank_card_no', sa.String(length=120), nullable=True),
|
||||
sa.Column('state', sa.Integer(), nullable=True),
|
||||
sa.Column('member_type', sa.Integer(), nullable=True),
|
||||
sa.Column('last_login_time', sa.DateTime(), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
with op.batch_alter_table('passenger', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_passenger_account'), ['account'], unique=True)
|
||||
|
||||
op.create_table('station',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('name', sa.String(length=120), nullable=False),
|
||||
sa.Column('pinyin', sa.String(length=120), nullable=True),
|
||||
sa.Column('province', sa.String(length=120), nullable=True),
|
||||
sa.Column('city', sa.String(length=120), nullable=True),
|
||||
sa.Column('district', sa.String(length=120), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
with op.batch_alter_table('station', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_station_name'), ['name'], unique=True)
|
||||
|
||||
op.create_table('train',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('train_no', sa.String(length=120), nullable=False),
|
||||
sa.Column('departure_station', sa.String(length=120), nullable=True),
|
||||
sa.Column('arrival_station', sa.String(length=120), nullable=True),
|
||||
sa.Column('departure_time', sa.DateTime(), nullable=True),
|
||||
sa.Column('expiration_time', sa.DateTime(), nullable=True),
|
||||
sa.Column('effective_time', sa.DateTime(), nullable=True),
|
||||
sa.Column('arrival_time', sa.DateTime(), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
with op.batch_alter_table('train', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_train_train_no'), ['train_no'], unique=True)
|
||||
|
||||
op.create_table('order',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('order_no', sa.String(length=120), nullable=False),
|
||||
sa.Column('price', sa.Numeric(precision=8, scale=2), nullable=True),
|
||||
sa.Column('payment_time', sa.DateTime(), nullable=True),
|
||||
sa.Column('state', sa.Integer(), nullable=True),
|
||||
sa.Column('passenger_id', sa.Integer(), nullable=False),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['passenger_id'], ['passenger.id'], ),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('order_no')
|
||||
)
|
||||
with op.batch_alter_table('order', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_order_passenger_id'), ['passenger_id'], unique=False)
|
||||
|
||||
op.create_table('train_station',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('train_no', sa.String(length=120), nullable=False),
|
||||
sa.Column('station_name', sa.String(length=120), nullable=False),
|
||||
sa.Column('price', sa.Numeric(precision=8, scale=2), nullable=True),
|
||||
sa.Column('arrival_time', sa.DateTime(), nullable=True),
|
||||
sa.Column('departure_time', sa.DateTime(), nullable=True),
|
||||
sa.Column('index', sa.Integer(), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['station_name'], ['station.name'], ),
|
||||
sa.ForeignKeyConstraint(['train_no'], ['train.train_no'], ),
|
||||
sa.PrimaryKeyConstraint('id', 'train_no', 'station_name')
|
||||
)
|
||||
with op.batch_alter_table('train_station', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_train_station_train_no'), ['train_no'], unique=False)
|
||||
|
||||
op.create_table('ticket',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('seat_no', sa.String(length=120), nullable=True),
|
||||
sa.Column('seat_class', sa.String(length=120), nullable=True),
|
||||
sa.Column('price', sa.Numeric(precision=8, scale=2), nullable=True),
|
||||
sa.Column('state', sa.Integer(), nullable=True),
|
||||
sa.Column('train_no', sa.String(length=120), nullable=False),
|
||||
sa.Column('passenger_id', sa.Integer(), nullable=False),
|
||||
sa.Column('order_id', sa.Integer(), nullable=False),
|
||||
sa.Column('from_station', sa.String(length=120), nullable=True),
|
||||
sa.Column('to_station', sa.String(length=120), nullable=True),
|
||||
sa.Column('date', sa.String(length=120), nullable=True),
|
||||
sa.Column('departure_time', sa.DateTime(), nullable=True),
|
||||
sa.Column('arrival_time', sa.DateTime(), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['order_id'], ['order.id'], ),
|
||||
sa.ForeignKeyConstraint(['passenger_id'], ['passenger.id'], ),
|
||||
sa.ForeignKeyConstraint(['train_no'], ['train.train_no'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
with op.batch_alter_table('ticket', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_ticket_order_id'), ['order_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_ticket_passenger_id'), ['passenger_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_ticket_train_no'), ['train_no'], unique=False)
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('ticket', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_ticket_train_no'))
|
||||
batch_op.drop_index(batch_op.f('ix_ticket_passenger_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_ticket_order_id'))
|
||||
|
||||
op.drop_table('ticket')
|
||||
with op.batch_alter_table('train_station', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_train_station_train_no'))
|
||||
|
||||
op.drop_table('train_station')
|
||||
with op.batch_alter_table('order', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_order_passenger_id'))
|
||||
|
||||
op.drop_table('order')
|
||||
with op.batch_alter_table('train', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_train_train_no'))
|
||||
|
||||
op.drop_table('train')
|
||||
with op.batch_alter_table('station', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_station_name'))
|
||||
|
||||
op.drop_table('station')
|
||||
with op.batch_alter_table('passenger', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_passenger_account'))
|
||||
|
||||
op.drop_table('passenger')
|
||||
op.drop_table('log')
|
||||
# ### end Alembic commands ###
|
||||
@ -1,32 +0,0 @@
|
||||
"""remove TrainStation id
|
||||
|
||||
Revision ID: 7866a6e8a75b
|
||||
Revises: 1b3bc6809b30
|
||||
Create Date: 2024-08-15 15:29:40.410360
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '7866a6e8a75b'
|
||||
down_revision = '1b3bc6809b30'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('train_station', schema=None) as batch_op:
|
||||
batch_op.drop_column('id')
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('train_station', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('id', sa.INTEGER(), autoincrement=False, nullable=False))
|
||||
|
||||
# ### end Alembic commands ###
|
||||
@ -1,9 +0,0 @@
|
||||
# myapp.py
|
||||
from app import create_app, LogService
|
||||
from utils import response
|
||||
|
||||
app = create_app()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True)
|
||||
@ -1,3 +0,0 @@
|
||||
from .passenger import PassengerPresenter
|
||||
from .station import StationPresenter
|
||||
from .mobile_code import MobileCodePresenter
|
||||
@ -1,8 +0,0 @@
|
||||
class MobileCodePresenter:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
def as_dict(self):
|
||||
return {
|
||||
"code": self.data
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
from presenter.ticket import TicketPresenter
|
||||
|
||||
|
||||
class OrderPresenter:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
def as_dict(self):
|
||||
return {
|
||||
"id": self.data.id,
|
||||
"orderNo": self.data.order_no,
|
||||
"price": self.data.price,
|
||||
"state": self.data.state,
|
||||
"paymentTime": self.data.payment_time,
|
||||
"tickets": [TicketPresenter(ticket).as_dict() for ticket in self.data.tickets]
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
|
||||
class PassengerPresenter:
|
||||
def __init__(self, data, aid_data=None):
|
||||
self.data = data
|
||||
self.aid_data = aid_data
|
||||
|
||||
def as_dict(self):
|
||||
return {
|
||||
"id": self.data.id,
|
||||
"account": self.data.account,
|
||||
"name": self.data.name,
|
||||
"idCardNo": self.data.id_card_no,
|
||||
"mobileNo": self.data.mobile_no,
|
||||
"bankCardNo": self.data.bank_card_no,
|
||||
"state": self.data.state,
|
||||
"memberType": self.data.member_type
|
||||
} | self.aid_data
|
||||
@ -1,10 +0,0 @@
|
||||
class StationPresenter:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
def as_dict(self):
|
||||
return {
|
||||
"id": self.data.id,
|
||||
"name": self.data.name,
|
||||
"pinyin": self.data.pinyin,
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
class TicketPresenter:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
def as_dict(self):
|
||||
return {
|
||||
"id": self.data.id,
|
||||
"seatNo": self.data.seat_no,
|
||||
"seatClass": self.data.seat_class,
|
||||
"price": self.data.price,
|
||||
"state": self.data.state,
|
||||
"trainNo": self.data.train_no,
|
||||
"from": self.data.from_station,
|
||||
"orderNo": self.data.order.order_no,
|
||||
"to": self.data.to_station,
|
||||
"date": self.data.date,
|
||||
"fromTime": self.data.departure_time,
|
||||
"toTime": self.data.arrival_time,
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
from presenter.train_station import TrainStationPresenter
|
||||
|
||||
|
||||
class TrainPresenter:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
def as_dict(self):
|
||||
return {
|
||||
"id": self.data.id,
|
||||
"trainNo": self.data.train_no,
|
||||
"arrTime": self.data.arrival_time,
|
||||
"depTime": self.data.departure_time,
|
||||
"arr": self.data.arrival_station,
|
||||
"dep": self.data.departure_station,
|
||||
"stations": [TrainStationPresenter(station).as_dict() for station in self.data.train_stations]
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
class TrainStationPresenter:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
def as_dict(self):
|
||||
return {
|
||||
"index": self.data.index,
|
||||
"trainNo": self.data.train_no,
|
||||
"name": self.data.station_name,
|
||||
"arrTime": self.data.arrival_time,
|
||||
"depTime": self.data.departure_time,
|
||||
"price": self.data.price,
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
Flask~=3.0.3
|
||||
Flask-SQLAlchemy
|
||||
psycopg2-binary
|
||||
PyJWT
|
||||
Flask-Migrate
|
||||
itsdangerous
|
||||
redis~=5.0.8
|
||||
Flask-JWT-Extended
|
||||
pypinyin~=0.52.0
|
||||
Werkzeug~=3.0.3
|
||||
SQLAlchemy~=2.0.32
|
||||
alembic~=1.13.2
|
||||
python-dateutil
|
||||
requests
|
||||
gunicorn==22.0.0
|
||||
Levenshtein==0.25.1
|
||||
munkres==1.1.4
|
||||
argparse==1.4.0
|
||||
flask-cors==4.0.1
|
||||
loguru
|
||||
iso8601
|
||||
@ -1,2 +0,0 @@
|
||||
from .response import create_response, StateCode
|
||||
from .server import checkMobile, checkIdCard, checkBankCard
|
||||
@ -1,45 +0,0 @@
|
||||
import os
|
||||
import requests
|
||||
|
||||
hosts = os.getenv('SERVER_LIB_URL', "http://127.0.0.1:5000")
|
||||
|
||||
|
||||
def checkIdCard(id_card):
|
||||
url = hosts + "/id_card/verify"
|
||||
params = {
|
||||
'idCardNo': id_card
|
||||
}
|
||||
# response = requests.get(url, params=params) 发送get请求
|
||||
|
||||
response = requests.post(url, json=params)
|
||||
return response.status_code == 200 and response.json().get("data")["result"]
|
||||
|
||||
|
||||
def checkBankCard(bank_card):
|
||||
url = hosts + "/bank/card_verify"
|
||||
|
||||
params = {
|
||||
'bankCard': bank_card
|
||||
}
|
||||
response = requests.post(url, json=params)
|
||||
return response.status_code == 200 and response.json().get("data")["result"]
|
||||
|
||||
|
||||
def checkMobile(mobile_no):
|
||||
url = hosts + "/mobile/check"
|
||||
|
||||
params = {
|
||||
'mobileNo': mobile_no
|
||||
}
|
||||
|
||||
response = requests.post(url, json=params)
|
||||
return response.status_code == 200 and response.json().get("data")["result"]
|
||||
|
||||
|
||||
def verifyOrderPayment(order_no):
|
||||
url = hosts + "/bank/query"
|
||||
|
||||
# 模拟向支付中心发送验证请求进行验证
|
||||
params = {"OrderNo": order_no}
|
||||
response = requests.post(url, json=params)
|
||||
return response
|
||||
Loading…
Reference in new issue