mirror of
https://github.com/sunrin-ana/2025-SSF-dotory-manage.git
synced 2026-03-09 18:10:02 +00:00
initial test
This commit is contained in:
commit
651703c0f8
19 changed files with 198 additions and 0 deletions
BIN
__pycache__/app.cpython-313.pyc
Normal file
BIN
__pycache__/app.cpython-313.pyc
Normal file
Binary file not shown.
BIN
__pycache__/db.cpython-313.pyc
Normal file
BIN
__pycache__/db.cpython-313.pyc
Normal file
Binary file not shown.
20
app.py
Normal file
20
app.py
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
from flask import Flask
|
||||||
|
from routes import add_namespaces
|
||||||
|
from flask_restx import Api
|
||||||
|
from db import db
|
||||||
|
from flask_migrate import Migrate
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///dotori.db'
|
||||||
|
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||||
|
|
||||||
|
db.init_app(app)
|
||||||
|
migrate = Migrate(app, db)
|
||||||
|
|
||||||
|
with app.app_context():
|
||||||
|
db.create_all()
|
||||||
|
|
||||||
|
api = Api(app, doc='/docs')
|
||||||
|
add_namespaces(api)
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(debug=True)
|
||||||
3
db.py
Normal file
3
db.py
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
|
||||||
|
db = SQLAlchemy()
|
||||||
BIN
instance/dotori.db
Normal file
BIN
instance/dotori.db
Normal file
Binary file not shown.
BIN
models/__pycache__/dotori.cpython-313.pyc
Normal file
BIN
models/__pycache__/dotori.cpython-313.pyc
Normal file
Binary file not shown.
41
models/dotori.py
Normal file
41
models/dotori.py
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
from datetime import datetime
|
||||||
|
from db import db
|
||||||
|
|
||||||
|
class UserDotori(db.Model):
|
||||||
|
__tablename__ = 'user_dotori'
|
||||||
|
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
user_id = db.Column(db.String(100), unique=True, nullable=False)
|
||||||
|
dotori_count = db.Column(db.Integer, default=0)
|
||||||
|
created_at = db.Column(db.DateTime, default=datetime.now)
|
||||||
|
updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return {
|
||||||
|
'id': self.id,
|
||||||
|
'user_id': self.user_id,
|
||||||
|
'dotori_count': self.dotori_count,
|
||||||
|
'created_at': self.created_at.isoformat(),
|
||||||
|
'updated_at': self.updated_at.isoformat()
|
||||||
|
}
|
||||||
|
|
||||||
|
def to_response(self):
|
||||||
|
return {
|
||||||
|
'userId': self.user_id,
|
||||||
|
'dotory': self.dotori_count
|
||||||
|
}
|
||||||
|
|
||||||
|
def increment(self, amount=1):
|
||||||
|
self.dotori_count += amount
|
||||||
|
self.updated_at = datetime.now()
|
||||||
|
return self.dotori_count
|
||||||
|
|
||||||
|
def decrement(self, amount=1):
|
||||||
|
if self.dotori_count >= amount:
|
||||||
|
self.dotori_count -= amount
|
||||||
|
self.updated_at = datetime.now()
|
||||||
|
return self.dotori_count
|
||||||
|
return False
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<UserDotori id={self.id} user_id={self.user_id} dotori_count={self.dotori_count}>"
|
||||||
BIN
requirements.txt
Normal file
BIN
requirements.txt
Normal file
Binary file not shown.
8
routes/__init__.py
Normal file
8
routes/__init__.py
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
from flask_restx import Api
|
||||||
|
|
||||||
|
from .dotori import dotori_ns
|
||||||
|
from .product import product_ns
|
||||||
|
|
||||||
|
def add_namespaces(api):
|
||||||
|
api.add_namespace(dotori_ns, path='/api/dotory')
|
||||||
|
api.add_namespace(product_ns, path='/api/buy')
|
||||||
BIN
routes/__pycache__/__init__.cpython-313.pyc
Normal file
BIN
routes/__pycache__/__init__.cpython-313.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/buy.cpython-313.pyc
Normal file
BIN
routes/__pycache__/buy.cpython-313.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/cart.cpython-313.pyc
Normal file
BIN
routes/__pycache__/cart.cpython-313.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/dotori.cpython-313.pyc
Normal file
BIN
routes/__pycache__/dotori.cpython-313.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/order.cpython-313.pyc
Normal file
BIN
routes/__pycache__/order.cpython-313.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/product.cpython-313.pyc
Normal file
BIN
routes/__pycache__/product.cpython-313.pyc
Normal file
Binary file not shown.
40
routes/dotori.py
Normal file
40
routes/dotori.py
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
from flask_restx import Namespace, Resource, fields
|
||||||
|
from services.dotori_service import DotoriService
|
||||||
|
|
||||||
|
dotori_ns = Namespace('dotory', description='도토리 관련 API')
|
||||||
|
|
||||||
|
user_model = dotori_ns.model('UserDotori', {
|
||||||
|
'userId': fields.Integer,
|
||||||
|
'dotory': fields.Integer,
|
||||||
|
})
|
||||||
|
|
||||||
|
@dotori_ns.route('/<int:userId>')
|
||||||
|
class UserDotori(Resource):
|
||||||
|
@dotori_ns.marshal_with(user_model)
|
||||||
|
def get(self, userId):
|
||||||
|
user_dotori = DotoriService.get_user_dotori(userId)
|
||||||
|
if not user_dotori:
|
||||||
|
dotori_ns.abort(404, 'User not found')
|
||||||
|
return user_dotori.to_response()
|
||||||
|
|
||||||
|
@dotori_ns.route('')
|
||||||
|
class InitializeDotori(Resource):
|
||||||
|
@dotori_ns.expect(dotori_ns.model('Initialize', {'userId': fields.String(required=True)}))
|
||||||
|
def post(self):
|
||||||
|
data = dotori_ns.payload
|
||||||
|
user_id = data.get('userId')
|
||||||
|
return DotoriService.initialize_user_dotori(user_id)
|
||||||
|
|
||||||
|
@dotori_ns.route('/<int:userId>')
|
||||||
|
class AddDotori(Resource):
|
||||||
|
@dotori_ns.expect(dotori_ns.model('AddDotori', {'num': fields.Integer(required=True)}))
|
||||||
|
def put(self, userId):
|
||||||
|
data = dotori_ns.payload
|
||||||
|
num = data.get('num')
|
||||||
|
return DotoriService.add_dotori(userId, num)
|
||||||
|
|
||||||
|
@dotori_ns.route('/all')
|
||||||
|
class GetAllDotori(Resource):
|
||||||
|
def get(self):
|
||||||
|
users = DotoriService.get_all_users_dotori()
|
||||||
|
return users
|
||||||
37
routes/product.py
Normal file
37
routes/product.py
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
from flask_restx import Namespace, Resource, fields
|
||||||
|
from services.dotori_service import DotoriService
|
||||||
|
|
||||||
|
product_ns = Namespace('buy', description='상품 구매 API')
|
||||||
|
|
||||||
|
buy_request_model = product_ns.model('BuyRequest', {
|
||||||
|
'userId': fields.Integer(required=True),
|
||||||
|
})
|
||||||
|
|
||||||
|
buy_response_model = product_ns.model('BuyResponse', {
|
||||||
|
'isSuccess': fields.Boolean,
|
||||||
|
'userId': fields.Integer,
|
||||||
|
'dotory': fields.Integer,
|
||||||
|
})
|
||||||
|
|
||||||
|
@product_ns.route('/<int:productId>')
|
||||||
|
class BuyProduct(Resource):
|
||||||
|
@product_ns.expect(buy_request_model)
|
||||||
|
@product_ns.response(200, 'Success', buy_response_model)
|
||||||
|
@product_ns.response(400, 'Failed')
|
||||||
|
def post(self, productId):
|
||||||
|
data = product_ns.payload
|
||||||
|
user_id = data.get('userId')
|
||||||
|
if not user_id:
|
||||||
|
product_ns.abort(400, 'userId is required')
|
||||||
|
|
||||||
|
product_price = 100 # 가격이 얼마에요?
|
||||||
|
success = DotoriService.buy_product(user_id, product_price)
|
||||||
|
if success:
|
||||||
|
user_dotori = DotoriService.get_user_dotori(user_id)
|
||||||
|
return {
|
||||||
|
'isSuccess': True,
|
||||||
|
'userId': user_id,
|
||||||
|
'dotory': user_dotori if user_dotori else 0
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
product_ns.abort(400, 'Insufficient dotory or purchase failed')
|
||||||
BIN
services/__pycache__/dotori_service.cpython-313.pyc
Normal file
BIN
services/__pycache__/dotori_service.cpython-313.pyc
Normal file
Binary file not shown.
49
services/dotori_service.py
Normal file
49
services/dotori_service.py
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
from models.dotori import UserDotori
|
||||||
|
from flask import current_app
|
||||||
|
from db import db
|
||||||
|
class DotoriService:
|
||||||
|
@staticmethod
|
||||||
|
def get_user_dotori(user_id: str):
|
||||||
|
user_dotori = UserDotori.query.filter_by(user_id=user_id).first()
|
||||||
|
if user_dotori:
|
||||||
|
return user_dotori.dotori_count
|
||||||
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def initialize_user_dotori(user_id: str):
|
||||||
|
user_dotori = UserDotori.query.filter_by(user_id=user_id).first()
|
||||||
|
if not user_dotori:
|
||||||
|
user_dotori = UserDotori(user_id=user_id, dotori_count=1000000)
|
||||||
|
print(f"초기화 완료, {user_id}님의 도토리: {user_dotori.dotori_count}")
|
||||||
|
db.session.add(user_dotori)
|
||||||
|
db.session.commit()
|
||||||
|
return user_dotori.dotori_count
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def buy_product(user_id: str, product_price: int):
|
||||||
|
user_dotori = UserDotori.query.filter_by(user_id=user_id).first()
|
||||||
|
if not user_dotori:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if user_dotori.dotori_count < product_price:
|
||||||
|
return False
|
||||||
|
print(f"구매 완료, {user_id}님의 도토리: {user_dotori.dotori_count} -> {user_dotori.dotori_count - product_price}")
|
||||||
|
user_dotori.decrement(product_price)
|
||||||
|
db.session.commit()
|
||||||
|
return True
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def add_dotori(user_id: str, amount: int):
|
||||||
|
user_dotori = UserDotori.query.filter_by(user_id=user_id).first()
|
||||||
|
if not user_dotori:
|
||||||
|
user_dotori = UserDotori(user_id=user_id)
|
||||||
|
db.session.add(user_dotori)
|
||||||
|
print(f"도토리 추가, {user_id}님의 도토리: {user_dotori.dotori_count} -> {user_dotori.dotori_count + amount}")
|
||||||
|
user_dotori.increment(amount)
|
||||||
|
db.session.commit()
|
||||||
|
return user_dotori.dotori_count
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_all_users_dotori():
|
||||||
|
users = UserDotori.query.all()
|
||||||
|
return [user.to_dict() for user in users]
|
||||||
Loading…
Add table
Add a link
Reference in a new issue